Жизненный цикл запроса в Hapi определяется строгой последовательностью этапов, через которые проходит каждое входящее HTTP-событие. Архитектура фреймворка построена так, чтобы обеспечить предсказуемую обработку, расширяемость и контроль на каждом уровне выполнения запроса.
На самом первом этапе запрос попадает в HTTP-сервер Hapi, где создаётся объект запроса. В этот момент формируются базовые структуры данных:
Hapi не передаёт запрос сразу в обработчики маршрутов. Сначала он проходит через систему внутренних хуков и плагинов, которые могут модифицировать поведение обработки.
Перед маршрутизацией выполняется проверка базовой корректности соединения. На этом этапе могут быть задействованы:
Далее запрос поступает в систему предварительных обработчиков. В Hapi они реализуются через lifecycle extensions:
onRequestonPreAuthonPostAuthonPreHandlerЭти этапы позволяют вмешиваться в обработку до того, как запрос попадёт в бизнес-логику.
Фаза onRequest является самой ранней точкой
вмешательства. Здесь запрос можно:
Этот этап выполняется до маршрутизации, поэтому маршруты ещё не сопоставлены.
После onRequest система маршрутизации определяет, какой
handler должен обработать запрос. Hapi использует внутренний роутинг,
основанный на методе и пути.
В процессе маршрутизации происходит:
params)Если маршрут не найден, запрос переходит в обработку ошибки 404.
После выбора маршрута начинается этап подготовки к аутентификации. На
уровне onPreAuth можно:
Этот этап критичен для систем, где требуется динамическое управление доступом.
Hapi имеет встроенную систему стратегий аутентификации. На этом этапе происходит:
request.authЕсли аутентификация не проходит, выполнение прерывается и возвращается ошибка 401 или 403.
После успешной аутентификации запускается onPostAuth.
Здесь уже доступны данные пользователя, и можно:
Этот этап часто используется для реализации RBAC и ABAC моделей.
Перед попаданием в основной обработчик происходит проверка входящих данных. В Hapi для этого используется схема валидации (обычно через Joi).
Проверяются:
params)query)payload)headers)Если данные не соответствуют схеме, выполнение прерывается с ошибкой 400.
На этапе onPreHandler запрос уже полностью сформирован,
а данные валидированы. Здесь выполняются:
Этот этап считается последним рубежом перед основной логикой обработки.
Основной обработчик маршрута — это место, где реализуется бизнес-логика. Здесь:
Handler может быть синхронным или асинхронным. Возвращаемое значение автоматически интерпретируется Hapi как payload ответа.
После выполнения handler’а запрос переходит в фазу формирования
ответа. На этапе onPreResponse можно:
Этот этап часто используется для унификации API-ответов.
После завершения всех lifecycle-этапов Hapi формирует финальный HTTP-ответ:
Если response был модифицирован в onPreResponse, именно
его версия отправляется клиенту.
Финальный этап — передача ответа по сети. После этого соединение может быть:
На этом жизненный цикл запроса считается завершённым.
В любой точке жизненного цикла может возникнуть ошибка. Hapi централизует её обработку через:
onPreResponse для перехвата исключенийОшибки преобразуются в стандартизированные HTTP-ответы с корректными статус-кодами.
Все lifecycle hooks выполняются строго последовательно. Порядок нельзя нарушить:
Эта детерминированность делает поведение системы предсказуемым даже при сложной цепочке плагинов.
Hapi построен вокруг системы плагинов, которые могут:
Плагины регистрируются на сервере и могут влиять на каждый этап обработки запроса, не нарушая основную архитектуру.
На протяжении всего жизненного цикла объект request
постепенно обогащается:
Это делает его центральным контейнером состояния запроса.
Каждый запрос в Hapi выполняется в собственном контексте. Это означает:
Такой подход критичен для масштабируемых серверных приложений.
После отправки ответа Hapi:
Это позволяет эффективно обрабатывать большое количество параллельных запросов без утечек памяти.