Життєвий цикл запиту

← Життєвий цикл запиту

Ashterix

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

uk/docs/api/rest-bundle/developers/lifecycle.md новий файл +51 −0

Життєвий цикл запиту

Як REST Bundle обробляє запит — від HTTP-запиту до RPC-виклику і назад. Опис відповідає версії 1.3; як той самий виклик обробляє ядро, — на сторінці Життєвий цикл JsonRpcBundle.

REST-виклик

  1. kernel.request, пріоритет 32 — RouterListener знаходить згенерований REST-маршрут. Його defaults містять _rest_route (назва REST-маршруту без версії), _ver для версій, відмінних від v1, api_group і _rest_name_prefix.
  2. kernel.request, пріоритет 30 — RestControllerListener записує групу в ApiGroupContext і для REST-виклику спрямовує _controller на RestEntryPointController::rest з атрибутами rpcRoute і ver.
  3. RestRequestParser::parse()
    • знаходить REST-маршрут і RPC Service для групи та версії (404, якщо немає);
    • перевіряє HTTP-метод: HEAD вважається GET, недозволений метод — 405;
    • скидає пул RPC-подій (RpcEventFactory::reset()), встановлює HttpTokenHolder і carrier RpcFromRest, перевіряє токен (protected_api).
  4. RpcFromRest будує RpcRequest: згенерований id, назва RPC-методу, об'єднані параметри і apiVersion.
  5. RpcExecutor::execute() виконує запит так само, як JSON-RPC: rpc.request → rpc.pre_execute (формування аргументів, валідація, конвертація, #[RPC\Lock], виклик методу) → rpc.pre_response → rpc.post_execute. Будь-яка помилка проходить через rpc.error і стає відповіддю з помилкою.
  6. Контролер повертає 200 з результатом методу або перетворює помилку на RFC 9457 problem через RestErrorNormalizer.
  7. kernel.terminate — для успішного виклику генерується rpc.post_response (інвалідація #[RPC\CacheRelation], post-response лістенери). Для помилки — ні.

Запит без відповідного REST-маршруту потрапляє в загальний вхід ufo_rest_api_entrypoint (пріоритет -100), і парсер повертає 404. Запит з неправильним HTTP-методом потрапляє в маршрут <назва>_method_not_allowed (пріоритет -10), і парсер повертає 405.

Документація

  1. Пріоритет 32 — роутинг на маршрут з default _rest_doc.
  2. Пріоритет 30 — RestControllerListener записує групу в ApiGroupContext.
  3. Пріоритет 8 — RestDocLocaleListener вибирає мову з Accept-Language (RpcLocaleNegotiator::applyLocale()).
  4. RestEntryPointController::openapiAction() / postmanAction() перевіряє токен (protected_doc) і будує документ для версії та групи.
  5. kernel.response — Content-Language і Vary: Accept-Language.

RPC-події на цьому шляху не генеруються; документ будується на кожен запит.

Події

REST-виклик генерує ті самі події, що й JSON-RPC, тож лістенери застосунку працюють для обох:

Подія Константа Коли
rpc.request RpcEvent::REQUEST запит прийнято
rpc.pre_execute RpcEvent::PRE_EXECUTE перед методом
rpc.pre_response RpcEvent::PRE_RESPONSE відповідь сформовано
rpc.post_execute RpcEvent::POST_EXECUTE після методу
rpc.error RpcEvent::ERROR будь-яка помилка
rpc.post_response RpcEvent::POST_RESPONSE на kernel.terminate, після успішного виклику

Детально про кожну подію — у розділі Події життєвого циклу.

До 1.3 REST-контролер виконував запит через RpcRequestHandler без RpcExecutor, і rpc.post_response для REST не генерувався.

Стан між запитами

Група API зберігається в ApiGroupContext, carrier — у RequestCarrier, токен-холдер — в IRpcSecurity; ці сервіси належать JsonRpcBundle і скидаються між запитами в довгоживучих воркерах. RestServiceMap будує REST-маршрути для групи один раз і перемикається між уже побудованими мапами, коли змінюється група в ApiGroupContext.