Асинхронні виклики

← Асинхронні виклики

Ashterix

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

uk/docs/api/sdk/client/async/README.md новий файл +81 −0

1 + # Асинхронні виклики
2 +
3 + :::info
4 + Ця сторінка описує версію 5.x. Опис для 4.x — у перемикачі версій угорі сторінки.
5 + :::
6 +
7 + Асинхронний клас (`AsyncUserSDK`) не чекає відповіді: він кладе JSON-RPC запит у чергу, звідки його забирає сервер на JsonRpcBundle ([Асинхронність](/docs/api/json-rpc-bundle/functionality/async)). Метод одразу повертає `true`. Результат, якщо потрібен, сервер надсилає на [callback](/docs/api/json-rpc-bundle/functionality/callback).
8 +
9 + ## Що потрібно на сервері
10 +
11 + * Асинхронний транспорт у `ufo_json_rpc.async`, назва якого починається з `rpc_async` (наприклад, `rpc_async`), і споживач `messenger:consume`.
12 + * `docs.async_dsn_info: true` — інакше транспорт не потрапить у документацію, і SDK не згенерує асинхронних класів.
13 +
14 + ## Підключення
15 +
16 + Транспорт вибирається за схемою DSN серед зареєстрованих resolver-ів. Для RabbitMQ встановіть AMQP-реалізацію:
17 +
18 + ```bash
19 + composer require ufo-tech/component-transport-amqp # потрібне розширення ext-amqp
20 + ```
21 +
22 + ```php
23 + use App\Sdk\Orders\AsyncUserSDK;
24 + use Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpTransportFactory;
25 + use Ufo\Component\AsyncAmqpTransport\AMQPTransportResolver;
26 + use Ufo\Component\TransportContracts\AsyncTransportFactory;
27 +
28 + $transports = new AsyncTransportFactory([
29 + new AMQPTransportResolver(new AmqpTransportFactory()),
30 + ]);
31 +
32 + $users = new AsyncUserSDK(
33 + asyncTransportFactory: $transports,
34 + token: $token, // перевіряється сервером так само, як для HTTP
35 + secretAsync: 'user:password', // підставляється в {rpc_async_secret} у DSN
36 + transportName: 'rpc_async', // ключ DSN у sdk_config.yaml
37 + );
38 +
39 + $users->rename(5, 'John'); // true — запит у черзі
40 + ```
41 +
42 + DSN береться з `sdk_config.yaml(.dist)`: `amqp://{rpc_async_secret}@rabbit.example.com:5672/vhost/rpc`. Плейсхолдер `{<transportName>_secret}` замінюється на `secretAsync`, тож облікові дані брокера не зберігаються у файлі.
43 +
44 + AMQP-resolver підтримує схеми `amqp` і `amqps`, публікує в exchange `queue_exchange` (тип `direct`) з назвою черги й ключем маршрутизації з останнього сегмента DSN і позначає повідомлення як persistent. Повідомлення серіалізується `PhpSerializer`, тож транспорт сервера має використовувати сумісний серіалізатор (стандартний у Symfony Messenger).
45 +
46 + ## Додаткові методи
47 +
48 + | Метод | Що робить |
49 + | --- | --- |
50 + | `callbackTo(string $url)` | `$rpc.callback` — сервер надішле результат POST-запитом на URL |
51 + | `asyncTimeout(int $seconds)` | `$rpc.timeout` |
52 + | `withMeta(array $meta)` | Метадані повідомлення (`RpcAsyncRequest::$meta`) |
53 + | `rayId()`, `withoutCache()`, `withCache()` | Як у синхронних класах |
54 +
55 + ```php
56 + $reports->callbackTo('https://my-app.example.com/rpc-callback')->build($month);
57 + ```
58 +
59 + :::warning
60 + Асинхронні класи не скидають спеціальні параметри і не змінюють id після виклику: `callbackTo()` чи `asyncTimeout()` діють на всі наступні виклики того самого об'єкта. Не викликайте `ping()` на асинхронному класі. Див. [Актуальні помилки](/docs/api/sdk/client/known_issues/open).
61 + :::
62 +
63 + ## Групи API
64 +
65 + Асинхронний запит надсилається без групи, тож сервер виконує його в групі `general`. Методи інших [груп API](/docs/api/json-rpc-bundle/functionality/groups) асинхронно через SDK не викликати.
66 +
67 + ## Власний транспорт
68 +
69 + Реалізуйте `Ufo\Component\TransportContracts\AsyncTransportResolverInterface` або успадкуйте `AbstractAsyncTransportResolver`:
70 +
71 + ```php
72 + interface AsyncTransportResolverInterface
73 + {
74 + public function getTransportFactory(): TransportFactoryInterface;
75 + public function getTransport(string $dsn): TransportInterface;
76 + public function createAsyncStamp(AsyncStampDTO $asyncStampData): StampInterface;
77 + public function getSupportSchemes(): array; // наприклад ['kafka']
78 + }
79 + ```
80 +
81 + і додайте його в `AsyncTransportFactory`. Немає resolver-а для схеми DSN — `TransportNotFoundException`.