docs: rewrite JsonRpcBundle docs, add SDK docs, move them under docs/api
uk/docs/api/json-rpc-bundle/functionality/groups.md
новий файл +132
−0
Групи API
Доступно з версії 10.2. Застосунки без груп працюють як раніше: усе належить до групи за замовчуванням general.
Групи дозволяють мати в одному застосунку кілька RPC API — наприклад, публічний для клієнтів, внутрішній для адмінки та окремі BFF. Кожна група має свою адресу, набір методів, версії, документацію та, за потреби, свою перевірку токенів.
Точки входу
Імпортуйте маршрути бандла один раз для кожного API. prefix задає адресу, а defaults.api_group — групу (без нього — general):
# config/routes/ufo_json_rpc.yaml
ufo_json_rpc:
resource: ../../vendor/ufo-tech/json-rpc-bundle/config/router.yaml
prefix: /rpc
trailing_slash_on_root: false
ufo_json_rpc_internal:
resource: ../../vendor/ufo-tech/json-rpc-bundle/config/router.yaml
prefix: /rpc/internal
defaults:
api_group: internal
trailing_slash_on_root: false
ufo_json_rpc_public:
resource: ../../vendor/ufo-tech/json-rpc-bundle/config/router.yaml
prefix: /rpc/public
defaults:
api_group: public
trailing_slash_on_root: false
POST /rpc/internal виконує запит, GET /rpc/internal повертає OpenRPC, GET /rpc/internal/postman — Postman; версійні адреси — /rpc/internal/v2 тощо. Документація групи містить лише її методи й версії.
Назви маршрутів отримують префікс групи: general_ufo_rpc_api_server, internal_ufo_rpc_api_server, … Старі назви без префікса лишаються аліасами для general, тож router->generate('ufo_rpc_api_server') працює як раніше.
#[RPC\APIGroups]
Атрибут на класі або методі визначає, до яких груп належить метод:
public function __construct(array $groups = [], bool $withDefault = true)
withDefault: true додає групу general, false — ні.
use Ufo\JsonRpcBundle\ApiMethod\Interfaces\IRpcService;
use Ufo\RpcObject\RPC;
#[RPC\Info('catalog')]
#[RPC\APIGroups(['internal', 'public'], false)]
class CatalogApi implements IRpcService
{
public function list(): array { /* ... */ } // internal і public
#[RPC\APIGroups(['internal'], false)]
public function updatePrice(int $productId, int $price): true { return true; } // лише internal
#[RPC\APIGroups(['public'], false)]
public function featured(): array { return [1]; } // лише public
#[RPC\APIGroups()]
public function status(): string { return 'ok'; } // лише general
#[RPC\APIGroups(['internal'], false)]
#[RPC\IgnoreApi]
public function rebuildIndex(): true { return true; } // ніде не публікується
}
| Метод | /rpc (general) |
/rpc/internal |
/rpc/public |
|---|---|---|---|
catalog.list |
— | так | так |
catalog.updatePrice |
— | так | — |
catalog.featured |
— | — | так |
catalog.status |
так | — | — |
catalog.rebuildIndex |
— | — | — |
Правила:
- атрибут методу повністю замінює групи класу; без атрибутів метод належить до
general; APIGroups([], false)не публікує метод у жодній групі;#[RPC\IgnoreApi]має пріоритет над групами;general— це не «усі групи», а звичайна група за замовчуванням;- карти методів і версії розділені за групами: метод іншої групи повертає
Method not found; - для HTTP групу визначає маршрут, а не поле в JSON.
Токени для груп
Без додаткових налаштувань усі групи перевіряє базовий валідатор (security.clients_tokens або ваш ITokenValidator). Окрему перевірку для груп задає security.providers. Кожен провайдер має рівно один з параметрів service або clients_tokens і непорожній api_groups.
ufo_json_rpc:
security:
protected_api: true
token_name: 'Ufo-RPC-Token'
clients_tokens:
- '%env(resolve:UFO_API_TOKEN)%' # general та групи без провайдера
providers:
internal:
api_groups: [internal]
clients_tokens:
- '%env(resolve:UFO_INTERNAL_API_TOKEN)%'
public:
service: App\Security\UserTokenValidator # реалізує ITokenValidator
api_groups: [public]
- Провайдер замінює базову перевірку для своїх груп; якщо він відхилив токен, базова перевірка не запускається.
- Два провайдери для однієї групи, відсутній сервіс або клас без
ITokenValidator— помилка компіляції контейнера. protected_api,protected_docіtoken_nameспільні для всіх груп; захищена документація перевіряється провайдером своєї групи.
Консоль і async
bin/console ufo:rpc:process '{"jsonrpc":"2.0","id":1,"method":"catalog.updatePrice","params":{"productId":1,"price":100}}' \
--api-group=internal --ver=v1
Дочірні процеси batch зберігають групу й версію маршруту. Для Symfony Messenger групу передають явно:
$message = new \Ufo\RpcObject\RpcAsyncRequest($request, $token, apiGroup: 'internal');
Повідомлення без групи виконуються в general.
Переклади для групи
Назви й описи методів у документації можна перевизначити для окремої групи — файлами translations/rpc/<group>.<locale>.yaml. Див. Документація API.