rpc.post_response

← rpc.post_response

Ashterix

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

en/docs/api/json-rpc-bundle/functionality/events/post_response.md new file +101 −0

rpc.post_response

Event name

rpc.post_response

Constant

RpcEvent::POST_RESPONSE

Class

RpcPostResponseEvent

Properties

RpcResponse $response, RpcRequest $rpcRequest, Service $service

The client has already received the response. This is the event for heavy work that must not delay the response: auditing, sending emails, cache invalidation, integrations.

When it is dispatched

Once per successfully executed request:

Source Moment
HTTP kernel.terminate, after fastcgi_finish_request() (under PHP-FPM the client does not wait)
Console, batch child processes console.terminate
Inline batch right after each item
RpcExecutor (adapters) kernel.terminate of the main request

Not dispatched for an error response, a cached response and for messages from Symfony Messenger.

An exception in a listener is logged and does not affect other listeners or other requests.

Built-in listeners

Priority Listener What it does
1000 CacheRelationsEventListener Invalidates and warms up the cache according to #[RPC\CacheRelation]
10 AsyncServerEventListener::processAsync Executes notifications and requests with $rpc.callback (or hands them to a detached process)

Do not stop propagation with a priority above 10: notifications and callback requests will then never be executed.

For notifications and callback, $event->response is a placeholder; after priority 10 the real result is available in $event->rpcRequest->getResponseObject().

What can be changed

Nothing in the response — it has already been sent. Only side effects.

Usage examples

Change auditing

#[AsEventListener(RpcEvent::POST_RESPONSE)]
final class AuditListener
{
    public function __construct(private AuditLog $audit, private ApiGroupContext $groups) {}

    public function __invoke(RpcPostResponseEvent $event): void
    {
        $this->audit->record(
            method: $event->service->name,
            params: $event->rpcRequest->getParams(),
            group: $this->groups->getGroup(),
        );
    }
}

Post-response integration

Send a webhook to a partner or sync data with a CRM without delaying the client. For very long operations, it is better to hand the work off to a Symfony Messenger queue.

At this point the Symfony HTTP request has already been popped from the RequestStack. If you need its headers, take them from RequestCarrier (getCarrier()->getHttpRequest() for IRpcHttpCarrier).