docs: rewrite JsonRpcBundle docs, add SDK docs, move them under docs/api
uk/docs/api/json-rpc-bundle/documentation.md
новий файл +134
−0
Документація API
Документацію не треба писати окремо: бандл будує її з коду — типів PHP, PHPDoc, DTO, enum, обмежень валідації та атрибутів.
| Запит | Відповідь |
|---|---|
GET /rpc |
Документ OpenRPC |
GET /rpc?info |
Лише заголовок документа (info, servers) без методів і схем |
GET /rpc/postman |
Колекція Postman |
GET /rpc/v2, GET /rpc/v2/postman |
Те саме для версії API |
GET /rpc/internal, … |
Те саме для групи API |
Якщо в налаштуваннях protected_doc: true, ці запити теж потребують токена.
Що потрапляє в OpenRPC
- Методи згруповані тегами за псевдонімом класу з
#[RPC\Info]; повна назва класу — в описі тегу. - Параметри й результат — JSON Schema з нативних типів і PHPDoc: union, nullable,
Dto[],array<string, Dto>; значення за замовчуванням і обов'язковість. - DTO та enum винесені в
#/components/schemasі підключаються через$ref, тож кожен описаний один раз. - Обмеження з
#[RPC\Assertions]перетворюються на правила схеми. - Помилки методу — з тегів
@throwsу докблоці (код і повідомлення кожного винятку). - Застарілі методи (
@deprecated,#[\Deprecated]) позначаються"deprecated": true. - Версії — перелік у
info.x-versions; службова інформація UFO — у розширенняхx-ufo.
/**
* Returns a user by id
* @param int $id User identifier
* @return UserDto
* @throws UserNotFoundException
*/
public function get(int $id): UserDto
Колекція Postman
GET /rpc/postman повертає колекцію з усіма методами й прикладами параметрів. Назва колекції: RPC: <project_name> <версія>, для групи — з суфіксом [група]. Адреса сервера — у змінній base_url, токен — у заголовку з назвою token_name.
Переклад назв і описів методів
Назву (summary в OpenRPC) і опис методу можна задати й перекласти без зміни коду. Переклади кладуться в translations/rpc.<locale>.yaml (або .yml), ключ — назва RPC-методу:
# translations/rpc.uk.yaml
catalog.list:
title: Каталог
description: Список товарів
# translations/rpc.en.yaml
catalog.list:
title: Catalog
description: List of products
Мова вибирається з заголовка Accept-Language серед мов, для яких є файли перекладів (uk-UA дає uk); без збігу — kernel.default_locale. Відповідь отримує Content-Language і Vary: Accept-Language.
Переклади для групи API
Перевизначення для однієї групи — у підтеці rpc/:
translations/rpc.uk.yaml # база, для всіх груп
translations/rpc/bfa.uk.yaml # лише для групи bfa
# translations/rpc/bfa.uk.yaml
catalog.list:
title: Каталог для партнерів # description береться з базового перекладу
Кожне поле шукається в такому порядку (група важливіша за мову):
| Крок | Джерело |
|---|---|
| 1 | група, мова клієнта |
| 2 | група, kernel.default_locale |
| 3 | база, мова клієнта |
| 4 | база, kernel.default_locale |
| 5 | #[RPC\Info] / PHPDoc |
Мова — останній сегмент імені файлу, група — усе перед ним: rpc/partner.v2.en.yaml належить групі partner.v2.
Не називайте групу як домен Symfony Translator (messages, validators, security або власний): Translator сканує translations/ рекурсивно і вважатиме rpc/messages.uk.yaml частиною домену messages.
Список мов спільний для всіх груп — див. Актуальні помилки.
Переклади з розширень
Бандл, що додає RPC-методи, може постачати їхні переклади. Додаткові теки з тією самою структурою (rpc.<locale>.yaml, rpc/<group>.<locale>.yaml) підключаються через translations.paths:
ufo_json_rpc:
translations:
paths:
- '%kernel.project_dir%/vendor/acme/rpc-extension/translations'
або з самого розширення в prepend():
public function prepend(ContainerBuilder $container): void
{
$container->prependExtensionConfig('ufo_json_rpc', [
'translations' => ['paths' => [__DIR__.'/../../translations']],
]);
}
Теки зводяться поле за полем, пізніша перекриває попередню; translations/ застосунку завжди остання. Переклади збираються під час компіляції контейнера; у debug контейнер перебудовується при змінах файлів.
RpcLocaleNegotiator
Розширенням, що мають власні переклади, доступний сервіс вибору мови, яким користується документація:
use Ufo\JsonRpcBundle\Server\RpcLocaleNegotiator;
public function __construct(private RpcLocaleNegotiator $localeNegotiator) {}
$locale = $this->localeNegotiator->negotiate($request, ['en', 'uk']); // null, якщо список порожній
$this->localeNegotiator->applyLocale($request); // після LocaleListener (пріоритет 16)
$this->localeNegotiator->addLanguageHeaders($request, $response); // Content-Language + Vary
Кешування документації
Поза debug-режимом згенерований документ кешується й віддається з ETag. Клієнт, що надсилає If-None-Match, отримує 304 Not Modified без повторної генерації. Ключ кешу враховує маршрут, версію, ?info, групу, хост, мову, склад методів і container.build_id, тож кеш оновлюється при будь-якій зміні методів чи перебудові контейнера. Налаштовувати нічого не треба; пул задає cache.pool.