For developers

← For developers

Ashterix

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

en/docs/api/rest-bundle/developers/README.md new file +63 −0

For developers

REST Bundle is an adapter over the JsonRpcBundle core: it has no method map, validation or security of its own, it only turns an HTTP request into an RPC call and the result into a REST response. This section is for those who want to understand how it works inside or extend it.

Principles

  1. The RPC method is the only implementation. REST is one more transport for the same method: no REST controller per method, no second set of DTOs or separate validation.
  2. Explicit publishing. A method appears in REST only with the Symfony #[Route] attribute. #[RPC\IgnoreApi] and #[RPC\APIGroups] work the same way as in RPC.
  3. Execution belongs to the RPC core. The bundle builds an RpcRequest and executes it through RpcExecutor; parameter conversion, #[RPC\Assertions], #[RPC\Cache], #[RPC\Lock] and the rpc.* events behave as for a JSON-RPC call.
  4. Groups and versions come from the RPC service map. Each API group and version has its own REST routes and documents; inherited and removed methods are defined by #[RPC\Info(version:, removedMethods:)].
  5. HTTP semantics at the edge. The REST layer is responsible only for what JSON-RPC lacks: paths, HTTP methods, statuses (404, 405, 401, …) and the RFC 9457 error format.
  6. Documentation from the same metadata. OpenAPI and Postman are generated from the service map, so they do not diverge from the code.

Components

Component Role
Services\RestServiceMap Reads the RPC service map of the current group and builds REST routes from #[Route] attributes (class + method) for each version
Services\RpcRestRouteLoader Route loader of type ufo_rest_api: a route per method and version plus a _method_not_allowed fallback
Routing\RestRouteImport Registers config/router.yaml with the JsonRpcBundle route loader (IApiRouteImport)
EventDispatcher\RestControllerListener After routing, sets the group in ApiGroupContext and directs REST routes to the controller
EventDispatcher\RestDocLocaleListener Documentation language from Accept-Language via RpcLocaleNegotiator
Services\RestRequestParser Finds the route and RPC service, checks the HTTP method and token, creates the carrier
Services\RpcFromRest Carrier (IRpcHttpCarrier): builds an RpcRequest from the path, query, form and body, casts strings to parameter types
Controller\RestEntryPointController Executes the call through RpcExecutor, returns the result or a problem; serves OpenAPI and Postman
Exceptions\RestErrorNormalizer, Rest*Exception Conversion of RPC errors to REST exceptions with HTTP statuses
DocAdapters\Outputs\OpenApiAdapter, PostmanAdapter Build documents from RestServiceMap

Two phases

Container and route compilation

RPC procedures ──► JsonRpcBundle ServiceMap (for each group and version)
                        │
config/routes/*.yaml ──► JsonRpcBundle loader ── RestRouteImport recognises config/router.yaml
                        │   sets the import's group, prefixes the names: <group>_<name>
                        ▼
              config/router.yaml
               ├─ controller routes: documentation (/, /postman, /{ver}, /{ver}/postman), catch-all entry point
               └─ ufo_rest_api resource ──► RpcRestRouteLoader ──► RestServiceMap ──► routes from #[Route]

Request: see Lifecycle.

What the bundle does not do

  • It has no configuration tree of its own: everything is in ufo_json_rpc.
  • It does not support batch, notifications and $rpc.callback via REST.
  • It does not cache documents with ETag.

In this section

  • Lifecycle: how a REST request passes through the bundle and the RPC core.
  • Extensions: events, replacing the parser, reading the REST map, other adapters.
  • Testing: running and structure of the bundle's tests.
  • Known issues: what does not work as expected and how to work around it.

General guidelines for core extensions are on the JsonRpcBundle For developers page.

Contributing

Found a bug or a mismatch with the documentation? Open an issue in the bundle repository. For behaviour changes, add a functional test: routes, statuses, problem documents and documentation are the REST contract.