JsonRpcBundle

← JsonRpcBundle

Ashterix

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

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

JsonRpcBundle

<include>(docs/api/json-rpc-bundle/.info.md)

A JSON-RPC 2.0 server for Symfony 7.2+ / 8 (PHP 8.4+).

Building RPC services for a service-oriented architecture on Symfony has never been this easy.

Any service in your application becomes an API: implement the IRpcService interface and its public methods are available as JSON-RPC methods. Validation, type conversion, security, caching and OpenRPC documentation come from the code you have already written.

From class to API

Your code

#[RPC\Info('User')]
final class UserApi implements IRpcService
{
    public function __construct(private UserService $users) {}

    /**
     * Returns a user by id
     * @throws UserNotFoundException
     */
    #[RPC\Cache(lifetimeSecond: RPC\Cache::T_HOUR)]
    public function get(int $id): UserDto
    {
        return $this->users->get($id);
    }
}

Request

{"jsonrpc": "2.0", "id": 1, "method": "User.get", "params": {"id": 5}}

Response

{
    "jsonrpc": "2.0",
    "id": 1,
    "result": {"id": 5, "email": "user@example.com", "name": "John"}
}

There is nothing else to write:

  • GET /rpc already returns OpenRPC documentation with the User.get method, the UserDto schema and the error from @throws, and GET /rpc/postman returns a ready-made Postman collection;
  • a wrong id type returns a -32602 error with an explanation for the parameter;
  • in the prod environment the response is cached for an hour;
  • the same method can be called from the console, from a Symfony Messenger queue, in a batch together with other methods, and, through extensions, as a REST endpoint or a tool for an AI agent.

Why JsonRpcBundle

  • Documentation never lags behind the code. OpenRPC and Postman are built from PHP types, PHPDoc, DTOs, enums and validation constraints; method names are translated according to Accept-Language (API documentation).
  • One method, many transports. HTTP, console, Symfony Messenger, and through extensions REST, MCP, Mercure (Asynchronous processing, Console calls).
  • Painless evolution. Several API versions side by side (/rpc, /rpc/v2) and several API groups in one application (public, internal, BFF), each with its own methods and tokens.
  • Fewer network requests. Batch with @FROM:<id>(<field>) dependencies, fire-and-forget notifications, results delivered to a webhook.
  • Declarative instead of boilerplate. Validation, DTOs and type conversion, caching and locking via attributes on the method.
  • Extensibility. Events around every call and core extension points (For developers).

<include>(change_log/latest.md)

Ecosystem

  • AI agents. MCP Bundle exposes your RPC methods as tools for Claude Code, Cursor, Gemini CLI and OpenAI, with no extra code.
  • REST. REST Bundle publishes selected methods as a REST API with OpenAPI documentation.
  • Clients. JSON-RPC Client SDK generates a PHP client with procedure classes and DTOs, RPC TS SDK generates TypeScript interfaces from the OpenRPC document.
  • Rules for AI assistants. Instruction files so that Claude Code, Codex or Cursor work with the bundle correctly.

The full list is on the Extensions page.

Getting started

  1. Install the bundle: composer require ufo-tech/json-rpc-bundle and two configuration files.
  2. Add custom methods and open GET /rpc to see the documentation.
  3. Configure security and other parameters.
  4. Explore the features: batch, notifications, asynchronous processing, events.

Not sure JSON-RPC is right for you? Read the article RPC, REST and GraphQL, a short and practical look at when each approach fits.

en/docs/api/json-rpc-bundle/.info.md new file +67 −0

Current version

Category

API

Type

Symfony Bundle

Dependencies

php_version symfony_version symfony_version symfony_messenger

Other details

License Size fork

en/docs/api/json-rpc-bundle/change_log/latest.md new file +1 −0

<include>(10.4.2.md)

en/docs/api/json-rpc-bundle/change_log/10.4.2.md new file +17 −0

Version 10.4

Key changes

  • Translations for API groups: translations/rpc/<group>.<locale>.yaml; the group takes precedence over the language.
  • Translations from extensions (translations.paths), the public RpcLocaleNegotiator service.
  • 10.4.1: IApiRouteImport: adapter routes can be registered separately for each API group.
  • 10.4.2: RpcExecutor is the single entry point for adapters (REST, MCP); rpc.post_response fires for any request source and for each executed batch item.

What to keep in mind

  • Partial base translation: a missing description is taken from the base translation in the kernel.default_locale language, not from the attribute / PHPDoc.
  • REST calls now get rpc.post_response: cache relations and async/notification listeners start working for them.

Environment changes

  • Unchanged from 10.3.