Bundle configuration

← Bundle configuration

Ashterix

docs: rewrite JsonRpcBundle docs, add SDK docs, move them under docs/api

en/docs/api/json-rpc-bundle/config/README.md new file +220 −0

Bundle configuration

This page describes version 10.x. Configuration for earlier versions is available in the version selector at the top of the page.

All configuration lives in config/packages/ufo_json_rpc.yaml. No section is required: if a section is omitted, the default values apply.

# config/packages/ufo_json_rpc.yaml
ufo_json_rpc:
    batch:
        enabled: true
        process: true
        process_count: 2

    notification:
        process: false
        process_count: 2

    translations:
        paths: []

    cache:
        ttl: 60
        prefix: 'rpc_cache'
        # pool: 'cache.app'

    security:
        protected_api: true
        protected_doc: false
        token_name: 'Ufo-RPC-Token'
        clients_tokens:
            - '%env(resolve:UFO_API_TOKEN)%'
        # providers: ...

    docs:
        project_name: 'My Project'
        project_description: ''
        project_version: null
        async_dsn_info: false
        validations:
            symfony_asserts: false

    async: []

The security block

Protects the API with an access key (token) passed in an HTTP header.

Parameter Type Default Description
protected_api bool true Check the token for RPC requests (HTTP, CLI, async)
protected_doc bool false Check the token for documentation GET requests
token_name string Ufo-RPC-Token Name of the header carrying the token. In the console, it is the --<token_name in lowercase> option
clients_tokens string[] [] List of valid tokens for the base validator
providers map — Separate validators for API groups
ufo_json_rpc:
    security:
        protected_api: true
        protected_doc: false
        token_name: 'Ufo-RPC-Token'
        clients_tokens:
            - '%env(resolve:UFO_API_TOKEN)%'
            - '%env(resolve:UFO_API_TOKEN_OLD)%'   # multiple keys, for rotation

<include>(.http_headers.md)

Do not store tokens in code

Pass tokens via environment variables (.env.local, Symfony secrets) instead of hardcoding them in YAML.

A missing token returns error -32401 (HTTP 401), an invalid one returns -32403.

Custom token validator

If a token list does not fit your case (for example, the token is a user key stored in the database), implement Ufo\JsonRpcBundle\Security\Interfaces\ITokenValidator and register it as the base validator:

use Ufo\JsonRpcBundle\Security\Interfaces\ITokenValidator;
use Ufo\RpcError\RpcInvalidTokenException;

final class UserTokenValidator implements ITokenValidator
{
    public function __construct(private ApiKeyRepository $keys) {}

    public function isValid(string $token): true
    {
        if (!$this->keys->isActive($token)) {
            throw new RpcInvalidTokenException();
        }

        return true;
    }
}
# config/services.yaml
services:
    Ufo\JsonRpcBundle\Security\Interfaces\ITokenValidator:
        alias: App\Security\UserTokenValidator

The validator checks all protected entry points that have no dedicated provider assigned, including the documentation when protected_doc: true.

Providers for API groups (providers)

Each provider sets exactly one of service (a service implementing ITokenValidator) or clients_tokens (a separate list of keys), plus a non-empty api_groups:

ufo_json_rpc:
    security:
        clients_tokens:
            - '%env(resolve:UFO_API_TOKEN)%'
        providers:
            internal:
                api_groups: [internal]
                clients_tokens:
                    - '%env(resolve:UFO_INTERNAL_API_TOKEN)%'
            public:
                service: App\Security\UserTokenValidator
                api_groups: [public]

Groups without a provider are checked by the base validator. See API groups for details.

The docs block

Parameters of the OpenRPC document.

Parameter Default Description
project_name My Project API name in the documentation and the Postman collection
project_description '' API description
project_version null Version of your project (not to be confused with API versions)
async_dsn_info false Show the parameters of asynchronous transports in the documentation (x-ufo.transport)
validations.symfony_asserts false Add the list of Symfony constraints to parameters (x-ufo-assertions)

The cache block

Response cache for methods with #[RPC\Cache] and the documentation cache.

Parameter Default Description
ttl 60 Default entry lifetime, in seconds
prefix rpc_cache Cache namespace
pool null Cache pool service to use instead of the local file pool rpc.cache.pool
ufo_json_rpc:
    cache:
        pool: 'cache.app'   # e.g. a shared Redis

ttl and prefix apply only to the default pool. On multiple servers, use a shared pool so that #[RPC\CacheRelation] invalidation works on all of them.

The batch block

Processing of batch requests.

Parameter Default Description
enabled true false: batch requests are rejected with a single -32600 error
process true true: each item runs in its own ufo:rpc:process child process (isolation and parallelism); false: items run one by one in the current process (inline)
process_count 2 How many child processes run concurrently (1–10)

For short methods, inline mode (process: false) is roughly 250 times faster than process mode.

The notification block

Execution of notifications and $rpc.callback.

Parameter Default Description
process false true: run in a detached ufo:rpc:process process instead of the HTTP worker
process_count 2 Detached processes running concurrently (1–10); when all are busy, execution happens inline

Enable notification.process only for rare long-running notifications: each detached process boots the Symfony kernel (~200–300 ms CPU), so under load this is slower than regular execution.

The translations block

Translations of method names and descriptions for the documentation live in the application's translations/rpc.<locale>.yaml. paths adds directories with the same structure, for example from extensions:

ufo_json_rpc:
    translations:
        paths:
            - '%kernel.project_dir%/vendor/acme/rpc-extension/translations'

See API documentation for details.

The async block

List of asynchronous transports. Each item has a type and an arbitrary config (name, dsn and additional keys):

ufo_json_rpc:
    async:
        - type: 'amqp'
          config:
              name: 'rpc_async'
              dsn: '%env(resolve:RPC_TRANSPORT_DSN)%'
        - type: 'mercure'
          config:
              name: 'rpc_socket'
              dsn: '%env(resolve:MERCURE_PUBLIC_URL)%'
              topics_prefix: 'rpc.event.'

Items with type: amqp are registered as Symfony Messenger transports named name. See Asynchronous processing for details.

en/docs/api/json-rpc-bundle/config/.http_headers.md new file +11 −0

HTTP header naming requirements

HTTP header names are not strictly regulated with respect to capitalization, because HTTP headers are case-insensitive. However, there are some common practices and standards that are usually followed for better readability and consistency:

  • Capitalization: HTTP header names are usually written in CamelCase, where each word starts with a capital letter, e.g. Content-Type, User-Agent, Accept-Encoding. This does not affect how headers are processed technically, but makes them easier to read.
  • Uniqueness: Each header must have a unique name within a single HTTP request or response. The same name cannot be used for different headers in the same request or response.
  • Special headers: Some headers are used specifically to control caching behavior (Cache-Control), security (Strict-Transport-Security), authentication (Authorization), etc.
  • RFC norms: Header requirements are governed by RFC documents, which define the standards for Internet protocols. For example, general headers and their usage are described in RFC 7231.