rpc.pre_response

← rpc.pre_response

Ashterix

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

en/docs/api/json-rpc-bundle/functionality/events/pre_response.md new file +95 āˆ’0

1 + # rpc.pre_response
2 +
3 + ::::::block class="floatinginfobox floatinginfobox--fit"
4 + :::::columns border zebra
5 + ::::row
6 + :::col width="40%"
7 + **Event name**
8 + :::
9 + :::col
10 + `rpc.pre_response`
11 + :::
12 + ::::
13 + ::::row
14 + :::col width="40%"
15 + **Constant**
16 + :::
17 + :::col
18 + `RpcEvent::PRE_RESPONSE`
19 + :::
20 + ::::
21 + ::::row
22 + :::col width="40%"
23 + **Class**
24 + :::
25 + :::col
26 + `RpcPreResponseEvent`
27 + :::
28 + ::::
29 + ::::row
30 + :::col width="40%"
31 + **Properties**
32 + :::
33 + :::col
34 + `RpcResponse $response`, `RpcRequest $rpcRequest`, `?Service $service`
35 + :::
36 + ::::
37 + :::::
38 + ::::::
39 +
40 + The response has been built but not sent yet. Dispatched both for a result and for an error (in that case `$service` is `null`).
41 +
42 + ## When it is dispatched
43 +
44 + * After successful method execution (before `rpc.post_execute`).
45 + * After an execution error (from `rpc.error`).
46 + * On receipt of a notification or a request with `$rpc.callback` — with a placeholder response (`null` or `{"async": true, "callback": …}`); later, when the method runs, — once more with the real response.
47 +
48 + **Not dispatched** for a cached response.
49 +
50 + ## Built-in listeners
51 +
52 + | Priority | Listener | What it does |
53 + | --- | --- | --- |
54 + | 1000 | `ParamsConverterEventListener::objectToScalar` | Converts properties of the result object into scalars (enums, dates, UUIDs, entities) and replaces the response |
55 + | -100000 | `RpcServer` | Takes `$event->rpcRequest->getResponseObject()` as the response that goes to the client |
56 +
57 + ## What can be changed
58 +
59 + `RpcResponse` is immutable. To replace the response, set a new one through the request **with a priority above -100000**:
60 +
61 + ```php
62 + $event->rpcRequest->setResponse(new RpcResponse($event->rpcRequest->getId(), $newResult));
63 + ```
64 +
65 + * Assigning `$event->response` does **not** change the response to the client (but this is exactly what `rpc.post_response` receives).
66 + * Listeners with a priority above 1000 see the raw result object, below 1000 — an already normalized array.
67 + * Replacement has no effect on the notification/callback placeholder.
68 + * Do not stop propagation above -100000: the response will not be picked up.
69 +
70 + ## Usage examples
71 +
72 + ### Masking sensitive data
73 +
74 + ```php
75 + #[AsEventListener(RpcEvent::PRE_RESPONSE, priority: 500)]
76 + final class MaskEmailListener
77 + {
78 + public function __invoke(RpcPreResponseEvent $event): void
79 + {
80 + $result = $event->response->getResult();
81 + if ($event->response->getError() !== null || !is_array($result) || !isset($result['email'])) {
82 + return;
83 + }
84 +
85 + $result['email'] = preg_replace('/(?<=.).(?=[^@]*@)/', '*', $result['email']);
86 + $event->rpcRequest->setResponse(new RpcResponse($event->rpcRequest->getId(), $result));
87 + }
88 + }
89 + ```
90 +
91 + ### Other ideas
92 +
93 + * logging responses (taking errors into account: `$event->response->getError()`);
94 + * adding service fields to the result for a specific API group;
95 + * collecting response size metrics.