HTTP Інтерсептори
Інтерсептори дуже близькі по функціональності до контролерів, але вони не створюють роутів, вони прив'язуються до вже існуючих роутів. На одному роуті може працювати ціла група інтерсепторів, що запускаються один за одним. Інтерсептори - це аналог middleware в ExpressJS, але інтерсептори можуть використовувати DI.
Як правило, інтерсептори використовують для автоматизації стандартної обробки, такої як:
- парсинг тіла запиту чи заголовків;
- валідація запиту;
- збирання та логування різних метрик роботи застосунку;
- кешування;
- і т.д.
Інтерсептори можна централізовано підключати або відключати, не змінюючи при цьому код методів контролерів, до яких вони прив'язуються. Як і контролери, інтерсептори можуть працювати в режимі request-scoped чи route-scoped. На відміну від route-scoped, в режимі request-scoped вони мають доступ до інжектора на рівні запиту, тому вони можуть викликати сервіси на рівні запиту, роуту, модуля чи застосунку. З іншого боку, в режимі route-scoped їхні інстанси створюються на рівні роуту, відповідно - для них доступні сервіси на рівні роуту, модуля чи застосунку.
Схема обробки HTTP-запиту
Робота в режимі request-scoped
Обробка HTTP-запиту має наступний робочий потік:
- Holu створює інстанс RequestDispatcher на рівні застосунку.
RequestDispatcherза допомогою роутера шукає обробника запиту відповідно до URI.- Якщо обробника запиту не знайдено,
RequestDispatcherвидає помилку зі статусом 404. - Якщо знайшовся обробник запиту, Holu створює інстанс провайдера з токеном HttpFrontend на рівні запиту, ставить його першим у черзі інтерсепторів і автоматично викликає. By default, цей інтерсептор відповідає за встановлення значень для провайдерів з токенами
QUERY_PARAMSтаPATH_PARAMS. - Якщо в поточному маршруті є ґарди, то по-дефолту запускається
RequestScopedGuardedInterceptorзразу післяHttpFrontend. - Наступними можуть запуститись інші інтерсептори, це залежать від того, чи запустить їх попередній у черзі інтерсептор.
- Якщо усі інтерсептори відпрацювали, Holu запускає HttpBackend, інстанс якого створюється на рівні запиту. By default,
HttpBackendзапускає безпосередньо метод контролера, що відповідає за обробку поточного запиту.
Отже, приблизний порядок обробки запиту такий:
RequestDispatcher;HttpFrontend;RequestScopedGuardedInterceptor;- інші інтерсептори;
HttpBackend, який запускає метод контролера.
Оскільки ланцюжок промісів починається від RequestDispatcher, і закінчується методом контролера, то резолвиться цей ланцюжок у зворотньому порядку - від методу контролера до RequestDispatcher. Це означає, що в інтерсепторі ви можете слухати результат резолву проміса, що повертає метод контролера.
Окрім цього, оскільки інстанси RequestDispatcher, HttpFrontend, RequestScopedGuardedInterceptor та HttpBackend створюються з а допомогою DI, ви можете їх підміняти своєю версією відповідних класів. Наприклад, якщо ви хочете не просто відправити 404-ий статус у випадку відсутності потрібного роута, а хочете ще й додати певний текст чи змінити заголовки, ви можете підмінити RequestDispatcher своїм класом.
Робота в режимі route-scoped
Інтерсептор в режимі route-scoped працює дуже подібним чином до режиму request-scoped, але при цьому він не використовує інжектор на рівні запиту. Робочий потік за його участі відрізняється у пункті 4 та 7, оскільки інстанс інтерсептора в режимі route-scoped створюється на рівні роуту:
- Holu створює інстанс RequestDispatcher на рівні застосунку.
RequestDispatcherза допомогою роутера шукає обробника запиту відповідно до URI.- Якщо обробника запиту не знайдено,
RequestDispatcherвидає помилку зі статусом 404. - Якщо знайшовся обробник запиту, Holu використовує інстанс провайдера з токеном HttpFrontend на рівні роуту, ставить його першим у черзі інтерсепторів і автоматично викликає. By default, цей інтерсептор відповідає за встановлення значень
pathParamsтаqueryParamsдляRequestContext. - Якщо в поточному маршруті є ґарди, то по-дефолту запускається
RouteScopedGuardedInterceptorзразу післяHttpFrontend. - Наступними можуть запуститись інші інтерсептори, це залежать від того, чи запустить їх попередній у черзі інтерсептор.
- Якщо усі інтерсептори відпрацювали, Holu запускає HttpBackend, інстанс якого використовується на рівні роуту. By default,
HttpBackendзапускає безпосередньо метод контролера, що відповідає за обробку поточного запиту.