Сервер
Объект сервера является основным контейнером приложения. Сервер управляет всеми входящими запросами, а также всеми средствами, предоставляемыми фреймворком. Каждый сервер поддерживает одно подключение (например, прослушивает порт 80).
server([options])
Создаёт новый объект сервера, где:
-
options- (необязательно) объект конфигурации сервера.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ load: { sampleInterval: 1000 } });Параметры сервера
Параметры сервера управляют поведением объекта сервера. Обратите внимание, что объект параметров глубоко клонируется (за исключением listener, который копируется поверхностно) и не должен содержать значений, небезопасных для глубокого копирования.
Все параметры необязательны.
server.options.address
Значение по умолчанию: '::' если IPv6 доступен, в противном случае '0.0.0.0' (т.е. все доступные сетевые интерфейсы).
Устанавливает имя хоста или IP-адрес, на котором сервер будет прослушивать. Если не настроен, по умолчанию устанавливается host, если он задан, иначе – все доступные сетевые интерфейсы. Установите значение '127.0.0.1', '::1', или 'localhost' для ограничения сервера только теми подключениями, которые поступают с того же хоста.
server.options.app
Значение по умолчанию: {}.
Предоставляет конфигурацию, специфичную для приложения, к которой можно получить доступ позже через server.settings.app. Фреймворк не взаимодействует с этим объектом. Это просто ссылка, доступная везде, где предоставляется ссылка server.
Обратите внимание на разницу между server.settings.app , используемым для хранения статических значений конфигурации, и server.app, предназначенным для хранения состояния во время выполнения.
server.options.autoListen
Значение по умолчанию: true.
Используется для отключения автоматической инициализации listener. Когда false, указывает, что listener будет запущен вручную вне фреймворка.
Не может быть установлено в false одновременно со значением port.
server.options.cache
Значение по умолчанию: { provider: { constructor: require('@hapi/catbox-memory'), options: { partition: 'hapi-cache' } } }.
Настраивает поставщиков кэширования на стороне сервера. Каждый сервер включает в себя кэш по умолчанию для хранения состояния приложения. По умолчанию создаётся простой кэш на основе памяти, имеющий ограниченную ёмкость и возможности.
hapi использует catbox для реализации кэша, который включает поддержку распространённых решений хранения (например, Redis, MongoDB, Memcached, Riak и др.). Кэширование используется только в том случае, если методы и плагины явно хранят своё состояние в кэше.
Конфигурация кэша сервера определяет только сам контейнер хранения. Конфигурация может быть назначена одному или нескольким (массиву):
-
класс или функция прототипа (обычно получаемый вызовом
require()к стратегии catbox, например,require('@hapi/catbox-redis')). Внутри будет создан новый клиент catbox клиент с использованием этого конструктора. -
объект конфигурации со следующим:
-
engine- экземпляр объекта движка catbox. -
name- идентификатор, используемый позже при оснащении или настройке кэширования для методов сервера или плагинов. Каждое имя кэша должно быть уникальным. Один элемент может опустить опциюname, которая определяет кэш по умолчанию. Если каждый кэш включаетname, кэш по умолчанию на основе памяти также будет предоставлен. -
provider- класс, функция-конструктор или объект со следующим:-
constructor- класс или функция прототипа. -
options- (необязательно) объект настроек, передаваемый как есть вconstructorсо следующим:-
partition- (необязательно) строка, используемая для изоляции кэшированных данных. По умолчанию'hapi-cache'. - другие параметры конструктора, передаваемые в
constructorпри создании.
-
-
-
shared- еслиtrue, позволяет нескольким пользователям кэша совместно использовать один и тот же сегмент (например, несколько методов, использующих один и тот же контейнер хранилища кэша). По умолчаниюfalse. -
Один (и только один) из
engineилиproviderтребуется в каждом объекте конфигурации.
-
server.options.compression
Значение по умолчанию: { minBytes: 1024 }.
Определяет обработку сервером запросов кодирования содержимого. Если false, кодирование содержимого ответа отключено, и сервером не выполняется сжатие.
server.options.compression.minBytes
Значение по умолчанию: '1024'.
Устанавливает минимальный размер полезной нагрузки ответа в байтах, необходимый для сжатия кодирования содержимого. Если размер полезной нагрузки меньше предела, сжатие не выполняется.
server.options.debug
Значение по умолчанию: { request: ['implementation'] }.
Определяет, какие события регистрации отправляются в консоль. Это следует использовать только в целях разработки и не влияет на то, какие события фактически регистрируются внутри и записываются. Установите в false для отключения всех сообщений отладки в консоли, или в объект со:
-
log- массив строк тегов журнала сервера, отображаемых вconsole.error(), когда события регистрируются черезserver.log(), а также внутренние сгенерированные журналы сервера. По умолчанию не выводится. -
request- массив строк тегов журнала запроса, отображаемых вconsole.error(), когда события регистрируются черезrequest.log(), а также внутренние сгенерированные журналы запросов. Например, для отображения всех ошибок, установите этот параметр в['error']. Для отключения всех сообщений отладки в консоли установите вfalse. Для отображения всех журналов запросов установите в'*'. По умолчанию отображаются необработанные ошибки, сгенерированные внешним кодом (эти ошибки обрабатываются автоматически и приводят к ответу Internal Server Error) или ошибки во время выполнения из-за ошибки разработчика.
Например, для отображения всех ошибок, установите log или request в ['error']. Для отключения всего вывода, установите log или request в false. Для отображения всех журналов сервера, установите log или request в '*'. Для отключения всех данных отладки установите debug в false.
server.options.host
Значение по умолчанию: имя хоста операционной системы, а если он недоступен, то 'localhost'.
Общедоступное имя хоста или IP-адрес. Используется для установки server.info.host и server.info.uri, а также в качестве address, если он не указан.
server.options.info.remote
Значение по умолчанию: false.
Если true, request.info.remoteAddress и request.info.remotePort заполняются при получении запроса, что может потреблять больше ресурсов (но это нормально, если информация нужна, особенно для прерванных запросов). Если false, поля заполняются только по запросу (но будут undefined если доступ к ним осуществляется после прерывания запроса).
server.options.listener
Значение по умолчанию: отсутствует.
Необязательный объект node HTTP (или HTTPS) http.Server (или объект с совместимым интерфейсом).
Если listener необходимо запустить вручную, установите autoListen в false.
Если listener использует TLS, установите tls в true.
server.options.load
Значение по умолчанию: { sampleInterval: 0, maxHeapUsedBytes: 0, maxRssBytes: 0, maxEventLoopDelay: 0, maxEventLoopUtilization: 0 }.
Пределы обработки чрезмерной нагрузки сервера, где:
-
sampleInterval- частота выборки в миллисекундах. Если установлено в0, другие параметры нагрузки игнорируются. По умолчанию0(без выборки). -
maxHeapUsedBytes- максимальный размер кучи V8, превышение которого приводит к отклонению входящих запросов с ответом HTTP Server Timeout (503). По умолчанию0(без ограничения). -
maxRssBytes- максимальный размер RSS процесса, превышение которого приводит к отклонению входящих запросов с ответом HTTP Server Timeout (503). По умолчанию0(без ограничения). -
maxEventLoopDelay- максимальная продолжительность задержки цикла событий в миллисекундах, превышение которой приводит к отклонению входящих запросов с ответом HTTP Server Timeout (503). По умолчанию0(без ограничения). -
maxEventLoopUtilization- максимальное значение использования цикла событий, превышение которого приводит к отклонению входящих запросов с ответом HTTP Server Timeout (503). По умолчанию0(без ограничения).
server.options.mime
Значение по умолчанию: отсутствует.
Параметры, передаваемые модулю mimos при генерации базы данных MIME, используемой сервером (и доступной через server.mime):
-
override- хеш объекта, который объединяется с встроенной информацией MIME, указанной здесь. Каждая пара ключ-значение представляет один объект MIME. Каждое значение замены должно содержать:-
key- строка типа MIME в нижнем регистре (например,'application/javascript'). -
value- объект, соответствующий спецификациям, указанным здесь. Дополнительные значения включают:-
type- указывает значениеtypeдля объектов результата, по умолчаниюkey. -
predicate- метод с сигнатуройfunction(mime), когда этот тип MIME найден в базе данных, эта функция будет выполнена для предоставления возможностей кастомизации.
-
-
const options = {
mime: {
override: {
'node/module': {
source: 'iana',
compressible: true,
extensions: ['node', 'module', 'npm'],
type: 'node/module'
},
'application/javascript': {
source: 'iana',
charset: 'UTF-8',
compressible: true,
extensions: ['js', 'javascript'],
type: 'text/javascript'
},
'text/html': {
predicate: function(mime) {
if (someCondition) {
mime.foo = 'test';
}
else {
mime.foo = 'bar';
}
return mime;
}
}
}
}
};
server.options.operations
Значение по умолчанию: { cleanStop: true }.
Определяет обработку сервером операций сервера:
-
cleanStop- еслиtrue, сервер отслеживает открытые подключения и должным образом закрывает их при остановке сервера. При нормальной нагрузке это не должно влиять на производительность сервера. Однако при сильной нагрузке мониторинг подключений может потреблять дополнительные ресурсы и усугубить ситуацию. Если сервер никогда не останавливается или если его вынужденно остановить без ожидания закрытия открытых подключений, установка этого значения вfalseможет сохранить ресурсы, которые не используются. По умолчаниюtrue.
server.options.plugins
Значение по умолчанию: {}.
Конфигурация, специфичная для плагина, к которой можно получить доступ позже через server.settings.plugins. plugins — это объект, где каждый ключ — имя плагина, а значение — конфигурация. Обратите внимание на разницу между server.settings.plugins, используемым для хранения статических значений конфигурации, и server.plugins, предназначенным для хранения состояния во время выполнения.
server.options.port
Значение по умолчанию: 0 (эпизодический порт).
Порт TCP, на котором будет прослушивать сервер. По умолчанию сервер выбирает следующий доступный порт при запуске (и присваивается server.info.port).
Если port — строка, содержащая символ '/', она используется в качестве пути к сокету доменной системы UNIX. Если она начинается с '\.\pipe', она используется как имя именованной пайпы Windows.
server.options.query
Значение по умолчанию: {}.
Определяет обработку запросов сервером для компонента запроса пути.
server.options.query.parser
Значение по умолчанию: none.
Устанавливает метод анализа параметров запроса с помощью сигнатуры function(query), где:
-
query— объект, содержащий параметры входногоrequest.query. - метод должен вернуть объект, где каждый ключ — параметр, а соответствующее значение — значение параметра. Если метод вызывает ошибку, ошибка используется в качестве ответа или возвращается при вызове
request.setUrl().
const Qs = require('qs');
const options = {
query: {
parser: (query) => Qs.parse(query)
}
};
server.options.router
Значение по умолчанию: { isCaseSensitive: true, stripTrailingSlash: false }.
Управляет тем, как входные URI запросов сопоставляются со справочником маршрутов:
-
isCaseSensitive— определяет, считаются ли пути '/example' и '/EXAMPLE' различными ресурсами. По умолчаниюtrue. -
stripTrailingSlash— удаляет завершающие косые черты из входных путей. По умолчаниюfalse.
server.options.routes
Значение по умолчанию: none.
Объект параметров маршрута, используемый в качестве конфигурации по умолчанию для каждого маршрута.
server.options.state
Значение по умолчанию:
{
strictHeader: true,
ignoreErrors: false,
isSecure: true,
isHttpOnly: true,
isSameSite: 'Strict',
encoding: 'none'
}Устанавливает конфигурацию по умолчанию для каждого состояния (cookie), установленного явно через server.state() или неявно (без определения) с использованием объекта конфигурации состояния.
server.options.tls
Значение по умолчанию: none.
Используется для создания соединения HTTPS. Объект tls передаётся неизменённым серверу node HTTPS как описано в документации node HTTPS.
Устанавливается в true при передаче объекта listener, который был настроен для прямого использования TLS.
server.options.uri
Значение по умолчанию: построено на основе информации о сервере во время выполнения.
Полный общедоступный URI без пути (например, 'http://example.com:8080'). Если он присутствует, используется как информация о сервере, иначе строится из настроек сервера.
Свойства сервера
server.app
Доступ: чтение/запись.
Предоставляет безопасное место для хранения данных приложения сервера во время выполнения без потенциальных конфликтов с внутренними компонентами фреймворка. К данным можно получить доступ, когда сервер доступен. Инициализируется пустым объектом.
const server = Hapi.server();
server.app.key = 'value';
const handler = function (request, h) {
return request.server.app.key; // 'value'
};
server.auth.api
Доступ: специфичен для стратегии аутентификации.
Объект, где каждый ключ — имя стратегии аутентификации, а значение — раскрытый API стратегии. Доступен только тогда, когда схема аутентификации раскрывает API, возвращая ключ api в объекте, возвращённом из его функции реализации.
const server = Hapi.server({ port: 80 });
const scheme = function (server, options) {
return {
api: {
settings: {
x: 5
}
},
authenticate: function (request, h) {
const authorization = request.headers.authorization;
if (!authorization) {
throw Boom.unauthorized(null, 'Custom');
}
return h.authenticated({ credentials: { user: 'john' } });
}
};
};
server.auth.scheme('custom', scheme);
server.auth.strategy('default', 'custom');
console.log(server.auth.api.default.settings.x); // 5
server.auth.settings.default
Доступ: только для чтения.
Содержит настройки аутентификации по умолчанию, если стратегия по умолчанию была установлена через server.auth.default().
server.decorations
Доступ: только для чтения.
Предоставляет доступ к уже применённым декорациям к различным интерфейсам фреймворка. Объект нельзя напрямую изменять, а только через server.decorate. Содержит:
-
request— декорации объекта запроса. -
response— декорации объекта ответа. -
toolkit— декорации инструментария ответа. -
server— декорации объекта сервера.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
const success = function () {
return this.response({ status: 'ok' });
};
server.decorate('toolkit', 'success', success);
console.log(server.decorations.toolkit); // ['success']
server.events
Доступ: общедоступный интерфейс podium.
Эмиттер событий сервера. Использует podium с поддержкой проверки критериев событий, каналов и фильтров.
Для взаимодействия с server.events используйте следующие методы:
-
server.event(events)— регистрация событий приложения. -
server.events.emit(criteria, data)— отправка событий сервера. -
server.events.on(criteria, listener, context)— подписка на все события. -
server.events.once(criteria, listener, context)— подписка на одно событие.
Другие методы включают: server.events.removeListener(name, listener), server.events.removeAllListeners(name), и server.events.hasListeners(name).
'log' Событие
Тип события 'log' отправляет внутренние события сервера, сгенерированные фреймворком, а также события приложения, записанные с помощью server.log().
Обработчик события 'log' использует функцию с сигнатурой function(event, tags), где:
-
event— объект со следующими свойствами:-
timestamp— метка времени события. -
tags— массив тегов, определяющих событие (например,['error', 'http']). -
channel— устанавливается в'internal'для событий, сгенерированных внутри, иначе'app'для событий, сгенерированныхserver.log(). -
data— информация, специфичная для события. Доступна, когда данные события были предоставлены и не являются ошибкой. Ошибки передаются черезerror. -
error— объект ошибки, связанный с событием, если применимо. Не может появиться вместе сdata.
-
-
tags— объект, где каждыйevent.tag— ключ, а значение —true. Полезно для быстрого идентификации событий.
server.events.on('log', (event, tags) => {
if (tags.error) {
console.log(`Server error: ${event.error ? event.error.message : 'unknown'}`);
}
});Сгенерированные внутри события (идентифицируются по tags):
-
load— записывает текущие измерения загрузки сервера, когда сервер отклоняет запрос из-за высокой загрузки. Данные события содержат метрики загрузки процесса. -
connectionclienterror— событиеclientErrorполучено от слушателя HTTP или HTTPS. Данные события — объект ошибки, полученный.
'cachePolicy' Событие
Тип события 'cachePolicy' генерируется при создании политики кэша сервера политика кэша через server.cache() или при регистрации server.method() с включённым кэшированием. Обработчик события 'cachePolicy' использует функцию с сигнатурой function(cachePolicy, cache, segment), где:
-
cachePolicy— политика кэша catbox. -
cache— имя обеспечения кэша, использованное при создании политики, илиundefinedесли использовался кэш по умолчанию. -
segment— имя сегмента, использованное при создании политики.
server.events.on('cachePolicy', (cachePolicy, cache, segment) => {
console.log(`New cache policy created using cache: ${cache === undefined ? 'default' : cache} and segment: ${segment}`);
});
'request' Событие
Тип события 'request' отправляет внутренние события запроса, сгенерированные фреймворком, а также события приложения, записанные с помощью request.log().
Обработчик события 'request' использует функцию с сигнатурой function(request, event, tags), где:
-
request— объект запроса. -
event— объект со следующими свойствами:-
timestamp— метка времени события. -
tags— массив тегов, определяющих событие (например,['error', 'http']). -
channel— одно из-
'app'— события, сгенерированныеrequest.log(). -
'error'— генерируется один раз на запрос, если у ответа был код состояния500. -
'internal'— внутренние сгенерированные события.
-
-
request— идентификатор запроса идентификатор. -
data— информация, специфичная для события. Доступна, когда данные события были предоставлены и не являются ошибкой. Ошибки передаются черезerror. -
error— объект ошибки, связанный с событием, если применимо. Не может появиться вместе сdata.
-
-
tags— объект, где каждыйevent.tag— ключ, а значение —true. Полезно для быстрого идентификации событий.
server.events.on('request', (request, event, tags) => {
if (tags.error) {
console.log(`Request ${event.request} error: ${event.error ? event.error.message : 'unknown'}`);
}
});Чтобы прослушивать только один из каналов, используйте объект критериев событий:
server.events.on({ name: 'request', channels: 'error' }, (request, event, tags) => {
console.log(`Request ${event.request} failed`);
});Сгенерированные внутри события (идентифицируются по tags):
-
accept-encodingerror- запрос содержит неверный заголовок Accept-Encoding. -
authunauthenticated- со схемой аутентификации в запросе не указано. -
authunauthenticatedresponse{strategy}- выбранная стратегия аутентификации вернула ответ, не являющийся ошибкой (например, переадресация на страницу входа). -
authunauthenticatederror{strategy}- запрос не прошёл проверку выбранной стратегией аутентификации (неверные учетные данные). -
authunauthenticatedmissing{strategy}- запрос не прошёл проверку выбранной стратегией аутентификации (учетные данные не найдены). -
authunauthenticatedtry{strategy}- запрос не прошёл проверку выбранной стратегией аутентификации в режиме'try'и будет продолжен. -
authscopeerror- запрос прошёл аутентификацию, но не удовлетворяет требованиям к доступу. -
authentityusererror- запрос прошёл аутентификацию, но содержал сущность приложения, когда требовалась сущность пользователя. -
authentityapperror- запрос прошёл аутентификацию, но содержал сущность пользователя, когда требовалась сущность приложения. -
exterror- произошла ошибка обработчика расширенияonPostResponse. -
handlererror- обработчик маршрута вернул ошибку. Включает продолжительность выполнения и сообщение об ошибке. -
preerror- метод pre был выполнен и вернул ошибку. Включает продолжительность выполнения, ключ назначения и ошибку. -
internalerror- запросу был назначен HTTP-ответ со статусом 500. -
internalimplementationerror- неправильно реализованный метод жизненного цикла. -
requestaborterror- запрос прерван. -
requestclosederror- запрос преждевременно закрыт. -
requesterror- поток запроса выдал ошибку. Включает ошибку. -
requestservertimeouterror- запрос занял слишком много времени на обработку сервером. Включает значение конфигурации таймаута и продолжительность. -
stateerror- запрос содержал недействительный cookie или cookies. Включает cookies и подробности ошибки. -
stateresponseerror- ответ содержал недействительный cookie, что помешало генерации корректного заголовка. Включает ошибку. -
payloaderror- произошла ошибка обработки тела запроса. Включает ошибку. -
responseerror- произошла ошибка при записи ответа клиенту. Включает ошибку. -
responseerrorclose- произошла ошибка при записи ответа клиенту из-за преждевременного закрытия соединения. -
responseerroraborted- произошла ошибка при записи ответа клиенту из-за преждевременного прерывания соединения. -
responseerrorcleanup- произошла ошибка при освобождении ресурсов ответа. -
validationerror{input}- произошла ошибка валидации входных данных (т.е. тела, запроса, параметров, заголовков). Включает ошибку. Выдаётся только при установленномfailActionв значение'log'. -
validationresponseerror- произошла ошибка валидации ответа. Включает сообщение об ошибке. Выдаётся только при установленномfailActionв значение'log'.
'response' Событие
Тип события 'response' срабатывает после отправки ответа клиенту (или при закрытии соединения с клиентом без отправки ответа, в этом случае request.response равен null). Одно событие генерируется на запрос. Обработчик события 'response' использует сигнатуру функции function(request), где:
-
request- объект запроса.
server.events.on('response', (request) => {
console.log(`Response sent for request: ${request.info.id}`);
});
'route' Событие
Тип события 'route' срабатывает при добавлении маршрута с помощью server.route(). Обработчик события 'route' использует сигнатуру функции function(route), где:
-
route- информация о маршруте. Объектrouteне должен изменяться.
server.events.on('route', (route) => {
console.log(`New route added: ${route.path}`);
});
'start' Событие
Тип события 'start' срабатывает при запуске сервера с помощью server.start(). Обработчик события 'start' использует сигнатуру функции function().
server.events.on('start', () => {
console.log('Server started');
});
'closing' Событие
Тип события 'closing' срабатывает при остановке сервера с помощью server.stop(). Оно срабатывает, когда приём входящих запросов больше не производится, но до закрытия всех активных подключений, и, следовательно, до срабатывания события 'stop'. Обработчик события 'closing' использует сигнатуру функции function().
server.events.on('closing', () => {
console.log('Server is closing');
});
'stop' Событие
Тип события 'stop' срабатывает при остановке сервера с помощью server.stop(). Обработчик события 'stop' использует сигнатуру функции function().
server.events.on('stop', () => {
console.log('Server stopped');
});
server.info Информация о сервере
Доступ: только для чтения.
Объект, содержащий информацию о сервере, где:
-
id- уникальный идентификатор сервера (в формате '{имя_хоста}:{PID}:{текущее_время_base36}'). -
created- метка времени создания сервера. -
started- метка времени запуска сервера (0при остановке). -
port- порт подключения, определённый по следующим правилам:- до запуска сервера: значение конфигурации
port. - после запуска сервера: фактический назначенный порт, если порт не был сконфигурирован или был установлен в
0.
- до запуска сервера: значение конфигурации
-
host- значение конфигурацииhost. -
address- активный IP-адрес, к которому подключение было привязано после запуска. Устанавливается вundefinedдо запуска сервера или при использовании порта, отличного от TCP (например, UNIX-доменная сокета). -
protocol- используемый протокол:-
'http'- HTTP. -
'https'- HTTPS. -
'socket'- UNIX-доменная сокета или именованная труба Windows.
-
-
uri- строковое представление подключения (например, 'http://example.com:8080' или 'socket:/unix/domain/socket/path'). Содержит значениеuri, если оно задано, в противном случае построено на основе доступных настроек. Если конфигурацияportне задана или установлена в0, компонент порта вuriне будет включён до запуска сервера.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
console.log(server.info.port); // 80
server.listener Слушатель сервера
Доступ: только для чтения и публичный интерфейс слушателя.
Объект HTTP-сервера Node.
const Hapi = require('@hapi/hapi');
const SocketIO = require('socket.io');
const server = Hapi.server({ port: 80 });
const io = SocketIO.listen(server.listener);
io.sockets.on('connection', (socket) => {
socket.emit({ msg: 'welcome' });
});
server.load Загрузка сервера
Доступ: только для чтения.
Объект, содержащий метрики загрузки процесса (когда включён load.sampleInterval):
-
eventLoopDelay- задержка цикла событий в миллисекундах. -
eventLoopUtilization- текущее значение использования цикла событий. -
heapUsed- использование памяти кучи V8. -
rss- использование памяти RSS.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ load: { sampleInterval: 1000 } });
console.log(server.load.rss);
server.methods Методы сервера
Доступ: только для чтения.
Методы сервера — это функции, зарегистрированные на сервере и используемые в приложении в качестве общих утилит. Преимущество в возможности их настройки для использования встроенного кеша и совместного использования между несколькими обработчиками запросов без необходимости создания общего модуля.
sever.methods — это объект, предоставляющий доступ к методам, зарегистрированным с помощью server.method(), где каждое имя метода сервера является свойством объекта.
const Hapi = require('@hapi/hapi');
const server = Hapi.server();
server.method('add', (a, b) => (a + b));
const result = server.methods.add(1, 2); // 3
server.mime MIME-типы сервера
Доступ: только для чтения и публичный интерфейс mimos.
Предоставляет доступ к базе данных MIME-типов сервера, используемой для задания информации о формате содержимого. Объект не должен изменяться напрямую, а только через настройку сервера mime.
const Hapi = require('@hapi/hapi');
const options = {
mime: {
override: {
'node/module': {
source: 'steve',
compressible: false,
extensions: ['node', 'module', 'npm'],
type: 'node/module'
}
}
}
};
const server = Hapi.server(options);
console.log(server.mime.path('code.js').type) // 'application/javascript'
console.log(server.mime.path('file.npm').type) // 'node/module'
server.plugins Плагины сервера
Доступ: чтение/запись.
Объект, содержащий значения, экспонированные каждым зарегистрированным плагином, где каждый ключ — имя плагина, а значения — экспонированные свойства каждого плагина с использованием server.expose(). Плагины могут устанавливать значение объекта server.plugins[name] напрямую или с помощью метода server.expose().
exports.plugin = {
name: 'example',
register: function (server, options) {
server.expose('key', 'value');
server.plugins.example.other = 'other';
console.log(server.plugins.example.key); // 'value'
console.log(server.plugins.example.other); // 'other'
}
};
server.realm Область сервера
Доступ: только для чтения.
Объект области содержит защищённые настройки сервера, специфичные для каждого плагина или стратегии аутентификации. При регистрации плагина или схемы аутентификации предоставляется ссылка на объект server, с новым контейнером server.realm, специфичным для этой регистрации. Это позволяет каждому плагину сохранять свои собственные настройки без утечек и влияния на другие плагины.
Например, плагин может установить путь к файлу по умолчанию для локальных ресурсов без нарушения конфигурированных путей других плагинов. При вызове server.bind(), свойство settings.bind активной области устанавливается и используется маршрутами и расширениями, добавленными на том же уровне (корень сервера или плагин).
Объект server.realm содержит:
-
modifiers- когда объект сервера предоставляется в качестве аргумента плагинуregister()метод,modifiersпредоставляет настройки регистрации, переданные методуserver.register(), и включает:-
route- настройки маршрутизации:-
prefix- префикс пути маршрута, используемый всеми вызовамиserver.route()со стороны сервера. Обратите внимание, что если используется префикс, и путь маршрута задан как'/', результирующий путь не будет содержать заключительный слеш. -
vhost- настройки виртуального хоста маршрута, используемые всеми вызовамиserver.route()со стороны сервера.
-
-
-
parent- область родительского объекта сервера илиnullдля корневого сервера. -
plugin- имя активного плагина (пустая строка, если на корневом сервере). -
pluginOptions- параметры плагина, переданные при регистрации. -
plugins- состояние, специфичное для плагина, которое должно быть доступно только активным плагинам, работающим в одном состоянии.plugins- это объект, где каждый ключ — имя плагина, а значение — состояние плагина. -
settings- переопределения настроек:files.relativeTobind
Объект server.realm следует считать только для чтения и его нельзя изменять напрямую, за исключением свойства plugins, которое каждый плагин может непосредственно управлять, устанавливая его свойства внутри plugins[name].
exports.register = function (server, options) {
console.log(server.realm.modifiers.route.prefix);
};
server.registrations
Доступ: только для чтения.
Объект текущих зарегистрированных плагинов, где каждый ключ — имя зарегистрированного плагина, а значение — объект, содержащий:
-
version- версия плагина. -
name- имя плагина. -
options- (необязательно) параметры, переданные плагину при регистрации.
server.settings
Доступ: только для чтения.
Объект конфигурации сервера после применения значений по умолчанию.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({
app: {
key: 'value'
}
});
console.log(server.settings.app); // { key: 'value' }
server.states
Доступ: только для чтения и statehood общедоступный интерфейс.
Менеджер файлов cookie сервера.
server.states.settings
Доступ: только для чтения.
Настройки менеджера файлов cookie сервера. Настройки основаны на значениях, настроенных в server.options.state.
server.states.cookies
Доступ: только для чтения.
Объект, содержащий конфигурацию каждого файла cookie, добавленного с помощью server.state(), где каждый ключ — имя файла cookie, а значение — объект конфигурации.
server.states.names
Доступ: только для чтения.
Массив, содержащий имена всех настроенных файлов cookie.
server.type
Доступ: только для чтения.
Строка, указывающая тип слушателя, где:
-
'socket'- сокет доменной UNIX-системы или именованная Windows-пайпа. -
'tcp'- HTTP-слушатель.
server.version
Доступ: только для чтения.
Номер версии модуля hapi.
const Hapi = require('@hapi/hapi');
const server = Hapi.server();
console.log(server.version); // '17.0.0'
server.auth.default(options)
Устанавливает стратегию по умолчанию, которая применяется ко всем маршрутам, где:
-
options- один из:- строка с именем стратегии по умолчанию
- объект конфигурации аутентификации, использующий тот же формат, что и параметры обработчика маршрута
auth.
Возвращаемое значение: ничего.
Стратегия по умолчанию не применяется, если маршрут явно указывает auth как false, или имеет настроенную стратегию аутентификации (содержит параметры аутентификации strategy или strategies).
Обратите внимание, что если для маршрута настроена аутентификация, стратегия по умолчанию применяется только при добавлении маршрута, а не во время выполнения. Это означает, что вызов server.auth.default() после добавления маршрута с настройками аутентификации не повлияет на ранее добавленные маршруты. Однако стратегия по умолчанию будет применена к маршрутам, добавленным до вызова server.auth.default() , если эти маршруты не имеют настроек аутентификации.
Настройки стратегии аутентификации по умолчанию можно получить с помощью server.auth.settings.default. Чтобы получить активную конфигурацию аутентификации маршрута, используйте server.auth.lookup(request.route).
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
server.auth.scheme('custom', scheme);
server.auth.strategy('default', 'custom');
server.auth.default('default');
server.route({
method: 'GET',
path: '/',
handler: function (request, h) {
return request.auth.credentials.user;
}
});
server.auth.scheme(name, scheme)
Регистрирует схему аутентификации, где:
-
name- имя схемы. -
scheme- метод, реализующий схему, со сигнатуройfunction(server, options), где:-
server- ссылка на объект сервера, к которому добавляется схема. Каждая стратегия аутентификации получает собственнуюserver.realm, родитель которой — областьserverпри вызовеserver.auth.strategy(). -
options- (необязательно) аргумент схемыoptions, переданный вserver.auth.strategy()при создании стратегии.
-
Возвращаемое значение: ничего.
Функция scheme должна возвращать объект схемы аутентификации при вызове.
Схема аутентификации
Схема аутентификации — это объект со следующими свойствами:
-
api- (необязательно) объект, доступный через объектserver.auth.api. -
async authenticate(request, h)- (обязательно) функция метода жизненного цикла, вызываемая для каждого входящего запроса, настроенного со схемой аутентификации. Методу предоставляются два специальных метода инструментария для возврата аутентифицированного или неаутентифицированного результата:-
h.authenticated()- указывает, что запрос аутентифицирован успешно. -
h.unauthenticated()- указывает, что запрос не смог пройти аутентификацию.
-
-
async payload(request, h)- (необязательно) метод жизненного цикла для аутентификации полезной нагрузки запроса. -
async response(request, h)- (необязательно) метод жизненного цикла для добавления заголовков аутентификации в ответ перед записью заголовков или полезной нагрузки ответа. -
async verify(auth)- (необязательно) метод для проверки того, что предоставленные учетные данные аутентификации по-прежнему действительны (например, не истекли или не аннулированы после первоначальной аутентификации), где:-
auth- объектrequest.auth, содержащий объектыcredentialsиartifacts, возвращенные методом схемыauthenticate(). - метод генерирует исключение
Error, когда предоставленные учетные данные больше не действительны (например, истекли или аннулированы). Обратите внимание, что методу не доступен исходный запрос, только учетные данные и артефакты, созданные методомauthenticate().
-
-
options- (необязательно) объект со следующими ключами:-
payload- еслиtrue, требуется валидация полезной нагрузки в качестве части схемы и запрещает маршрутам отключать валидацию полезной нагрузки. По умолчаниюfalse.
-
Когда метод схемы authenticate() вызывает ошибку или вызывает h.unauthenticated(), конкретика ошибки влияет на то, будут ли предприняты дополнительные стратегии аутентификации (если они настроены для маршрута). Если ошибка содержит сообщение, дополнительные стратегии не будут предприняты. Если ошибка не содержит сообщения, но содержит имя схемы (например, Boom.unauthorized(null, 'Custom')), дополнительные стратегии будут предприняты в порядке приоритета (определенном в конфигурации маршрута). При неудачной аутентификации имена схем будут присутствовать в заголовке «WWW-Authenticate».
Когда метод схемы payload() вызывает ошибку с сообщением, это означает, что валидация полезной нагрузки не прошла из-за некорректной полезной нагрузки. Если ошибка не содержит сообщения, но содержит имя схемы (например, Boom.unauthorized(null, 'Custom') ), аутентификация все еще может быть успешной, если настройка маршрута auth.payload установлена в 'optional'.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
const scheme = function (server, options) {
return {
authenticate: function (request, h) {
const req = request.raw.req;
const authorization = req.headers.authorization;
if (!authorization) {
throw Boom.unauthorized(null, 'Custom');
}
return h.authenticated({ credentials: { user: 'john' } });
}
};
};
server.auth.scheme('custom', scheme);
server.auth.strategy(name, scheme, [options])
Регистрирует стратегию аутентификации, где:
-
name- имя стратегии. -
scheme- имя схемы (должно быть предварительно зарегистрировано с помощьюserver.auth.scheme()). -
options- параметры схемы, основанные на требованиях схемы.
Возвращаемое значение: ничего.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
server.auth.scheme('custom', scheme);
server.auth.strategy('default', 'custom');
server.route({
method: 'GET',
path: '/',
options: {
auth: 'default',
handler: function (request, h) {
return request.auth.credentials.user;
}
}
});
await server.auth.test(strategy, request)
Проверяет запрос по стратегии аутентификации, где:
-
strategy- имя стратегии, зарегистрированной с помощьюserver.auth.strategy(). -
request- объект запроса.
Возвращаемое значение: объект, содержащий аутентификацию credentials и artifacts , если аутентификация прошла успешно, в противном случае генерируется ошибка.
Обратите внимание, что метод test() не учитывает конфигурацию аутентификации маршрута. Он также не выполняет аутентификацию полезной нагрузки. Он ограничен выполнением основной аутентификации стратегии. Он не включает проверку области, сущности или других свойств маршрута.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
server.auth.scheme('custom', scheme);
server.auth.strategy('default', 'custom');
server.route({
method: 'GET',
path: '/',
handler: async function (request, h) {
try {
const { credentials, artifacts } = await request.server.auth.test('default', request);
return { status: true, user: credentials.name };
}
catch (err) {
return { status: false };
}
}
});
await server.auth.verify(request)
Проверяет учетные данные аутентификации запроса по стратегии аутентификации, где:
-
request- объект запроса.
Возвращаемое значение: ничего, если проверка прошла успешно, в противном случае генерируется ошибка.
Обратите внимание, что метод verify() не учитывает конфигурацию аутентификации маршрута или любую другую информацию из запроса, кроме объекта request.auth. Он также не выполняет аутентификацию полезной нагрузки. Он ограничен проверкой того, что ранее действительные учетные данные по-прежнему действительны (например, не аннулированы или не истекли). Он не включает проверку области, сущности или других свойств.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
server.auth.scheme('custom', scheme);
server.auth.strategy('default', 'custom');
server.route({
method: 'GET',
path: '/',
handler: async function (request, h) {
try {
const credentials = await request.server.auth.verify(request);
return { status: true, user: credentials.name };
}
catch (err) {
return { status: false };
}
}
});
server.bind(context)
Устанавливает глобальный контекст, используемый в качестве объекта связывания по умолчанию при добавлении маршрута или расширения, где:
-
context— объект, используемый для привязкиthisв методах жизненного цикла, таких как обработчик маршрута и методы расширения. Контекст также доступен какh.context.
Значение возврата: ничего.
При установке контекста внутри плагина, контекст применяется только к методам, настроенным плагином. Обратите внимание, что контекст применяется только к маршрутам и расширениям, добавленным после его установки. Игнорируется, если привязываемый метод является стрелочной функцией.
const handler = function (request, h) {
return this.message; // Or h.context.message
};
exports.plugin = {
name: 'example',
register: function (server, options) {
const bind = {
message: 'hello'
};
server.bind(bind);
server.route({ method: 'GET', path: '/', handler });
}
};
server.cache(options)
Предоставляет сегмент кэша внутри серверного кэша, где:
-
options— конфигурация catbox политики, где:-
expiresIn— относительный срок истечения, выраженный в миллисекундах с момента сохранения элемента в кэше. Нельзя использовать вместе сexpiresAt. -
expiresAt— время суток, выраженное в 24-часовом формате 'ЧЧ:ММ', в которое все записи кэша истекают. Используется местное время. Нельзя использовать вместе сexpiresIn. -
generateFunc— функция, используемая для генерации нового элемента кэша, если он не найден в кэше при вызовеget(). Подпись метода:async function(id, flags), где:- `id` - the `id` string or object provided to the `get()` method. - `flags` - an object used to pass back additional flags to the cache where: - `ttl` - the cache ttl value in milliseconds. Set to `0` to skip storing in the cache. Defaults to the cache global policy. -
staleIn— число миллисекунд, чтобы пометить элемент, сохраненный в кэше, как устаревший и попытаться перегенерировать его, когдаgenerateFuncпредоставлен. Должно быть меньшеexpiresIn. -
staleTimeout— число миллисекунд, через которое проверяется, является ли элемент устаревшим. -
generateTimeout— число миллисекунд, через которое ожидается возврат ошибки тайм-аута, когда функцияgenerateFuncзанимает слишком много времени для возвращения значения. Когда значение, наконец, возвращено, оно хранится в кэше для будущих запросов. Требуется, еслиgenerateFuncприсутствует. Установлено вfalse, чтобы отключить тайм-ауты, что может привести к зависанию всех запросовget()на неопределенное время. -
generateOnReadError— еслиfalse, ошибка чтения из upstream кэша остановит методcache.get()от вызова функции генерации, а вместо этого вернёт ошибку кэша. По умолчаниюtrue. -
generateIgnoreWriteError— еслиfalse, ошибка записи в upstream кэша при вызовеcache.get()будет возвращена вместе с сгенерированным значением при вызове. По умолчаниюtrue. -
dropOnError— еслиtrue, ошибка или тайм-аут вgenerateFuncприводит к удалению устаревшего значения из кэша. По умолчаниюtrue. -
pendingGenerateTimeout— число миллисекунд, пока вызовgenerateFuncпродолжается для данного идентификатора, прежде чем последующий вызовgenerateFuncбудет разрешен. По умолчанию0(нет блокировки одновременных вызововgenerateFuncпомимоstaleTimeout). -
cache— имя кэша, настроенное вserver.cache. По умолчанию — кэш по умолчанию. -
segment— имя сегмента, используемое для изоляции кэшированных элементов в разделе кэша. При вызове внутри плагина, по умолчанию '!имя', где 'имя' — имя плагина. При вызове внутри серверного метода, по умолчанию '#имя', где 'имя' — имя серверного метода. Требуется при вызове вне плагина. -
shared— еслиtrue, позволяет нескольким кэшам разделять один и тот же сегмент. По умолчаниюfalse.
-
Значение возврата: объект catbox политики.
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
const cache = server.cache({ segment: 'countries', expiresIn: 60 * 60 * 1000 });
await cache.set('norway', { capital: 'oslo' });
const value = await cache.get('norway');
}
await server.cache.provision(options)
Предоставляет серверный кэш, как описано в server.cache, где:
-
options— такие же, как серверныеcacheопции конфигурации.
Значение возврата: ничего.
Обратите внимание, что если сервер был инициализирован или запущен, кэш будет автоматически запущен, чтобы соответствовать состоянию любого другого предоставленного серверного кэша.
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
await server.initialize();
await server.cache.provision({ provider: require('@hapi/catbox-memory'), name: 'countries' });
const cache = server.cache({ cache: 'countries', expiresIn: 60 * 60 * 1000 });
await cache.set('norway', { capital: 'oslo' });
const value = await cache.get('norway');
}
server.control(server)
Связывает другой сервер с состоянием инициализации/старта/остановки текущего сервера, вызывая у управляемого сервера методы initialize()/start()/stop() всякий раз, когда вызываются методы текущего сервера, где:
-
server— объект сервера hapi, который будет управляется.
server.decoder(encoding, decoder)
Регистрирует пользовательский декомпрессор кодирования для расширения встроенной поддержки 'gzip' и 'deflate', где:
-
encoding— строка имени декодера. -
decoder— функция, использующая подписьfunction(options), гдеoptions— опции, специфичные для кодирования, настроенные в маршрутной опцииpayload.compression, а возвращаемое значение — объект, совместимый с выводом нодаzlib.createGunzip().
Значение возврата: ничего.
const Zlib = require('zlib');
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80, routes: { payload: { compression: { special: { chunkSize: 16 * 1024 } } } } });
server.decoder('special', (options) => Zlib.createGunzip(options));
server.decorate(type, property, method, [options])
Расширяет различные интерфейсы фреймворка пользовательскими методами, где:
-
type— декорируемый интерфейс. Поддерживаемые типы:-
'handler'— добавляет новый тип обработчика, используемый в обработчиках маршрутов. -
'request'— добавляет методы к объекту Запрос. -
'response'— добавляет методы к объекту Ответ. -
'server'— добавляет методы к объекту Сервер. -
'toolkit'— добавляет методы к инструментарию ответа.
-
-
property— имя ключа декорации объекта или символ. -
method— функция расширения или другое значение. -
options— (необязательно) поддерживает следующие необязательные параметры:-
apply— когдаtypeравно'request', еслиtrue, функцияmethodвызывается с подписьюfunction(request), гдеrequest— текущий объект запроса, а возвращаемое значение назначается как декорация. -
extend— еслиtrue, переопределяет существующую декорацию.methodдолжна быть функцией с подписьюfunction(existing), где:-
existing— предыдущее значение метода декорации. - должна возвращать новую функцию или значение декорации.
- не может быть использована для расширения декораций обработчиков.
-
-
Значение возврата: ничего.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
const success = function () {
return this.response({ status: 'ok' });
};
server.decorate('toolkit', 'success', success);
server.route({
method: 'GET',
path: '/',
handler: function (request, h) {
return h.success();
}
});При регистрации декорации обработчика, method должна быть функцией с подписью function(route, options), где:
-
route— информация о маршруте. -
options— объект конфигурации, предоставленный в конфигурации обработчика.
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ host: 'localhost', port: 8000 });
// Defines new handler for routes on this server
const handler = function (route, options) {
return function (request, h) {
return 'new handler: ' + options.msg;
}
};
server.decorate('handler', 'test', handler);
server.route({
method: 'GET',
path: '/',
handler: { test: { msg: 'test' } }
});
await server.start();
}Функция method может иметь свойство объекта или функции defaults. Если свойство установлено в объект, этот объект используется в качестве конфигурации по умолчанию для маршрутов, использующих этот обработчик. Если свойство установлено в функцию, функция использует подпись function(method) и возвращает конфигурацию маршрута по умолчанию.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ host: 'localhost', port: 8000 });
const handler = function (route, options) {
return function (request, h) {
return 'new handler: ' + options.msg;
}
};
// Change the default payload processing for this handler
handler.defaults = {
payload: {
output: 'stream',
parse: false
}
};
server.decorate('handler', 'test', handler);
server.dependency(dependencies, [after])
Используется в плагине для объявления необходимой зависимости от других плагинов, необходимых для работы текущего плагина (перечисленные плагины должны быть зарегистрированы перед инициализацией или запуском сервера), где:
-
dependencies— одно из:- строка имени одного плагина.
- массив строк имён плагинов.
- объект, где каждый ключ — имя плагина, а соответствующее значение — строка диапазона версии, которая должна соответствовать зарегистрированной версии плагина.
-
after— (необязательно) функция, вызываемая после регистрации всех указанных зависимостей и перед запуском сервера. Функция вызывается только при инициализации или запуске сервера. Подпись функции:async function(server), где:-
server— сервер, на котором был вызван методdependency().
-
Значение возврата: ничего.
Метод after идентичен установке точки расширения сервера на 'onPreStart'.
Если обнаружена циклическая зависимость, выводится исключение (например, два плагина имеют функцию after для вызова друг после друга).
const after = function (server) {
// Additional plugin registration logic
};
exports.plugin = {
name: 'example',
register: function (server, options) {
server.dependency('yar', after);
}
};Зависимости также могут быть установлены через свойство плагина dependencies (не поддерживает установку after):
exports.plugin = {
name: 'test',
version: '1.0.0',
dependencies: {
yar: '1.x.x'
},
register: function (server, options) { }
};Конфигурация dependencies принимает одно из:
- строка имени одного плагина.
- массив строк имён плагинов.
- объект, где каждый ключ — имя плагина, а соответствующее значение — строка диапазона версии, которая должна соответствовать зарегистрированной версии плагина.
server.encoder(encoding, encoder)
Регистрирует пользовательский компрессор кодирования для расширения встроенной поддержки 'gzip' и 'deflate', где:
-
encoding— строка имени кодировщика. -
encoder— функция, использующая подписьfunction(options), гдеoptions— опции, специфичные для кодирования, настроенные в опции маршрутаcompression, а возвращаемое значение — объект, совместимый с выводом нодаzlib.createGzip().
Значение возврата: ничего.
const Zlib = require('zlib');
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80, routes: { compression: { special: { chunkSize: 16 * 1024 } } } });
server.encoder('special', (options) => Zlib.createGzip(options));
server.event(events)
Регистрирует пользовательские события приложения, где:
-
events- должно быть одним из следующих:-
строка имени события.
-
объект опций события со следующими необязательными ключами (если не указано иное):
-
name- строка имени события (обязательно). -
channels- строка или массив строк, определяющих доступные каналы события. По умолчанию никаких ограничений по каналам (обновления события могут указывать канал или нет). -
clone- еслиtrue, то объектdata, переданный вserver.events.emit(), клонируется перед передачей слушателям (если не указано иначе каждым слушателем). По умолчаниюfalse(dataпередаётся как есть). -
spread- еслиtrue, то объектdata, переданный вserver.event.emit(), должен быть массивом, и методlistenerвызывается с каждым элементом массива в качестве отдельного аргумента (если не указано иначе каждым слушателем). Это следует использовать только тогда, когда структура данных, отправляемых на передачу, известна и предсказуема. По умолчаниюfalse(dataпередаётся как один аргумент независимо от его типа). -
tags- еслиtrueи объектcriteria, переданный вserver.event.emit(), включаетtags, метки отображаются в объект (где каждая строка метки — ключ, а значение —true), который добавляется в список аргументов в конце. Настройка может быть переопределена каждым слушателем. По умолчаниюfalse. -
shared- еслиtrue, то одно и то же событиеnameможет быть зарегистрировано несколько раз, при этом повторная регистрация игнорируется. Обратите внимание, что если конфигурация регистрации изменяется между регистрацией, используется только первая конфигурация. По умолчаниюfalse(повторная регистрация вызовет ошибку).
-
-
массив, содержащий любой из вышеперечисленных элементов.
-
Значение возврата: ничего.
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
server.event('test');
server.events.on('test', (update) => console.log(update));
await server.events.gauge('test', 'hello');
}
server.events.emit(criteria, data)
Отправляет пользовательское событие приложения всем подписанным слушателям, где:
-
criteria- критерии обновления события, которые должны быть одним из следующих:- строка имени события.
- объект со следующими необязательными ключами (если не указано иное):
-
name- строка имени события (обязательно). -
channel- строка имени канала. -
tags- строка тега или массив строк тегов.
-
-
data- значение, отправляемое подписчикам. Еслиdataявляется функцией, сигнатура функции —function(), и она вызывается один раз для генерации (возвращаемого значения) фактических данных, отправляемых слушателям. Если слушатели, соответствующие событию, отсутствуют, функцияdataне вызывается.
Значение возврата: ничего.
Обратите внимание, что события должны быть зарегистрированы перед их отправкой или подпиской на них, вызвав server.event(events). Это делается для обнаружения опечаток в имени события и недопустимых действий с событием.
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
server.event('test');
server.events.on('test', (update) => console.log(update));
server.events.emit('test', 'hello');
}
server.events.on(criteria, listener, context)
Подписывается на событие, где:
-
criteria- критерии подписки, которые должны быть одним из следующих:-
строка имени события, которая может быть любой из встроенных событий сервера или пользовательского события приложения, зарегистрированного с помощью
server.event(). -
объект критериев со следующими необязательными ключами (если не указано иное):
-
name- (обязательно) строка имени события. -
channels- строка или массив строк, определяющих каналы события для подписки. Если регистрация события указала список разрешенных каналов, массивchannelsдолжен соответствовать разрешенным каналам. Еслиchannelsуказаны, обновления событий без обозначения канала не будут включены в подписку. По умолчанию никаких фильтров по каналам. -
clone- еслиtrue, то объектdata, переданный вserver.event.emit(), клонируется перед вызовом методаlistener. По умолчанию опция регистрации события (которая по умолчаниюfalse). -
count- целое положительное число, указывающее количество раз, котороеlistenerможет быть вызвано, после чего подписка автоматически удаляется. Значение1эквивалентно вызовуserver.events.once(). По умолчанию нет лимита. -
filter- метки события (если есть) для подписки, которые могут быть одним из следующих:-
строка метки.
-
массив строк меток.
-
объект со следующим:
-
tags- строка метки или массив строк меток. -
all- еслиtrue, всеtagsдолжны быть присутствовать для того, чтобы обновление события соответствовало подписке. По умолчаниюfalse(хотя бы одна совпадающая метка).
-
-
-
spread- еслиtrue, и объектdata, переданный вserver.event.emit(), является массивом, методlistenerвызывается с каждым элементом массива в качестве отдельного аргумента. Это следует использовать только тогда, когда структура данных, отправляемых на передачу, известна и предсказуема. По умолчанию опция регистрации события (которая по умолчаниюfalse). -
tags- еслиtrueи объектcriteria, переданный вserver.event.emit(), включаетtags, метки отображаются в объект (где каждая строка метки — ключ, а значение —true), который добавляется в список аргументов в конце. По умолчанию опция регистрации события (которая по умолчаниюfalse).
-
-
-
listener- метод обработчика, настроенный для получения обновлений события. Сигнатура функции зависит от аргумента события, а также от опцийspreadиtags. -
context- объект, привязанный к обработчику слушателя.
Значение возврата: ничего.
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
server.event('test');
server.events.on('test', (update) => console.log(update));
server.events.emit('test', 'hello');
}
server.events.once(criteria, listener, context)
То же, что и вызов server.events.on() с опцией count установленной в 1.
Значение возврата: ничего.
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
server.event('test');
server.events.once('test', (update) => console.log(update));
server.events.emit('test', 'hello');
server.events.emit('test', 'hello'); // Ignored
}
await server.events.once(criteria)
То же, что и вызов server.events.on() с опцией count установленной в 1.
Значение возврата: промис, который разрешается, когда событие отправляется.
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
server.event('test');
const pending = server.events.once('test');
server.events.emit('test', 'hello');
const update = await pending;
}
await server.events.gauge(criteria, data)
Ведёт себя идентично server.events.emit(), но также возвращает массив результатов всех обработчиков событий, которые выполняются. Возвращаемое значение - это результат Promise.allSettled(), где каждый элемент в результирующем массиве - это { status: 'fulfilled', value } в случае успешного обработчика или { status: 'rejected', reason } в случае обработчика, который вызывает ошибку.
Обратите внимание, что системные ошибки, такие как TypeError, не обрабатываются специально, и рекомендуется тщательно проверять любые отклонения с помощью чего-либо вроде bounce.
server.expose(key, value, [options])
Используется внутри плагина для экспонирования свойства через server.plugins[name], где:
-
key- назначенный ключ (server.plugins[name][key]). -
value- назначенное значение. -
options- необязательные настройки:-
scope- управляет тем, как обрабатывать наличие области видимости плагина в имени (например,@hapi/test):-
false- область видимости удаляется (например,@hapi/testизменяется наtestподserver.plugins). Это значение по умолчанию. -
true- область видимости сохраняется как есть (например,@hapi/testиспользуется какserver.plugins['@hapi/test']). -
'underscore'- область видимости переписывается (например,@hapi/testиспользуется какserver.plugins.hapi__test).
-
-
Значение возврата: ничего.
exports.plugin =
name: 'example',
register: function (server, options) {
server.expose('util', () => console.log('something'));
}
};
server.expose(obj)
Объединяет объект в существующее содержимое server.plugins[name], где:
-
obj- объект, объединяемый в контейнер экспонированных свойств.
Значение возврата: ничего.
exports.plugin = {
name: 'example',
register: function (server, options) {
server.expose({ util: () => console.log('something') });
}
};Обратите внимание, что все свойства obj глубоко клонируются в server.plugins[name], поэтому не используйте этот метод для экспонирования больших объектов, которые могут быть дорогими для клонирования или одиночных объектов, таких как объекты клиента базы данных. Вместо этого отдавайте предпочтение server.expose(key, value), который копирует только ссылку на value.
server.ext(events)
Регистрирует функцию расширения в одном из пунктов расширения цикла жизни запроса , где:
-
events- объект или массив объектов со следующими полями:-
type- (обязательно) имя события точки расширения. Доступные точки расширения включают точки расширения запроса, а также следующие точки расширения сервера:-
'onPreStart'- вызывается перед запуском слушателей соединения. -
'onPostStart'- вызывается после запуска слушателей соединения. -
'onPreStop'- вызывается перед остановкой слушателей соединения. -
'onPostStop'- вызывается после остановки слушателей соединения.
-
-
method- (обязательно) функция или массив функций, которые должны быть выполнены в определённый момент обработки запроса. Требуемая сигнатура функции расширения:-
точки расширения сервера:
async function(server)где:-
server- объект сервера. -
this- объект, предоставленный черезoptions.bindили текущий активный контекст, установленный с помощьюserver.bind().
-
-
точки расширения запроса: метод жизненного цикла.
-
-
options- (необязательно) объект со следующими полями:-
before- строка или массив строк с именами плагинов, которые этот метод должен выполнить перед ним (в том же событии). В противном случае, методы расширения выполняются в порядке добавления. -
after- строка или массив строк с именами плагинов, которые этот метод должен выполнить после него (в том же событии). В противном случае, методы расширения выполняются в порядке добавления. -
bind- объект контекста, передаваемый обратно предоставленному методу (черезthis) при его вызове. Игнорируется, если метод является стрелочной функцией. -
sandbox- если установлено в'plugin', при добавлении точек расширения запроса расширение добавляется только к маршрутам, определённым текущим плагином. Не разрешается при конфигурировании расширений на уровне маршрутов или при добавлении расширений сервера. По умолчанию установлено в'server', что применяется к любому маршруту, добавленному к серверу, к которому добавлено расширение. -
timeout- количество миллисекунд, ожидаемых для выполненияmethod, прежде чем вернуть ошибку таймаута. По умолчанию таймаут не используется.
-
-
Значение возврата: ничего.
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
server.ext({
type: 'onRequest',
method: function (request, h) {
// Change all requests to '/test'
request.setUrl('/test');
return h.continue;
}
});
server.route({ method: 'GET', path: '/test', handler: () => 'ok' });
await server.start();
// All requests will get routed to '/test'
}
server.ext(event, [method, [options]])
Регистрирует одно событие расширения с использованием тех же свойств, что и в server.ext(events), но передаваемых в качестве аргументов.
Свойство method может быть опущено (если options отсутствует) или передано null, что заставит функцию вернуть промис. Промис разрешается с объектом request при первом вызове точки расширения. Это используется в основном для написания тестов без необходимости писать пользовательские обработчики только для обработки одного события.
Значение возврата: промис, если method опущено, в противном случае undefined.
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
server.ext('onRequest', function (request, h) {
// Change all requests to '/test'
request.setUrl('/test');
return h.continue;
});
server.route({ method: 'GET', path: '/test', handler: () => 'ok' });
await server.start();
// All requests will get routed to '/test'
}
await server.initialize()
Инициализирует сервер (запускает кэши, завершает регистрацию плагинов), но не начинает прослушивание на порту соединения.
Значение возврата: ничего.
Обратите внимание, что если метод завершается с ошибкой и генерирует ошибку, сервер считается в неопределённом состоянии и должен быть остановлен. В большинстве случаев полное восстановление невозможно, так как различные плагины, кэши и другие слушатели событий могут быть сбиты с толку многократными попытками запуска сервера или делать предположения о стабильном состоянии среды. Рекомендуется прервать процесс, если сервер не может запуститься должным образом. Если необходимо попытаться продолжить после ошибки, сначала вызовите server.stop() для сброса состояния сервера.
const Hapi = require('@hapi/hapi');
const Hoek = require('@hapi/hoek');
async function example() {
const server = Hapi.server({ port: 80 });
await server.initialize();
}
await server.inject(options)
Вводит запрос на сервер, моделируя входящий HTTP-запрос без реального подключения сокета. Ввод полезен для целей тестирования, а также для вызова логики маршрутизации внутри без избыточности и ограничений стека сети.
Метод использует модуль shot для выполнения ввода с некоторыми дополнительными параметрами и свойствами ответа:
-
options- может быть присвоен строка с запрошенным URI или объект со следующими полями:-
method- (необязательно) HTTP-метод запроса (например,'POST'). По умолчанию'GET'. -
url- (обязательно) URL запроса. Если URI включает авторизацию (например,'example.com:8080'), она используется для автоматической установки заголовка HTTP 'Host', если он не был указан вheaders. -
authority- (необязательно) строка, определяющая значение заголовка HTTP 'Host'. Используется только в том случае, если 'Host' не указан вheadersиurlне содержит компонента авторизации. Значение по умолчанию определяется по информации сервера во время выполнения. -
headers- (необязательно) объект с необязательными заголовками запроса, где каждый ключ - имя заголовка, а значение - содержимое заголовка. По умолчанию дополнений к стандартным заголовкам shot нет. -
payload- (необязательно) строка, буфер или объект, содержащий содержимое запроса. В случае объекта он будет преобразован в строку. По умолчанию содержимое отсутствует. Обратите внимание, что обработка содержимого по умолчанию установлена в'application/json', если заголовок 'Content-Type' не предоставлен. -
auth- (необязательно) объект, содержащий обработанные учетные данные аутентификации, где:-
strategy- (обязательно) имя стратегии аутентификации, соответствующее предоставленным учетным данным. -
credentials- (обязательно) объект учетных данных, содержащий информацию об аутентификации.credentialsиспользуются для обхода стандартных стратегий аутентификации и проверяются напрямую, как если бы они были получены через схему аутентификации. -
artifacts- (необязательно) объект артефактов, содержащий информацию об артефактах аутентификации.artifactsиспользуются для обхода стандартных стратегий аутентификации и проверяются напрямую, как если бы они были получены через схему аутентификации. По умолчанию артефакты отсутствуют. -
payload- (необязательно) отключает аутентификацию содержимого при установке в false. Необходимо только тогда, когда стратегия аутентификации требует аутентификации содержимого. По умолчаниюtrue.
-
-
app- (необязательно) задаёт начальное значениеrequest.app, по умолчанию{}. -
plugins- (необязательно) задаёт начальное значениеrequest.plugins, по умолчанию{}. -
allowInternals- (необязательно) позволяет доступ к маршрутам сoptions.isInternalустановленным вtrue. По умолчаниюfalse. -
remoteAddress- (необязательно) устанавливает удалённый адрес для входящего соединения. -
simulate- (необязательно) объект с параметрами, используемыми для моделирования условий потока клиентских запросов для тестирования:-
error- еслиtrue, генерирует событие'error'после передачи содержимого (если таковое есть). По умолчаниюfalse. -
close- еслиtrue, генерирует событие'close'после передачи содержимого (если таковое есть). По умолчаниюfalse. -
end- еслиfalse, не завершает поток. По умолчаниюtrue. -
split- указывает, будет ли содержимое запроса разбиваться на части. По умолчаниюundefined, т.е. содержимое не разбивается на части.
-
-
validate- (необязательно) еслиfalse,optionsвводы не валидируются. Это рекомендуется для использованияinject()во время выполнения, чтобы сделать его быстрее, так как проверка ввода может быть проверена отдельно.
-
Значение возврата: объект ответа со следующими свойствами:
-
statusCode- код HTTP-статуса. -
headers- объект, содержащий установленные заголовки. -
payload- строка содержимого ответа. -
rawPayload- буфер исходного содержимого ответа. -
raw- объект с объектами запроса и ответа ввода:-
req- симулированный объект запроса node. -
res- симулированный объект ответа node.
-
-
result- исходный ответ обработчика (например, когда это не поток или представление) перед сериализацией для передачи. Если недоступен, значение устанавливается вpayload. Полезно для проверки и повторного использования возвращаемых внутренних объектов (вместо анализа строки ответа). -
request- объект запроса.
Выбрасывает ошибку Boom, если обработка запроса завершается с ошибкой. Частичный объект ответа доступен в свойстве data.
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
server.route({ method: 'GET', path: '/', handler: () => 'Success!' });
const res = await server.inject('/');
console.log(res.result); // 'Success!'
}
server.log(tags, [data, [timestamp]])
Регистрирует события сервера, которые нельзя связать с конкретным запросом. При вызове сервер генерирует событие 'log', которое может использоваться другими слушателями или плагинами
-
tags- (обязательно) строка или массив строк (например,['error', 'database', 'read']) для идентификации события. Теги используются вместо уровней регистрации и предоставляют гораздо более выразительный механизм для описания и фильтрации событий. Любые логи, генерируемые сервером внутри, включают тег'hapi'вместе со специфической для события информацией. -
data- (необязательно) строка сообщения или объект с данными приложения, которые регистрируются. Еслиdataфункция, её сигнатураfunction(), и она вызывается один раз для генерации (значения возврата) фактических данных, передаваемых слушателям. Если нет слушателей, соответствующих событию, функцияdataне вызывается. -
timestamp- (необязательно) временная метка в миллисекундах. По умолчаниюDate.now()(текущее время).
Значение возврата: ничего.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
server.events.on('log', (event, tags) => {
if (tags.error) {
console.log(event);
}
});
server.log(['test', 'error'], 'Test event');
server.lookup(id)
Ищет конфигурацию маршрута, где:
Значение возврата: информация о маршруте в запросе, если найдена, в противном случае null.
const Hapi = require('@hapi/hapi');
const server = Hapi.server();
server.route({
method: 'GET',
path: '/',
options: {
id: 'root',
handler: () => 'ok'
}
});
const route = server.lookup('root');
server.match(method, path, [host])
Ищет конфигурацию маршрута, где:
-
method- метод HTTP (например, 'GET', 'POST'). -
path- запрашиваемый путь (должен начинаться с '/'). -
host- (необязательно) имя хоста (для сопоставления с маршрутами сvhost).
Возвращаемое значение: информация о маршруте, если найден, в противном случае null.
const Hapi = require('@hapi/hapi');
const server = Hapi.server();
server.route({
method: 'GET',
path: '/',
options: {
id: 'root',
handler: () => 'ok'
}
});
const route = server.match('get', '/');
server.method(name, method, [options])
Регистрирует метод сервера, где:
-
name- уникальное имя метода, используемое для вызова метода черезserver.methods[name]. -
method- функция метода со структуройasync function(...args, [flags]), где:-
...args- аргументы функции метода (может быть любое количество аргументов или ни одного). -
flags- при включенном кэшировании, объект, используемый для установки необязательных флагов результата метода. Этот параметр предоставляется автоматически и может быть доступен/изменён только внутри функции метода. Его нельзя передавать в качестве аргумента.-
ttl-0если результат действителен, но не может быть кэширован. По умолчанию используется политика кэширования.
-
-
-
options- (необязательно) объект конфигурации:-
bind- объект контекста, передаваемый обратно функции метода (черезthis) при вызове. По умолчанию используется активный контекст (устанавливается черезserver.bind()при регистрации метода). Игнорируется, если метод является стрелочной функцией. -
cache- та же конфигурация кэширования, что и вserver.cache(). ОпцияgenerateTimeoutобязательна, и опцияgenerateFuncзапрещена. -
generateKey- функция, используемая для генерации уникального ключа (для кэширования) из аргументов, переданных в функцию метода (аргументflagsне передаётся как вход). Сервер автоматически сгенерирует уникальный ключ, если все аргументы функции являются типов'string','number', или'boolean'. Однако, если метод использует другие типы аргументов, необходимо предоставить функцию генерации ключа, которая принимает те же аргументы, что и функция, и возвращает уникальную строку (илиnullесли ключ сгенерировать нельзя).
-
Возвращаемое значение: ничего.
Имена методов могут быть вложенными (например, utils.users.get), что автоматически создаст полный путь в server.methods (например, доступ к которому осуществляется через server.methods.utils.users.get).
При конфигурации с включенным кэшированием server.methods[name].cache назначается объект со следующими свойствами и методами: - await drop(...args) - функция, которая может быть использована для очистки кэша для данного ключа. - stats - объект со статистикой кэша, см. catbox для документации по статистике.
Пример с простыми аргументами:
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
const add = (a, b) => (a + b);
server.method('sum', add, { cache: { expiresIn: 2000, generateTimeout: 100 } });
console.log(await server.methods.sum(4, 5)); // 9
}Пример с аргументом-объектом:
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
const addArray = function (array) {
let sum = 0;
array.forEach((item) => {
sum += item;
});
return sum;
};
const options = {
cache: { expiresIn: 2000, generateTimeout: 100 },
generateKey: (array) => array.join(',')
};
server.method('sumObj', addArray, options);
console.log(await server.methods.sumObj([5, 6])); // 11
}
server.method(methods)
Регистрирует функцию метода сервера, как описано в server.method(), используя объект конфигурации, где:
-
methods- объект или массив объектов, где каждый содержит:-
name- имя метода. -
method- функция метода. -
options- (необязательно) настройки.
-
Возвращаемое значение: ничего.
const add = function (a, b) {
return a + b;
};
server.method({
name: 'sum',
method: add,
options: {
cache: {
expiresIn: 2000,
generateTimeout: 100
}
}
});
server.path(relativeTo)
Устанавливает префикс пути, используемый для поиска статических ресурсов (файлов и шаблонов представления) при использовании относительных путей, где:
-
relativeTo- префикс пути, добавляемый к любому относительному пути к файлу, начинающемуся с'.'.
Возвращаемое значение: ничего.
Обратите внимание, что установка пути в плагине применяется только к ресурсам, к которым обращаются методы плагина. Если путь не задан, используется значение по умолчанию сервера конфигурация маршрутов files.relativeTo настроек. Путь применяется только к маршрутам, добавленным после его установки.
exports.plugin = {
name: 'example',
register: function (server, options) {
// Assuming the Inert plugin was registered previously
server.path(__dirname + '../static');
server.route({ path: '/file', method: 'GET', handler: { file: './test.html' } });
}
};
await server.register(plugins, [options])
Регистрирует плагин, где:
-
plugins- один или массив: -
options- (необязательно) параметры регистрации (отличаются от параметров, переданных функции регистрации):-
once- еслиtrue, последующие регистрации того же плагина пропускаются без ошибки. Не может быть использовано с опциями плагина. По умолчаниюfalse. Если не установлено значениеtrue, при повторной регистрации плагина на сервере будет выброшено исключение. -
routes- модификаторы, применяемые к каждому маршруту, добавленному плагином:-
prefix- строка, добавленная в качестве префикса к любому пути маршрута (должна начинаться с'/'). Если плагин регистрирует дочерний плагин,prefixпередаётся дочернему плагину или добавляется перед префиксом, специфичным для дочернего плагина. -
vhost- строка виртуального хоста (или массив строк), применяемая к каждому маршруту. Внешнийvhostпереопределяет все вложенные настройки.
-
-
Возвращаемое значение: ссылка на server.
async function example() {
await server.register({ plugin: require('plugin_name'), options: { message: 'hello' } });
}
server.route(route)
Добавляет маршрут, где:
-
route- объект конфигурации маршрута или массив объектов конфигурации, где каждый объект содержит:-
path- (обязательно) абсолютный путь, используемый для сопоставления входящих запросов (должен начинаться с '/'). Входящие запросы сравниваются с настроенными путями на основе конфигурации сервераrouter. Путь может включать именованные параметры, заключенные в{}, которые будут сопоставлены с литеральными значениями в запросе, как описано в Параметрах пути. -
method- (обязательно) метод HTTP. Обычно один из 'GET', 'POST', 'PUT', 'PATCH', 'DELETE' или 'OPTIONS'. Разрешены все методы HTTP, кроме 'HEAD'. Используйте'*'для сопоставления с любым методом HTTP (только когда точное совпадение не найдено, и любое совпадение с конкретным методом будет иметь более высокий приоритет по сравнению с сопоставлением по шаблону). Может быть назначен массив методов, что имеет тот же результат, что и добавление одного и того же маршрута с разными методами вручную. -
vhost- (необязательно) строка домена или массив строк домена для ограничения маршрута только запросами с соответствующим заголовком хоста. Сопоставление выполняется только с частью имени хоста заголовка (исключая порт). По умолчанию все хосты. -
handler- (обязательно, еслиhandlerне задано) функция обработчика маршрута, вызываемая для генерации ответа после успешной проверки подлинности и валидации. -
options- дополнительные параметры маршрута. Значениеoptionsможет быть объектом или функцией, возвращающей объект с сигнатуройfunction(server), гдеserver— сервер, к которому добавляется маршрут, иthisпривязана к текущему области параметруbind. -
rules- объект пользовательских правил маршрута. Объект передаётся каждому процессору правил, зарегистрированному с помощьюserver.rules(). Не может быть использовано, еслиroute.options.rulesопределён.
-
Возвращаемое значение: ничего.
Обратите внимание, что объект options глубоко клонируется (за исключением bind, который копируется поверхностно) и не может содержать никаких значений, небезопасных для глубокого копирования.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
// Handler in top level
server.route({ method: 'GET', path: '/status', handler: () => 'ok' });
// Handler in config
const user = {
cache: { expiresIn: 5000 },
handler: function (request, h) {
return { name: 'John' };
}
};
server.route({ method: 'GET', path: '/user', options: user });
// An array of routes
server.route([
{ method: 'GET', path: '/1', handler: function (request, h) { return 'ok'; } },
{ method: 'GET', path: '/2', handler: function (request, h) { return 'ok'; } }
]);Параметры пути
Параметризованные пути обрабатываются путём сопоставления именованных параметров с содержимым пути входящего запроса в этом сегменте пути. Например, '/book/{id}/cover' будет соответствовать '/book/123/cover', и request.params.id будет установлено на значение '123'. Каждый сегмент пути (всё между открывающим '/' и закрывающим '/' сегментом, за исключением конца пути) может содержать только один именованный параметр. Параметр может охватывать весь сегмент ('/{param}') или часть сегмента (%%%CODE_BLOCK_986%%). Имя параметра может содержать только буквы, цифры и символы нижнего подчёркивания, например, '/{file-name}' недопустимо, а '/{file_name}' — допустимо.
Необязательный суффикс '?' после имени параметра указывает на необязательный параметр (разрешено только если параметр находится в конце пути или охватывает только часть сегмента, как в '/a{param?}/b'). Например, маршрут '/book/{id?}' соответствует '/book/', а значение request.params.id установлено на пустую строку ''.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
const getAlbum = function (request, h) {
return 'You asked for ' +
(request.params.song ? request.params.song + ' from ' : '') +
request.params.album;
};
server.route({
path: '/{album}/{song?}',
method: 'GET',
handler: getAlbum
});В дополнение к необязательному суффиксу ?, имя параметра также может указывать количество совпадающих сегментов, используя суффикс *, за которым следует число, большее 1. Если число ожидаемых частей может быть любым, то используйте * без числа (сопоставление с любым количеством сегментов может быть использовано только в последнем сегменте пути).
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
const getPerson = function (request, h) {
const nameParts = request.params.name.split('/');
return { first: nameParts[0], last: nameParts[1] };
};
server.route({
path: '/person/{name*2}', // Matches '/person/john/doe'
method: 'GET',
handler: getPerson
});Порядок сопоставления путей
Маршрутизатор итерируется по таблице маршрутизации при каждом входящем запросе и выполняет первый (и только первый) соответствующий маршрут. Сопоставление маршрутов выполняется на основе сочетания пути запроса и HTTP-глагола (например, 'GET', 'POST'). Запрос исключается из логики маршрутизации. Запросы сопоставляются в детерминированном порядке, где порядок добавления маршрутов не имеет значения.
Маршруты сопоставляются в зависимости от специфичности маршрута, которая оценивается в каждом сегменте входящего пути запроса. Каждый путь запроса разбивается на сегменты (части, разделённые '/'). Сегменты сравниваются с таблицей маршрутизации один за другим и сопоставляются с самым специфичным путём до тех пор, пока не будет найдено совпадение. Если совпадение не найдено, пробуется следующее совпадение.
При сопоставлении маршрутов литералы строк (без параметров пути) имеют наивысший приоритет, за которыми следуют смешанные параметры ('/a{p}b'), параметры ('/{p}') и затем шаблонные (/{p*}).
Обратите внимание, что смешанные параметры медленнее сравниваются, так как они не могут быть хешированы и требуют итерации по массиву всех регулярных выражений, представляющих различные смешанные параметры в каждом узле таблицы маршрутизации.
Маршрут по умолчанию
Если приложению нужно переопределить стандартный ответ об ошибке «Не найдено» (404), оно может добавить маршрут по умолчанию для определенного метода или всех методов. Только один такой маршрут может быть определён.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
const handler = function (request, h) {
return h.response('The page was not found').code(404);
};
server.route({ method: '*', path: '/{p*}', handler });
server.rules(processor, [options])
Определяет обработчик правил маршрутизации для преобразования объекта правил маршрутизации в конфигурацию маршрута, где:
-
processor- функция с сигнатуройfunction(rules, info), где:-
rules- пользовательский объект, определённый в вашей конфигурации маршрутов для использования его значений. -
info- объект со следующими свойствами:-
method- метод маршрута. -
path- путь маршрута. -
vhost- виртуальный хост маршрута (если он определён).
-
- возвращает объект конфигурации маршрута.
-
-
options- необязательные настройки:-
validate- валидация объекта правил:-
schema- схема joi. -
options- необязательные параметры валидации joi. По умолчанию %%%CODE_BLOCK_1017%%.
-
-
Обратите внимание, что корневой сервер и каждый экземпляр сервера плагина могут зарегистрировать только один обработчик правил. Если маршрут добавляется после настройки правил, он не будет включать конфигурацию правил. Маршруты, добавленные плагинами, применяют правила к правилам каждого родительского домена от корня до домена маршрута. Это означает, что обработчик, определённый плагином, переопределяет конфигурацию, сгенерированную обработчиком корня, если они перекрываются. Аналогично, собственная конфигурация маршрута переопределяет конфигурацию, созданную обработчиками правил.
const validateSchema = {
auth: Joi.string(),
myCustomPre: Joi.array().min(2).items(Joi.string()),
payload: Joi.object()
};
const myPreHelper = (name) => {
return {
method: (request, h) => {
return `hello ${name || 'world'}!`;
},
assign: 'myPreHelper'
};
};
const processor = (rules, info) => {
if (!rules) {
return null;
}
const options = {};
if (rules.auth) {
options.auth = {
strategy: rules.auth,
validate: {
entity: 'user'
}
};
}
if (rules.myCustomPre) {
options.pre = [
myPreHelper(...rules.myCustomPre)
];
}
if (rules.payload) {
options.validate = { payload: Joi.object(rules.payload) };
}
return options;
};
server.rules(processor, {
validate: { schema: validateSchema }
});
server.route({
method: 'GET',
path: '/',
rules: {
auth: 'jwt',
myCustomPre: ['arg1', 'arg2'],
payload: { a: Joi.boolean(), b: Joi.string() }
},
options: {
id: 'my-route'
}
});Запуск сервера
Запускает сервер, прослушивая входящие запросы на указанном порту (если подключение не было настроено с autoListen установленным в false).
Значение возврата: ничего.
Обратите внимание, что если метод завершается ошибкой и выбрасывает исключение, сервер считается в неопределённом состоянии и должен быть остановлен. В большинстве случаев полное восстановление невозможно, поскольку различные плагины, кэши и другие обработчики событий будут сбиты с толку многократными попытками запуска сервера или сделают предположения о здоровом состоянии среды. Рекомендуется прервать процесс, если сервер не может запуститься должным образом. Если вы должны попытаться возобновить работу после ошибки, сначала вызовите server.stop() для сброса состояния сервера.
Если запущенный сервер запускается снова, второй вызов server.start() игнорируется. События не будут генерироваться, и никакие расширения не будут вызываться.
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
await server.start();
console.log('Server started at: ' + server.info.uri);
}Настройка состояния сервера
Управление состоянием HTTP использует файлы cookie клиента для сохранения состояния между несколькими запросами. Регистрирует определения файлов cookie, где:
-
name- строка имени файла cookie. -
options- необязательные параметры файлов cookie:-
ttl- время жизни в миллисекундах. По умолчаниюnull(время жизни сессии — файлы cookie удаляются при закрытии браузера). -
isSecure- устанавливает флаг «Secure». По умолчаниюtrue. -
isHttpOnly- устанавливает флаг «HttpOnly». По умолчаниюtrue. -
isSameSite- устанавливает флаг 'SameSite'. Значение должно быть одним из:-
false- нет флага. -
'Strict'- устанавливает значение в'Strict'(это значение по умолчанию). -
'Lax'- устанавливает значение в'Lax'. -
'None'- устанавливает значение в'None'.
-
-
path- область действия пути. По умолчаниюnull(без пути). -
domain- область действия домена. По умолчаниюnull(без домена). -
autoValue- если присутствует и файл cookie не получен от клиента или не установлен обработчиком маршрута, файл cookie автоматически добавляется в ответ со значениями. Значение может быть функцией с сигнатуройasync function(request), где:-
request- объект запроса.
-
-
encoding- кодирование выполняется над предоставленным значением перед сериализацией. Варианты:-
'none'- без кодирования. В этом случае значение файла cookie должно быть строкой. Это значение по умолчанию. -
'base64'- строковое значение закодировано с помощью Base64. -
'base64json'- значение объекта JSON-строкируется, а затем кодируется с помощью Base64. -
'form'- значение объекта закодировано с помощью метода x-www-form-urlencoded. -
'iron'- шифрует и подписывает значение с помощью iron.
-
-
sign- объект, используемый для вычисления HMAC для проверки целостности файлов cookie. Это не обеспечивает конфиденциальность, а только средство проверки того, что значение файла cookie было сгенерировано сервером. Избыточно при использовании кодирования'iron'. Варианты:-
integrity- параметры алгоритма. По умолчаниюrequire('iron').defaults.integrity. -
password- пароль, используемый для генерации ключа HMAC (должен быть длиной не менее 32 символов).
-
-
password- пароль, используемый для кодирования'iron'(должен быть длиной не менее 32 символов). -
iron- параметры кодирования'iron'. По умолчаниюrequire('iron').defaults. -
ignoreErrors- еслиtrue, ошибки игнорируются и обрабатываются как отсутствующие файлы cookie. -
clearInvalid- еслиtrue, автоматически указывает клиенту на удаление некорректных файлов cookie. По умолчаниюfalse. -
strictHeader- еслиfalse, разрешает любое значение файла cookie, включая значения, нарушающие RFC 6265. По умолчаниюtrue. -
passThrough- используется плагинами прокси (например, h2o2). -
contextualize- функция с сигнатуройasync function(definition, request), используемая для переопределения параметров файлов cookie, специфичных для запроса, где:-
definition- копияoptionsдля форматирования файла cookie, которую функция может изменить для настройки заголовка файла cookie запроса. Обратите внимание, что изменение свойстваdefinition.contextualizeбудет проигнорировано. -
request- текущий объект запроса.
-
-
Значение возврата: ничего.
Значения по умолчанию для состояния можно изменить с помощью параметра конфигурации server.options.state.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
// Set cookie definition
server.state('session', {
ttl: 24 * 60 * 60 * 1000, // One day
isSecure: true,
path: '/',
encoding: 'base64json'
});
// Set state in route handler
const handler = function (request, h) {
let session = request.state.session;
if (!session) {
session = { user: 'joe' };
}
session.last = Date.now();
return h.response('Success').state('session', session);
};Зарегистрированные файлы cookie автоматически анализируются при получении. Правила анализа зависят от конфигурации маршрута state.parse. Если анализ входящего зарегистрированного файла cookie завершается ошибкой, он не включается в request.state, независимо от параметра state.failAction. Когда state.failAction установлен на 'log', а значение некорректного файла cookie получено, сервер выпустит событие 'request'. Чтобы перехватить эти ошибки, подпишитесь на событие 'request' на канале 'internal' и отфильтруйте по тегам 'error' и 'state':
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
server.events.on({ name: 'request', channels: 'internal' }, (request, event, tags) => {
if (tags.error && tags.state) {
console.error(event);
}
});
server.states.add(name, [options])
Доступ: только для чтения.
То же самое, что и вызов server.state().
Форматирование файлов cookie
Форматирует заголовок HTTP 'Set-Cookie' на основе server.options.state, где:
-
cookies- один объект или массив объектов, каждый из которых содержит:-
name- имя файла cookie. -
value- значение файла cookie. -
options- конфигурация файла cookie для переопределения настроек сервера.
-
Значение возврата: строка заголовка.
Обратите внимание, что эта утилита использует конфигурацию сервера, но не изменяет состояние сервера. Она предназначена для ручного форматирования файлов cookie (например, при ручном задании заголовков).
Анализ заголовка
Анализирует заголовок HTTP 'Cookies' на основе server.options.state, где:
-
header- заголовок HTTP.
Значение возврата: объект, где каждый ключ — имя файла cookie, а значение — проанализированный файл cookie.
Обратите внимание, что эта утилита использует конфигурацию сервера, но не изменяет состояние сервера. Она предназначена для ручного анализа файлов cookie (например, при отключении анализа сервером).
Остановка сервера
Останавливает прослушиватель сервера, отказываясь принимать новые подключения или запросы (существующие подключения будут продолжены до закрытия или истечения времени ожидания), где:
-
options- (необязательно) объект с:-
timeout- устанавливает время ожидания в миллисекундах до принудительного завершения любых открытых подключений, появившихся до остановки сервера на приём новых подключений. Время ожидания применяется только к ожиданию закрытия существующих подключений, а не к любым расширениям сервера'onPreStop'или'onPostStop', которые могут задерживать или блокировать операцию остановки неопределённо. Игнорируется, еслиserver.options.operations.cleanStop—false. Обратите внимание, что если сервер настроен как контроллер группы группы, время ожидания относится к каждому контролируемому серверу и самому контролирующему серверу. По умолчанию5000(5 секунд).
-
Значение возврата: ничего.
const Hapi = require('@hapi/hapi');
async function example() {
const server = Hapi.server({ port: 80 });
await server.start();
await server.stop({ timeout: 60 * 1000 });
console.log('Server stopped');
}Таблица маршрутизации
Возвращает копию таблицы маршрутизации, где:
-
host- (необязательно) хост для фильтрации маршрутов, соответствующих определённому виртуальному хосту. По умолчанию все виртуальные хосты.
Значение возврата: массив маршрутов, где каждый маршрут содержит:
-
settings- конфигурация маршрута с применёнными значениями по умолчанию. -
method- метод HTTP в нижнем регистре. -
path- путь маршрута.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
server.route({ method: 'GET', path: '/example', handler: () => 'ok' });
const table = server.table();
server.validator(validator)
Регистрирует модуль валидации сервера, используемый для компиляции исходных правил валидации в схемы валидации для всех маршрутов, где:
-
validator— модуль валидации (например, joi).
Возвращаемое значение: ничего.
Примечание: валидатор используется только тогда, когда правила валидации не являются предварительно скомпилированными схемами. Когда правило валидации является функцией или объектом схемы, правило используется как есть, и валидатор не используется. При установке валидатора внутри плагина, валидатор применяется только к маршрутам, настроенным этим плагином, и плагинам, зарегистрированным им.
const Hapi = require('@hapi/hapi');
const Joi = require('joi');
async function example() {
const server = Hapi.server({ port: 80 });
server.validator(Joi);
}Параметры маршрута
Каждый маршрут можно настроить для изменения стандартного поведения жизненного цикла запроса.
route.options.app
Состояние конфигурации маршрута, специфичное для приложения. Не должно использоваться плагинами, которые должны использовать options.plugins[name] вместо этого.
route.options.auth
Конфигурация аутентификации маршрута. Значение может быть:
-
falseдля отключения аутентификации, если установлена стратегия по умолчанию. -
строка с именем стратегии аутентификации, зарегистрированной с помощью
server.auth.strategy(). Стратегия будет установлена в режим'required'. -
объект конфигурации аутентификации.
route.options.auth.access
Значение по умолчанию: ничего.
Объект или массив объектов, определяющих правила доступа к маршруту. Каждое правило оценивается относительно входящего запроса, и доступ предоставляется, если хотя бы одно из правил соответствует. Каждый объект правила должен включать как минимум одно из scope или entity.
route.options.auth.access.scope
Значение по умолчанию: false (нет требований к области).
Требуемая область приложения для доступа к маршруту. Значение может быть строкой области или массивом строк областей. При аутентификации объект учетных данных scope должен содержать как минимум одну из определенных для доступа к маршруту областей.
Если строка области начинается с символа +, эта область обязательна. Если строка области начинается с символа !, эта область запрещена. Например, область ['!a', '+b', 'c', 'd'] означает, что учетные данные входящего запроса scope не должны содержать 'a', должны содержать 'b' и должны содержать одну из 'c' или 'd'.
Вы также можете получить доступ к свойствам объекта запроса (query, params, payload, и credentials) для заполнения динамической области, используя символы '{' и '}' вокруг имени свойства, например 'user-{params.id}'.
route.options.auth.access.entity
Значение по умолчанию: 'any'.
Требуемый тип аутентифицированного сущности. Если установлено, должно соответствовать значению entity аутентифицированных учетных данных запроса. Доступные значения:
-
'any'— аутентификация может быть от имени пользователя или приложения. -
'user'— аутентификация должна быть от имени пользователя, который идентифицируется по наличию атрибута'user'в объектеcredentials, возвращенном стратегией аутентификации. -
'app'— аутентификация должна быть от имени приложения, которое идентифицируется по отсутствию атрибутаuserв объектеcredentials, возвращенном стратегией аутентификации.
route.options.auth.mode
Значение по умолчанию: 'required'.
Режим аутентификации. Доступные значения:
-
'required'— аутентификация обязательна. -
'optional'— аутентификация необязательна — запрос должен содержать действительные учетные данные или вообще не содержать учетных данных. -
'try'— аналогично'optional', любые учетные данные запроса пытаются пройти аутентификацию, но если учетные данные недействительны, запрос продолжает выполняться независимо от ошибки аутентификации.
route.options.auth.payload
Значение по умолчанию: false, если схема не требует аутентификации содержимого.
Если установлено, содержимое входящего запроса аутентифицируется после обработки. Требуется стратегия с поддержкой аутентификации содержимого (например, Hawk). Не может быть установлено в значение, отличное от 'required', если схема устанавливает режим аутентификации options.payload в true.
Доступные значения:
-
false— аутентификация содержимого отсутствует. -
'required'— аутентификация содержимого требуется. -
'optional'— аутентификация содержимого выполняется только когда клиент предоставляет информацию об аутентификации содержимого (например, атрибутhashв Hawk).
route.options.auth.strategies
Значение по умолчанию: стратегия по умолчанию, установленная с помощью server.auth.default().
Массив имён стратегий, в порядке, в котором они должны быть проверены. Не может использоваться вместе с strategy.
route.options.auth.strategy
Значение по умолчанию: стратегия по умолчанию, установленная с помощью server.auth.default().
Имя стратегии. Не может использоваться вместе с strategies.
route.options.bind
Значение по умолчанию: null.
Объект, возвращаемый предоставленной handler (через this) при вызове. Игнорируется, если метод является стрелочной функцией.
route.options.cache
Значение по умолчанию: { privacy: 'default', statuses: [200], otherwise: 'no-cache' }.
Если метод маршрута 'GET', маршрут можно настроить для включения директив кэширования HTTP в ответе. Кэширование можно настроить с помощью объекта со следующими параметрами:
-
privacy— определяет флаг приватности, включенный в кэширование на стороне клиента с помощью заголовка 'Cache-Control'. Значения:-
'default'— нет флага приватности. -
'public'— отметить ответ как подходящий для публичного кэширования. -
'private'— отметить ответ как подходящий только для приватного кэширования.
-
-
expiresIn— относительное время истечения срока действия, выраженное в миллисекундах с момента сохранения элемента в кэше. Не может использоваться вместе сexpiresAt. -
expiresAt— время суток в формате 'HH:MM' 24-часового формата, к которому все записи кэша для маршрута истекают. Не может использоваться вместе сexpiresIn. -
statuses— массив номеров кодов HTTP-статусов (например,200), которые разрешается включать в действительную директиву кэширования. -
otherwise— строка со значением заголовка 'Cache-Control' при отключенном кэшировании.
Заголовок по умолчанию Cache-Control: no-cache может быть отключен, установив cache в false.
route.options.compression
Объект, где каждый ключ — имя кодировки содержимого, а каждое значение — объект с желаемыми настройками кодировщика. Обратите внимание, что настройки декодера устанавливаются в compression.
route.options.cors
Значение по умолчанию: false (нет заголовков CORS).
Протокол Cross-Origin Resource Sharing позволяет браузерам выполнять кросс-доменные вызовы API. CORS требуется веб-приложениям, работающим внутри браузера, которые загружаются с другого домена, чем сервер API. Чтобы включить, установите cors в true, или в объект со следующими параметрами:
-
origin— массив строк разрешенных серверов источников ('Access-Control-Allow-Origin'). Массив может содержать любое сочетание полных квалифицированных источников наряду со строками источников, содержащими символ подстановки'*', или единственную строку источника'*'. Если установлено в'ignore', любой входящий заголовок Origin игнорируется (есть или нет) и заголовок 'Access-Control-Allow-Origin' устанавливается в'*'. По умолчанию — любой источник['*']. -
maxAge— количество секунд, в течение которых браузер должен кэшировать ответ CORS ('Access-Control-Max-Age'). Чем больше значение, тем дольше потребуется браузеру для проверки изменений в политике. По умолчанию86400(один день). -
headers— массив строк разрешенных заголовков ('Access-Control-Allow-Headers'). По умолчанию['Accept', 'Authorization', 'Content-Type', 'If-None-Match']. -
additionalHeaders— массив дополнительных заголовков дляheaders. Используйте это для сохранения стандартных заголовков. -
exposedHeaders— массив строк выставляемых заголовков ('Access-Control-Expose-Headers'). По умолчанию['WWW-Authenticate', 'Server-Authorization']. -
additionalExposedHeaders— массив дополнительных заголовков дляexposedHeaders. Используйте это для сохранения стандартных заголовков. -
credentials— еслиtrue, разрешает отправку учетных данных пользователя ('Access-Control-Allow-Credentials'). По умолчаниюfalse. -
preflightStatusCode— код состояния, используемый для ответов CORS на предварительные запросы, либо200или204. По умолчанию200.
route.options.description
Значение по умолчанию: ничего.
Описание маршрута, используемое для генерации документации (строка).
Этот параметр недоступен при установке параметров сервера маршрутов с помощью server.options.routes.
route.options.ext
Значение по умолчанию: ничего.
Точки расширения запроса уровня маршрута, установив параметр в объект с ключом для каждой из желаемых точек расширения ('onRequest' не разрешается), и значение такое же, как аргумент server.ext(events) event.
route.options.files
Значение по умолчанию: { relativeTo: '.' }.
Определяет поведение доступа к файлам:
-
relativeTo— определяет, относительно каких каталогов будут разрешаться пути.
route.options.handler
Значение по умолчанию: ничего.
Функция обработчика маршрута выполняет основную бизнес-логику маршрута и устанавливает ответ. handler может быть назначено:
-
методом жизненного цикла.
-
объектом с единственным свойством, используя имя типа обработчика, зарегистрированного с помощью метода
server.decorate(). Соответствующее значение свойства передается как параметры зарегистрированному генератору обработчика.
const handler = function (request, h) {
return 'success';
};Примечание: обработчики, использующие стрелочную функцию со стилем «толстая стрелка», не могут быть привязаны к свойству bind. Вместо этого привязанный контекст доступен по адресу h.context.
route.options.id
Значение по умолчанию: none.
Необязательный уникальный идентификатор, используемый для поиска маршрута с помощью server.lookup(). Не может быть назначен маршрутам, добавленным с массивом методов.
route.options.isInternal
Значение по умолчанию: false.
Если true, доступ к маршруту нельзя получить через HTTP-прослушиватель, только через интерфейс server.inject() с параметром allowInternals установленным в true. Используется для внутренних маршрутов, которые не должны быть доступны внешнему миру.
route.options.json
Значение по умолчанию: none.
Необязательные аргументы, передаваемые в JSON.stringify(), при преобразовании объекта или ответа об ошибке в строковый полезный груз или экранировании его после строкового представления. Поддерживает следующие:
-
replacer— функция или массив замены. По умолчанию без действий. -
space— количество пробелов для отступа ключей вложенных объектов. По умолчанию без отступа. -
suffix— строковый суффикс, добавляемый после преобразования в строку JSON. По умолчанию без суффикса. -
escape— вызываетHoek.jsonEscape()после преобразования в строку JSON. По умолчаниюfalse.
route.options.log
Значение по умолчанию: { collect: false }.
Параметры ведения журнала запросов:
-
collect— еслиtrue, журналы уровня запроса (как внутренние, так и приложения) собираются и доступны черезrequest.logs.
route.options.notes
Значение по умолчанию: none.
Примечания к маршруту, используемые для генерации документации (строка или массив строк).
Этот параметр недоступен при установке параметров маршрута сервера с помощью server.options.routes.
route.options.payload
Определяет, как обрабатывается полезная нагрузка запроса.
route.options.payload.allow
Значение по умолчанию: разрешает парсинг следующих типов MIME:
- application/json
- application/*+json
- application/octet-stream
- application/x-www-form-urlencoded
- multipart/form-data
- text/*
Строка или массив строк с разрешенными типами MIME для конечной точки. Используйте этот параметр для ограничения набора разрешенных типов MIME. Обратите внимание, что разрешение дополнительных типов MIME, не перечисленных выше, не позволит их парсить, и если parse true, запрос приведет к ответу об ошибке.
route.options.payload.compression
Значение по умолчанию: none.
Объект, где каждый ключ — имя кодирования содержимого, а каждое значение — объект с желаемыми настройками декодера. Обратите внимание, что настройки кодировщика устанавливаются в compression.
route.options.payload.defaultContentType
Значение по умолчанию: 'application/json'.
Тип содержимого по умолчанию, если заголовок 'Content-Type' запроса отсутствует.
route.options.payload.failAction
Значение по умолчанию: 'error' (возвращает ошибку Bad Request (400)).
Значение failAction, определяющее, как обрабатывать ошибки при разборе полезной нагрузки.
route.options.payload.maxBytes
Значение по умолчанию: 1048576 (1 МБ).
Ограничивает размер входящей полезной нагрузки заданным количеством байтов. Разрешение очень больших полезных нагрузок может привести к нехватке памяти на сервере.
route.options.payload.maxParts
Значение по умолчанию: 1000.
Ограничивает количество частей, разрешенных в полезной нагрузке типа multipart.
route.options.payload.multipart
Значение по умолчанию: false.
Переопределяет обработку полезной нагрузки для запросов multipart. Значение может быть одним из:
-
false— отключение обработки multipart (это значение по умолчанию). -
true— включение обработки multipart с использованием значенияoutput. -
объект со следующими обязательными параметрами:
-
output— аналогично параметруoutputс дополнительным параметром value:-
annotated— оборачивает каждую часть multipart в объект со следующими ключами:-
headers— заголовки части. -
filename— имя файла части. -
payload— обработанная полезная нагрузка части.
-
-
-
route.options.payload.output
Значение по умолчанию: 'data'.
Формат обработанной полезной нагрузки. Значение должно быть одним из:
-
'data'— входящая полезная нагрузка полностью считывается в память. Еслиparsetrue, полезная нагрузка анализируется (JSON, декодирование формы, multipart) на основе заголовка 'Content-Type'. Еслиparsefalse, возвращается сыройBuffer. -
'stream'— входящая полезная нагрузка доступна через интерфейсStream.Readable. Если полезная нагрузка 'multipart/form-data' иparsetrue, значения полей представлены как текст, а файлы — как потоки. Потоки файлов из загрузки 'multipart/form-data' также будут иметь свойствоhapi, содержащее свойстваfilenameиheaders. Обратите внимание, что потоки полезной нагрузки для multipart-полезных нагрузок — это синтетический интерфейс, созданный поверх всего содержимого multipart, загруженного в память. Чтобы избежать загрузки больших multipart-полезных нагрузок в память, установитеparsefalseи обработайте multipart-полезную нагрузку в обработчике с помощью потокового анализатора (например, pez). -
'file'— входящая полезная нагрузка записывается во временный файл в каталоге, указанном в параметрахuploads. Если полезная нагрузка 'multipart/form-data' иparsetrue, значения полей представлены как текст, а файлы сохраняются на диск. Обратите внимание, что приложение несет полную ответственность за очистку файлов, созданных фреймворком. Это можно сделать, отслеживая используемые файлы (например, используя объектrequest.app) и прослушивая событие сервера'response'для выполнения очистки.
route.options.payload.override
Значение по умолчанию: none.
Строка типа MIME, переопределяющая значение заголовка 'Content-Type', полученного из запроса.
route.options.payload.parse
Значение по умолчанию: true.
Определяет, обрабатывается ли входящая полезная нагрузка или представлена в сыром виде. Доступные значения:
-
true— если тип содержимого запроса 'Content-Type' соответствует разрешенным типам MIME, заданным вallow(для всей полезной нагрузки и частей), полезная нагрузка преобразуется в объект, когда это возможно. Если формат неизвестен, отправляется ответ об ошибке Bad Request (400). Любая известная кодировка содержимого декодируется. -
false— сырая полезная нагрузка возвращается без изменений. -
'gunzip'— сырая полезная нагрузка возвращается без изменений после декодирования любой известной кодировки содержимого.
route.options.payload.protoAction
Значение по умолчанию: 'error'.
Устанавливает обработку входящей полезной нагрузки, которая может содержать атаку с отравлением прототипа. Доступные значения:
-
'error'— возвращает ошибку400bad request, если полезная нагрузка содержит прототип. -
'remove'— очищает полезную нагрузку, удаляя прототип. -
'ignore'— отключает защиту и позволяет полезной нагрузке пройти как полученную. Используйте этот параметр только в том случае, если вы уверены, что такие входящие данные не могут представлять никакой угрозы для вашего приложения.
route.options.payload.timeout
Значение по умолчанию: до 10000 (10 секунд).
Таймаут приема полезной нагрузки в миллисекундах. Устанавливает максимальное время, разрешенное для клиента для передачи полезной нагрузки запроса (тела), прежде чем отказаться и ответить с ошибкой Request Timeout (408).
Установите значение false для отключения.
route.options.payload.uploads
Значение по умолчанию: os.tmpdir().
Каталог, используемый для записи загрузок файлов.
route.options.plugins
Значение по умолчанию: {}.
Настройки, специфичные для плагинов. plugins — это объект, где каждый ключ — имя плагина, а значение — настройка плагина.
route.options.pre
Значение по умолчанию: none.
Параметр pre позволяет определять методы для выполнения действий перед вызовом обработчика. Эти методы позволяют разбить логику обработчика на более мелкие, повторно используемые компоненты, которые можно совместно использовать в разных маршрутах, а также обеспечить более чистую обработку ошибок предварительных операций (например, загрузка необходимых справочных данных из базы данных).
pre назначается упорядоченный массив методов, которые вызываются последовательно в порядке. Если массив pre содержит другой массив методов как один из своих элементов, эти методы вызываются параллельно. Обратите внимание, что во время параллельного выполнения, если любой из методов завершится ошибкой, вернет ответ takeover или сигнал прерывания, другие параллельные методы продолжат выполнение, но будут проигнорированы по завершении.
pre может быть назначен смешанный массив:
-
массив, содержащий элементы, перечисленные ниже, которые выполняются параллельно.
-
объект с:
-
method— метод жизненного цикла. -
assign— имя ключа, используемого для назначения ответа метода вrequest.preиrequest.preResponses. -
failAction— значениеfailAction, определяющее, что делать, когда метод предварительного обработчика вызывает ошибку. Еслиassignуказан и настройкаfailActionне равна'error', ошибка будет назначена.
-
-
функция метода — то же самое, что и включение объекта с единственным ключом
method.
Обратите внимание, что методы предобработчика ведут себя не так, как другие методы жизненного цикла, когда возвращается значение. Вместо того, чтобы возвращаемое значение становилось новым полезным нагрузом ответа, значение используется для назначения соответствующих request.pre и request.preResponses свойств. В остальных случаях обработка ошибок, ответ захвата или сигнал прерывания ведут себя так же, как и другие методы жизненного цикла.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
const pre1 = function (request, h) {
return 'Hello';
};
const pre2 = function (request, h) {
return 'World';
};
const pre3 = function (request, h) {
return request.pre.m1 + ' ' + request.pre.m2;
};
server.route({
method: 'GET',
path: '/',
options: {
pre: [
[
// m1 and m2 executed in parallel
{ method: pre1, assign: 'm1' },
{ method: pre2, assign: 'm2' }
],
{ method: pre3, assign: 'm3' },
],
handler: function (request, h) {
return request.pre.m3 + '!\n';
}
}
});
route.options.response
Правила обработки исходящего ответа.
route.options.response.disconnectStatusCode
Значение по умолчанию: 499.
Код состояния HTTP по умолчанию, используемый для установки ошибки ответа, когда запрос закрыт или прерван до полного передачи ответа. Значение может быть любым целым числом, большим или равным 400. Значение по умолчанию 499 основано на нестандартной ошибке nginx "CLIENT CLOSED REQUEST". Это значение используется только для ведения журнала, так как запрос уже завершен.
route.options.response.emptyStatusCode
Значение по умолчанию: 204.
Код состояния HTTP по умолчанию, когда полезная нагрузка считается пустой. Значение может быть 200 или 204. Обратите внимание, что код состояния 200 преобразуется в 204 только во время передачи ответа (код состояния ответа останется 200 на протяжении всего жизненного цикла запроса, если не задано вручную).
route.options.response.failAction
Значение по умолчанию: 'error' (возвратить ошибку Internal Server Error (500)).
Значение failAction, определяющее, что делать, когда проверка полезной нагрузки ответа завершается с ошибкой.
route.options.response.modify
Значение по умолчанию: false.
Если true, применяет изменения правил проверки к полезной нагрузке ответа.
route.options.response.options
Значение по умолчанию: none.
joi объект опций, передаваемый в функцию валидации. Полезно для установки глобальных параметров, таких как stripUnknown или abortEarly. Если пользовательская функция валидации определена с помощью schema или status, тогда options может быть произвольным объектом, который будет передан в эту функцию в качестве второго аргумента.
route.options.response.ranges
Значение по умолчанию: true.
Если false, поддержка диапазонов полезной нагрузки range отключена.
route.options.response.sample
Значение по умолчанию: 100 (все ответы).
Процент полезных нагрузок ответов, подвергнутых проверке (0 - 100). Установите значение 0 для отключения всей проверки.
route.options.response.schema
Значение по умолчанию: true (без проверки).
Правила проверки полезной нагрузки ответа по умолчанию (для всех ответов, не являющихся ошибками), выраженные как один из:
-
true- любая полезная нагрузка разрешена (без проверки). -
false- полезная нагрузка не разрешена. -
объект валидации joi.
optionsвместе с контекстом запроса ({ headers, params, query, payload, state, app, auth }) передаются в функцию проверки. -
функция проверки с сигнатурой
async function(value, options), где:-
value- ожидаемая полезная нагрузка ответа. -
options-optionsвместе с контекстом запроса ({ headers, params, query, payload, state, app, auth }). -
если функция возвращает значение и
modifyравноtrue, то значение используется как новый ответ. Если исходный ответ является ошибкой, возвращаемое значение используется для переопределения исходной ошибкиoutput.payload. Если возникает ошибка, ошибка обрабатывается в соответствии сfailAction.
-
route.options.response.status
Значение по умолчанию: none.
Схемы валидации для определённых кодов состояния HTTP. Ответы (исключая ошибки), не соответствующие указанным кодам состояния, проверяются с использованием по умолчанию schema.
status устанавливается в объект, где каждый ключ — 3-значный код состояния HTTP, а значение имеет такое же определение, как schema.
route.options.rules
Значение по умолчанию: none.
Пользовательский объект правил, передаваемый каждому обработчику правил, зарегистрированному в server.rules().
route.options.security
Значение по умолчанию: false (заголовки безопасности отключены).
Устанавливает общие заголовки безопасности. Чтобы включить, установите security в true или в объект со следующими параметрами:
-
hsts— управляет заголовком 'Strict-Transport-Security', где:-
true— заголовок будет установлен вmax-age=15768000. Это значение по умолчанию. -
число — параметр maxAge будет установлен в указанное значение.
-
объект со следующими полями:
-
maxAge— часть max-age заголовка, как число. Значение по умолчанию15768000. -
includeSubDomains— логическое значение, указывающее, нужно ли добавить флагincludeSubDomainsв заголовок. -
preload— логическое значение, указывающее, нужно ли добавить флаг'preload'(используется для добавления доменов в предварительно загруженный список HSTS Chrome) в заголовок.
-
-
-
xframe— управляет заголовком 'X-Frame-Options', где:-
true— заголовок будет установлен в'DENY'. Это значение по умолчанию. -
'deny'— заголовки будут установлены в'DENY'. -
'sameorigin'— заголовки будут установлены в'SAMEORIGIN'. -
объект для указания правила 'allow-from', где:
-
rule— одно из:'deny''sameorigin''allow-from'
-
source— когдаruleравно'allow-from', это используется для формирования остальной части заголовка, в противном случае это поле игнорируется. Еслиruleравно'allow-from', ноsourceне задано, правило будет автоматически изменено на'sameorigin'.
-
-
-
xss— управляет заголовком 'X-XSS-Protection', где:-
'disabled'— заголовок будет установлен в'0'. Это значение по умолчанию. -
'enabled'— заголовок будет установлен в'1; mode=block'. -
false— заголовок будет опущен.
Примечание: при включении это значение может создать уязвимости в версиях Internet Explorer ниже 8, неисправленных версиях IE8 и браузерах, использующих фильтр/аудитор XSS. Подробнее см. здесь, здесь и здесь.
-
-
noOpen— логическое значение, управляющее заголовком 'X-Download-Options' для Internet Explorer, предотвращая выполнение загрузок в вашем контексте. По умолчанию устанавливает заголовок в'noopen'. -
noSniff— логическое значение, управляющее заголовком 'X-Content-Type-Options'. По умолчанию устанавливает заголовок в его единственное и значение по умолчанию'nosniff'. -
referrer— управляет заголовком 'Referrer-Policy', который имеет следующие возможные значения.-
false— заголовок 'Referrer-Policy' не будет отправлен клиентам с ответами. Это значение по умолчанию. -
''— сообщает клиентам, что Referrer-Policy будет определён где-то ещё, например, в теге meta HTML. -
'no-referrer'— сообщает клиентам, что заголовок referer никогда не включается при выполнении запросов. -
'no-referrer-when-downgrade'— сообщает клиентам, что заголовок referer никогда не включается при переходе с HTTPS на HTTP. -
'same-origin'— сообщает клиентам, что заголовок referer включается только для текущего сайта. -
'origin'— аналогично'origin', но сообщает клиентам, что заголовок referer пропускается при переходе с HTTPS на HTTP. -
'origin-when-cross-origin'— сообщает клиентам, что полный путь включен в заголовок referer для запросов того же сайта, а компоненты происхождения URL включены для запросов с разных сайтов. -
'strict-origin-when-cross-origin'— аналогично'origin-when-cross-origin', но клиент получает инструкцию пропускать заголовок referer при переходе с HTTPS на HTTP. -
'unsafe-url'— сообщает клиенту всегда включать заголовок referer с полным URL.
-
route.options.state
Значение по умолчанию: { parse: true, failAction: 'error' }.
Управление состоянием HTTP (куки) позволяет серверу хранить информацию на стороне клиента, которая отправляется обратно на сервер с каждым запросом (как определено в RFC 6265). state поддерживает следующие параметры:
-
parse— определяет, будут ли анализироваться заголовки 'Cookie' и храниться в объектеrequest.state. -
failAction— значениеfailAction, определяющее, как обрабатывать ошибки парсинга куки. По умолчанию'error'(возвратить ошибку Bad Request (400)).
route.options.tags
Значение по умолчанию: none.
Теги маршрута, используемые для генерации документации (массив строк).
Это значение недоступно при установке параметров маршрутов сервера с помощью server.options.routes.
route.options.timeout
Значение по умолчанию: { server: false }.
Таймауты для обработки продолжительности.
route.options.timeout.server
Значение по умолчанию: false.
Тайм-аут ответа в миллисекундах. Устанавливает максимальное время, разрешённое для ответа сервера на входящий запрос перед отказом и отправкой ответа с ошибкой Service Unavailable (503).
route.options.timeout.socket
Значение по умолчанию: none (используется узел по умолчанию 2 минуты).
По умолчанию, сокеты узла автоматически отключаются после 2 минут. Используйте этот параметр, чтобы переопределить это поведение. Установите в false для отключения таймаутов сокета.
route.options.validate
Значение по умолчанию: { headers: true, params: true, query: true, payload: true, state: true, failAction: 'error' }.
Правила валидации входных данных запроса для различных компонентов запроса.
route.options.validate.errorFields
Значение по умолчанию: none.
Необязательный объект с полями ошибок, копируемыми в каждый ответ об ошибке валидации.
route.options.validate.failAction
Значение по умолчанию: 'error' (возвращает ошибку Bad Request (400)).
Значение failAction, которое определяет, как обрабатывать ошибки валидации. Если установлено значение функции, аргумент err включает тип ошибки валидации в err.output.payload.validation.source. Доступ к стандартной ошибке, которая в противном случае была бы записана в журнал или возвращена, можно получить в err.data.defaultError.
route.options.validate.headers
Значение по умолчанию: true (без валидации).
Правила валидации для входящих заголовков запроса:
-
true- любые разрешенные заголовки (валидация не выполняется). -
объект валидации joi.
-
функция валидации, использующая подпись
async function(value, options), где:-
value- объектrequest.headers, содержащий заголовки запроса. -
options-options. - если возвращается значение, значение используется в качестве нового значения
request.headers, а исходное значение сохраняется вrequest.orig.headers. В противном случае заголовки остаются неизменными. Если возникает ошибка, ошибка обрабатывается в соответствии сfailAction.
-
Обратите внимание, что все имена полей заголовков должны быть в нижнем регистре для соответствия нормализованным заголовкам, используемым узлом.
route.options.validate.options
Значение по умолчанию: none.
Объект параметров, передаваемый правилам joi или пользовательским методам валидации. Используется для установки глобальных параметров, таких как stripUnknown или abortEarly.
Если определена пользовательская функция валидации (см. headers, params, query, или payload выше), то options может быть произвольным объектом, который будет передан этой функции в качестве второго параметра.
Значения других входных данных (т. е. headers, query, params, payload, state, app, и auth ) добавляются в объект options в разделе валидации %%%CODE_BLOCK_1507%% (доступно в правилах как Joi.ref('$query.key')).
Обратите внимание, что валидация выполняется в порядке (т. е. заголовки, параметры, запросы и данные загрузки), и если используется преобразование типов (например, преобразование строки в число), значение входных данных, которые ещё не прошли валидацию, будет отражать необработанные, невалидированные и неизменённые значения.
Если правила валидации для headers, params, query, и payload определены как на уровне сервера routes, так и на уровне маршрута, индивидуальные настройки маршрута переопределяют настройки по умолчанию маршрутов (правила не объединяются).
route.options.validate.params
Значение по умолчанию: true (без валидации).
Правила валидации для входящих параметров пути запроса после сопоставления пути с маршрутом, извлечения параметров и сохранения их в request.params, где:
-
true- любые значения параметров пути разрешены (валидация не выполняется). -
объект валидации joi.
-
функция валидации, использующая подпись
async function(value, options), где:-
value- объектrequest.params, содержащий параметры пути запроса. -
options-options. - если возвращается значение, значение используется в качестве нового значения
request.params, а исходное значение сохраняется вrequest.orig.params. В противном случае параметры пути остаются неизменными. Если возникает ошибка, ошибка обрабатывается в соответствии сfailAction.
-
Обратите внимание, что отсутствие соответствия правил валидации определению параметров пути маршрута приведёт к отказу всех запросов.
route.options.validate.payload
Значение по умолчанию: true (без валидации).
Правила валидации для входящей загрузки (тела запроса), где:
-
true- любая загрузка разрешена (валидация не выполняется). -
false- любая загрузка запрещена. -
объект валидации joi.
- Обратите внимание, что пустые загрузки представлены значением
null. Если предоставлена схема валидации и разрешены пустые загрузки, схема должна быть явно определена, установив правило в схему joi с разрешенными пустыми значениями (например,null).
- Обратите внимание, что пустые загрузки представлены значением
-
функция валидации, использующая подпись
async function(value, options), где:-
value- объектrequest.payload, содержащий загрузку запроса. -
options-options. - если возвращается значение, значение используется в качестве нового значения
request.payload, а исходное значение сохраняется вrequest.orig.payload. В противном случае загрузка остаётся неизменной. Если возникает ошибка, ошибка обрабатывается в соответствии сfailAction.
-
Обратите внимание, что валидация больших загрузок и их модификация приведут к дублированию памяти загрузки (так как исходная сохраняется), а также к значительным затратам на производительность при валидации больших объёмов данных.
route.options.validate.query
Значение по умолчанию: true (без валидации).
Правила валидации для входящей компоненты URI запроса (ключевое значение части URI между '?' и '#'). Запрос анализируется на отдельные пары ключ-значение, декодируется и сохраняется в request.query перед валидацией. Где:
-
true- любые значения параметров запроса разрешены (валидация не выполняется). -
false- никакие значения параметров запроса не разрешены. -
объект валидации joi.
-
функция валидации, использующая подпись
async function(value, options), где:-
value- объектrequest.query, содержащий параметры запроса. -
options-options. - если возвращается значение, значение используется в качестве нового значения
request.query, а исходное значение сохраняется вrequest.orig.query. В противном случае параметры запроса остаются неизменными. Если возникает ошибка, ошибка обрабатывается в соответствии сfailAction.
-
Обратите внимание, что изменения параметров запроса не будут отражены в request.url.
route.options.validate.state
Значение по умолчанию: true (без валидации).
Правила валидации для входящих куки. Заголовок cookie анализируется и декодируется в request.state перед валидацией. Где:
-
true- любое значение куки разрешено (валидация не выполняется). -
false- куки запрещены. -
объект валидации joi.
-
функция валидации, использующая подпись
async function(value, options), где:-
value- объектrequest.state, содержащий все проанализированные значения куки. -
options-options. - если возвращается значение, значение используется в качестве нового значения
request.state, а исходное значение сохраняется вrequest.orig.state. В противном случае значения куки остаются неизменными. Если возникает ошибка, ошибка обрабатывается в соответствии сfailAction.
-
route.options.validate.validator
Значение по умолчанию: null (без модуля валидации по умолчанию).
Устанавливает модуль валидации сервера, используемый для компиляции необработанных правил валидации в схемы валидации (например, joi).
Примечание: модуль валидации используется только тогда, когда правила валидации не являются предварительно скомпилированными схемами. Когда правило валидации является функцией или объектом схемы, правило используется как есть, и модуль валидации не используется.
Жизненный цикл запроса
Каждый входящий запрос проходит через жизненный цикл запроса. Конкретные шаги зависят от конфигурации сервера и маршрута, но порядок выполнения применимых шагов всегда одинаков. Ниже приведён полный список шагов, которые может пройти запрос:
-
onRequest
- всегда вызывается, когда существуют расширения
onRequest. - путь запроса и метод могут быть изменены с помощью методов
request.setUrl()иrequest.setMethod(). Изменения пути или метода запроса повлияют на то, как запрос будет маршрутизирован, и могут быть использованы для правил перенаправления. -
request.payloadявляетсяundefinedи может быть переопределён любым ненулевым значением для обхода обработки полезной нагрузки. -
request.routeне назначен. -
request.urlможет бытьnull, если путь входящего запроса некорректен. -
request.pathможет быть некорректным путём.
- всегда вызывается, когда существуют расширения
-
Поиск маршрута
- поиск, основанный на
request.pathиrequest.method. - переходит к onPreResponse, если маршрут не найден или путь нарушает спецификацию HTTP.
- поиск, основанный на
-
Обработка куки
- основана на параметре маршрута
state. - обработка ошибок основана на
failAction.
- основана на параметре маршрута
-
onPreAuth
- вызывается независимо от того, выполняется ли аутентификация.
-
Аутентификация
- основана на параметре маршрута
auth.
- основана на параметре маршрута
-
Обработка полезной нагрузки
- основана на параметре маршрута
payloadи еслиrequest.payloadне был переопределён в onRequest. - обработка ошибок основана на
failAction.
- основана на параметре маршрута
-
Аутентификация полезной нагрузки
- основана на параметре маршрута
auth.
- основана на параметре маршрута
-
onCredentials
- вызывается только если выполняется аутентификация.
-
Авторизация
- основана на параметре аутентификации маршрута
access.
- основана на параметре аутентификации маршрута
-
onPostAuth
- вызывается независимо от того, выполняется ли аутентификация.
-
Валидация заголовков
- основана на параметре маршрута
validate.headers. - обработка ошибок основана на
failAction.
- основана на параметре маршрута
-
Валидация параметров пути
- основана на параметре маршрута
validate.params. - обработка ошибок основана на
failAction.
- основана на параметре маршрута
-
Валидация запросов
- основана на параметре маршрута
validate.query. - обработка ошибок основана на
failAction.
- основана на параметре маршрута
-
Валидация полезной нагрузки
- основана на параметре маршрута
validate.payload. - обработка ошибок основана на
failAction.
- основана на параметре маршрута
-
Валидация состояния
- основана на параметре маршрута
validate.state. - обработка ошибок основана на
failAction.
- основана на параметре маршрута
-
onPreHandler
-
Методы предварительной обработки
- основаны на параметре маршрута
pre. - обработка ошибок основана на настройке
failActionкаждого метода предварительной обработки.
- основаны на параметре маршрута
-
Обработчик маршрута
- выполняет маршрут
handler.
- выполняет маршрут
-
onPostHandler
- ответ, содержащийся в
request.response, может быть изменён (но не присвоено новое значение). Для возвращения другого типа ответа (например, замена ошибки HTML-ответом), верните новое значение ответа.
- ответ, содержащийся в
-
Валидация ответа
- обработка ошибок основана на
failAction.
- обработка ошибок основана на
-
onPreResponse
- всегда вызывается, если запрос не прерван.
- ответ, содержащийся в
request.response, может быть изменён (но не присвоено новое значение). Для возвращения другого типа ответа (например, замена ошибки HTML-ответом), верните новое значение ответа. Обратите внимание, что любые сгенерированные ошибки не будут переданы обратно в onPreResponse, чтобы предотвратить бесконечный цикл.
-
Передача ответа
- может генерировать событие
'request'на канале'error'.
- может генерировать событие
-
Завершение запроса
- генерирует событие
'response'.
- генерирует событие
-
onPostResponse
- возвращаемое значение игнорируется, так как ответ уже задан.
- генерирует событие
'request'на канале'error', если возвращается ошибка. - все обработчики расширений выполняются, даже если возникает ошибка.
- обратите внимание, что, поскольку обработчики выполняются последовательно (каждый
await), необходимо позаботиться о том, чтобы избежать блокировки выполнения, если другие обработчики расширений ожидают вызова сразу же при отправке ответа. Если обработчик onPostResponse выполняет ввод-вывод, он должен отложить эту деятельность до следующего цикла и вернуть значение сразу (либо без возвращаемого значения, либо без обещания, которое решает решить).
Методы жизненного цикла
Методы жизненного цикла представляют собой интерфейс между фреймворком и приложением. Многие этапы жизненного цикла запроса: расширения, аутентификация, обработчики, методы предварительной обработки и failAction функции-значения являются методами жизненного цикла, предоставляемыми разработчиком и выполняемыми фреймворком.
Каждый метод жизненного цикла является функцией со следующей подписью await function(request, h, [err]), где:
-
request- объект запроса. -
h- набор инструментов для работы с ответом, который обработчик должен вызвать, чтобы установить ответ и вернуть управление обратно фреймворку. -
err- объект ошибки, доступный только когда метод используется в качествеfailActionзначения.
Каждый метод жизненного цикла должен вернуть значение или обещание, которое разрешается в значение. Если метод жизненного цикла возвращается без значения или разрешается в undefined значение, отправляется ошибка "Внутренняя ошибка сервера" (500).
Возвращаемое значение должно быть одним из:
- Простое значение:
null- строка
- число
- логическое значение
- объект
Buffer - объект
Error,- простое
Error. - объект
Boom.
- простое
- объект
Stream,- должен быть совместим с API "streams2" и не должен находиться в
objectMode. - если у объекта потока есть свойство
statusCode, этот код состояния будет использован в качестве кода ответа по умолчанию на основе параметраpassThrough. - если у объекта потока есть свойство
headers, заголовки будут включены в ответ на основе параметраpassThrough. - если у объекта потока есть функция-свойство
setCompressor(compressor), и ответ проходит через компрессор, ссылка на поток компрессора будет передана в поток ответа через этот метод.
- должен быть совместим с API "streams2" и не должен находиться в
- любой объект или массив
- не должен содержать циклических ссылок.
- сигнал инструментария:
-
h.abandon- прервать обработку запроса. -
h.close- прервать обработку запроса и вызватьend(), чтобы убедиться, что ответ закрыт. -
h.continue- продолжить обработку жизненного цикла запроса без изменения ответа.
-
- ответ метода инструментария:
-
h.response()- оборачивает простой ответ в объект ответа. -
h.redirect()- оборачивает простой ответ с направлением перенаправления. -
h.authenticated()- указывает, что запрос успешно аутентифицирован (только схема аутентификации). -
h.unauthenticated()- указывает, что запрос не смог пройти аутентификацию (только схема аутентификации).
-
- объект обещания, который разрешается в любое из вышеперечисленных значений
Любая ошибка, сгенерированная методом жизненного цикла, будет использована в качестве объекта ответа. Хотя ошибки и допустимые значения могут быть возвращены, рекомендуется генерировать ошибки. Возврат ненулевых значений сгенерирует ошибку "Неправильная реализация" (500).
const handler = function (request, h) {
if (request.query.forbidden) {
throw Boom.badRequest();
}
return 'success';
};Если маршрут имеет параметр bind или был вызван server.bind(), метод жизненного цикла будет связан с предоставленным контекстом через this, а также доступен через h.context.
Поток выполнения жизненного цикла
Поток между каждым шагом жизненного цикла зависит от значения, возвращённого каждым методом жизненного цикла, следующим образом:
-
ошибка:
- жизненный цикл переходит к шагу валидации ответа.
- если возвращено шагом onRequest, он переходит к шагу onPreResponse.
- если возвращено шагом валидации ответа, он переходит к шагу onPreResponse.
- если возвращено шагом onPreResponse, он переходит к шагу передачи ответа.
-
сигнал прерывания (
h.abandonилиh.close):- переходит к шагу финализация запроса.
-
сигнал
h.continue:- продолжает обработку жизненного цикла запроса без изменения ответа запроса.
- не может быть использован методом схемы
authenticate().
-
ответ-захват:
- заменяет ответ запроса предоставленным значением и переходит к шагу валидации ответа.
- если возвращено шагом валидации ответа, он переходит к шагу onPreResponse.
- если возвращено шагом onPreResponse, он переходит к шагу передачи ответа.
-
любой другой ответ:
- заменяет ответ запроса предоставленным значением и продолжает обработку жизненного цикла запроса.
- не может быть возвращен ни на каком шаге до шага методы предварительной обработки.
Метод authenticate() имеет доступ к двум дополнительным значениям возврата: - h.authenticated() - указывает, что запрос успешно аутентифицирован. - h.unauthenticated() - указывает, что запрос не смог пройти аутентификацию.
Обратите внимание, что эти правила применяются несколько иначе, когда используются в методе предварительной обработки предобработчика.
Ответ-захват
Ответ-захват — это response object, на котором был вызван response.takeover() для сигнализации о том, что значение возврата метода жизненного цикла должно быть установлено как ответ и сразу перейти к валидации и передаче значения, минуя другие шаги жизненного цикла.
failAction конфигурация
Различные параметры конфигурации позволяют определить, как обрабатывать ошибки. Например, при получении недействительной полезной нагрузки или неправильного cookie, вместо возвращения ошибки, фреймворк можно настроить на выполнение другого действия. Если поддерживается, опция failAction поддерживает следующие значения:
-
'error'- вернуть объект ошибки как ответ. -
'log'- сообщить об ошибке, но продолжить обработку запроса. -
'ignore'- не выполнять никаких действий и продолжить обработку запроса. -
метод жизненного цикла со сигнатурой
async function(request, h, err), где:-
request- объект запроса. -
h- набор инструментов для ответа. -
err- объект ошибки.
-
Ошибки
hapi использует библиотеку ошибок boom для всех внутренних ошибок. boom предоставляет выразительный интерфейс для возврата HTTP-ошибок. Любая ошибка, брошенная методом жизненного цикла, преобразуется в объект boom и по умолчанию устанавливает код состояния 500 , если ошибка не является уже объектом boom.
При отправке ошибки клиенту ответ содержит JSON-объект с ключами statusCode, error, и message.
const Hapi = require('@hapi/hapi');
const Boom = require('@hapi/boom');
const server = Hapi.server();
server.route({
method: 'GET',
path: '/badRequest',
handler: function (request, h) {
throw Boom.badRequest('Unsupported parameter'); // 400
}
});
server.route({
method: 'GET',
path: '/internal',
handler: function (request, h) {
throw new Error('unexpect error'); // 500
}
});Преобразование ошибок
Ошибки можно настроить, изменив их содержимое output. Объект ошибки boom включает следующие свойства:
-
isBoom- еслиtrue, указывает, что это экземпляр объектаBoom. -
message- сообщение об ошибке. -
output- отформатированный ответ. Может быть непосредственно изменен после создания объекта для возврата настраиваемого ответа об ошибке. Разрешенные корневые ключи:-
statusCode- код HTTP-статуса (обычно 4xx или 5xx). -
headers- объект, содержащий любые HTTP-заголовки, где каждый ключ — имя заголовка, а значение — содержимое заголовка. -
payload- отформатированный объект, используемый в качестве полезной нагрузки ответа. Может быть непосредственно изменен, но любые изменения будут потеряны, если будет вызванreformat(). Разрешено любое содержимое, и по умолчанию включает следующее:-
statusCode- код HTTP-статуса, полученный изerror.output.statusCode. -
error- сообщение HTTP-статуса (например, «Ошибка запроса», «Внутренняя ошибка сервера»), полученное изstatusCode. -
message- сообщение об ошибке, полученное изerror.message.
-
-
-
унаследованные
Errorсвойства.
Также поддерживается следующий метод:
-
reformat()- перестраиваетerror.output, используя другие свойства объекта.
const Boom = require('@hapi/boom');
const handler = function (request, h) {
const error = Boom.badRequest('Cannot feed after midnight');
error.output.statusCode = 499; // Assign a custom error code
error.reformat();
error.output.payload.custom = 'abc_123'; // Add custom key
throw error;
});Если требуется другое представление ошибки, например, HTML-страница или другой формат полезной нагрузки, можно использовать точку расширения 'onPreResponse' для идентификации ошибок и замены их другим объектом ответа объектом ответа, как в этом примере, использующем .view() свойство набора инструментов для ответа набора инструментов для ответа Vision.
const Hapi = require('@hapi/hapi');
const Vision = require('@hapi/vision');
const server = Hapi.server({ port: 80 });
server.register(Vision, (err) => {
server.views({
engines: {
html: require('handlebars')
}
});
});
const preResponse = function (request, h) {
const response = request.response;
if (!response.isBoom) {
return h.continue;
}
// Replace error with friendly HTML
const error = response;
const ctx = {
message: (error.output.statusCode === 404 ? 'page not found' : 'something went wrong')
};
return h.view('error', ctx).code(error.output.statusCode);
};
server.ext('onPreResponse', preResponse);Набор инструментов для ответа
Доступ: только для чтения.
Набор инструментов для ответа — это коллекция свойств и утилит, передаваемых каждому методу жизненного цикла метода жизненного цикла. Его сложно определить, так как он предоставляет как утилиты для работы с ответами, так и другую информацию. Поскольку набор инструментов передаётся как аргумент функции, разработчики могут назвать его как угодно. Для целей этого документа используется обозначение h. Оно названо в духе метода RethinkDB r, с h для hapi.
Свойства набора инструментов
h.abandon
Доступ: только для чтения.
Символ ответа. При возвращении методом жизненного цикла жизненный цикл запроса переходит к шагу финализации без дальнейшего взаимодействия с потоком ответа узла. Ответственность разработчика — записать и завершить ответ непосредственно через request.raw.res.
h.close
Доступ: только для чтения.
Символ ответа. При возвращении методом жизненного цикла жизненный цикл запроса переходит к шагу финализации после вызова request.raw.res.end()) для закрытия потока ответа узла.
h.context
Доступ: чтение/запись (повлияет на общий контекст, если объект будет изменён).
Символ ответа. Предоставляет доступ к контексту маршрута или сервера, установленному с помощью опции маршрута bind или server.bind().
h.continue
Доступ: только для чтения.
Символ ответа. При возвращении методом жизненного цикла жизненный цикл запроса продолжается без изменения ответа.
h.realm
Доступ: только для чтения.
Область сервера сервера, связанная с соответствующим маршрутом. По умолчанию — корневая область сервера на шаге onRequest.
h.request
Доступ: только для чтения и общедоступный интерфейс запроса.
Объект запроса. Это дублирование аргумента метода жизненного цикла request, используемого декорациями набора инструментов для доступа к текущему запросу.
h.authenticated(data)
Используется методом [аутентификации] для возврата действительных учетных данных, где:
-
data- объект с:-
credentials- (обязательно) объект, представляющий аутентифицированного субъекта. -
artifacts- (необязательно) объект артефактов аутентификации, специфичный для схемы аутентификации.
-
Значение возврата: внутренний объект аутентификации.
h.entity(options)
Устанавливает заголовки ответа 'ETag' и 'Last-Modified' и проверяет наличие заголовков условного запроса, чтобы определить, будет ли ответ соответствовать HTTP 304 (Неизменён). Если значения сущности соответствуют условиям запроса, h.entity() возвращает объект ответа объект ответа для возврата методом жизненного цикла, который установит ответ 304. В противном случае он устанавливает предоставленные заголовки сущности и возвращает undefined. Аргументы метода:
-
options- обязательный объект конфигурации с:-
etag- строка ETag. Обязательно, еслиmodifiedне указано. По умолчанию — заголовок отсутствует. -
modified- значение заголовка Last-Modified. Обязательно, еслиetagне указано. По умолчанию — заголовок отсутствует. -
vary- аналогично опцииresponse.etag(). По умолчанию —true.
-
Значение возврата: - объект ответа объект ответа, если ответ не изменён. - undefined если ответ изменился.
Если возвращается undefined, разработчик должен вернуть действительное значение метода жизненного цикла. Если возвращается ответ, он должен быть использован в качестве значения возврата (но может быть настроен с помощью методов ответа).
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
server.route({
method: 'GET',
path: '/',
options: {
cache: { expiresIn: 5000 },
handler: function (request, h) {
const response = h.entity({ etag: 'abc' });
if (response) {
response.header('X', 'y');
return response;
}
return 'ok';
}
}
});
h.redirect(uri)
Перенаправляет клиента на указанный uri. Аналогично вызову h.response().redirect(uri).
Возвращает объект ответа объект ответа.
const handler = function (request, h) {
return h.redirect('http://example.com');
};
h.response([value])
Оборачивает предоставленное значение и возвращает объект объект ответа, который позволяет настроить ответ (например, установить код HTTP-статуса, настраиваемые заголовки и т. д.), где:
-
value- (необязательно) возвращаемое значение. По умолчанию —null.
Возвращает объект ответа объект ответа.
// Detailed notation
const handler = function (request, h) {
const response = h.response('success');
response.type('text/plain');
response.header('X-Custom', 'some-value');
return response;
};
// Chained notation
const handler = function (request, h) {
return h.response('success')
.type('text/plain')
.header('X-Custom', 'some-value');
};
h.state(name, value, [options])
Устанавливает cookie ответа с теми же аргументами, что и response.state().
Значение возврата: ничего.
const ext = function (request, h) {
h.state('cookie-name', 'value');
return h.continue;
};
h.unauthenticated(error, [data])
Используется методом [authentication] для указания того, что аутентификация не удалась, и возврата полученных учетных данных, где:
-
error- (обязательно) ошибка аутентификации. -
data- (необязательно) объект со следующими свойствами:-
credentials- (обязательно) объект, представляющий аутентифицированный субъект. -
artifacts- (необязательно) объект артефактов аутентификации, специфичный для схемы аутентификации.
-
Метод используется для передачи как ошибки аутентификации, так и учетных данных. Например, если в запросе были просроченные учетные данные, этот метод позволяет вернуть информацию о пользователе (вместе с 'try' схемой аутентификации mode) для настройки ошибок.
Разницы между выбросом ошибки и её передачей с помощью метода h.unauthenticated() при отсутствии учетных данных нет, но это может быть полезно для повышения ясности кода.
h.unstate(name, [options])
Очищает куки ответа с теми же аргументами, что и response.unstate().
const ext = function (request, h) {
h.unstate('cookie-name');
return h.continue;
};Объект ответа
Объект ответа содержит значение ответа запроса вместе с различными HTTP-заголовками и флагами. Когда метод жизненного цикла возвращает значение, это значение упаковывается в объект ответа вместе с некоторыми стандартными флагами (например, 200 код состояния). Для настройки ответа перед его возвратом предоставляется метод h.response().
Свойства ответа
response.app
Доступ: чтение/запись.
Значение по умолчанию: {}.
Состояние, специфичное для приложения. Представляет собой безопасное место для хранения данных приложения без потенциальных конфликтов с фреймворком. Не должно использоваться плагинами (plugins), которые должны использовать plugins[name].
response.contentType
Доступ: чтение.
Значение по умолчанию: отсутствует.
Предварительный просмотр заголовка HTTP Content-Type ответа на основе неявного типа ответа, любого явного заголовка Content-Type и любого определенного набора символов контента. Возвращаемое значение является лишь предварительным, поскольку тип контента может измениться позже как внутри фреймворка, так и кодом пользователя (он представляет текущее состояние ответа). Значение равно null если не удаётся определить неявный тип.
response.events
Доступ: только для чтения и для публичного интерфейса podium.
Объект response.events поддерживает следующие события:
-
'peek'- генерируется для каждого фрагмента данных, отправленных обратно соединению с клиентом. Подпись метода события:function(chunk, encoding). -
'finish'- генерируется, когда ответ закончил запись, но прежде чем соединение с клиентом будет закрыто. Подпись метода события:function ().
const Crypto = require('crypto');
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
const preResponse = function (request, h) {
const response = request.response;
if (response.isBoom) {
return null;
}
const hash = Crypto.createHash('sha1');
response.events.on('peek', (chunk) => {
hash.update(chunk);
});
response.events.once('finish', () => {
console.log(hash.digest('hex'));
});
return h.continue;
};
server.ext('onPreResponse', preResponse);
response.headers
Доступ: только для чтения.
Значение по умолчанию: {}.
Объект, содержащий заголовки ответа, где каждый ключ — это имя поля заголовка, а значение — строковое значение заголовка или массив строк.
Обратите внимание, что это неполный список заголовков, которые должны быть включены в ответ. Дополнительные заголовки будут добавлены после подготовки ответа к передаче.
response.plugins
Доступ: чтение/запись.
Значение по умолчанию: {}.
Состояние, специфичное для плагина. Предоставляет место для хранения и передачи данных плагина на уровне запроса. plugins — это объект, где каждый ключ — имя плагина, а значение — состояние.
response.settings
Доступ: только для чтения.
Объект, содержащий флаги обработки ответа.
response.settings.passThrough
Доступ: только для чтения.
Значение по умолчанию: true.
Если true и source является Stream, копирует свойства statusCode и headers объекта потока в исходящий ответ.
response.settings.stringify
Доступ: только для чтения.
Значение по умолчанию: null (используются значения по умолчанию маршрута).
Переопределяет параметры маршрута json, используемые при необходимости строкового преобразования значения source.
response.settings.ttl
Доступ: только для чтения.
Значение по умолчанию: null (используются значения по умолчанию маршрута).
Если задано, переопределяет маршрут cache значением срока действия в миллисекундах.
response.settings.varyEtag
Значение по умолчанию: false.
Если true, суффикс будет автоматически добавлен к заголовку 'ETag' во время передачи (разделенный символом '-') при наличии заголовка HTTP 'Vary'.
response.source
Доступ: только для чтения.
Исходное значение, возвращённое методом жизненного цикла.
response.statusCode
Доступ: только для чтения.
Значение по умолчанию: 200.
Код состояния HTTP-ответа.
response.variety
Доступ: только для чтения.
Строка, указывающая тип source с доступными значениями:
-
'plain'- простой ответ, такой как строка, число,null, или простой объект. -
'buffer'-Buffer. -
'stream'-Stream.
response.bytes(length)
Устанавливает заголовок HTTP 'Content-Length' (чтобы избежать кодирования с фрагментацией) где:
-
length- значение заголовка. Должно соответствовать фактическому размеру полезной нагрузки.
Возвращаемое значение: текущий объект ответа.
response.charset(charset)
Устанавливает свойство 'charset' заголовка HTTP 'Content-Type', где:
-
charset- значение свойства charset. Если значениеcharsetложно, это предотвратит использование hapi его значения charset по умолчанию.
Возвращаемое значение: текущий объект ответа.
response.code(statusCode)
Устанавливает код состояния HTTP, где:
-
statusCode- код состояния HTTP (например, 200).
Возвращаемое значение: текущий объект ответа.
response.message(httpMessage)
Устанавливает сообщение состояния HTTP, где:
-
httpMessage- сообщение состояния HTTP (например, 'Ok' для кода состояния 200).
Возвращаемое значение: текущий объект ответа.
response.compressed(encoding)
Устанавливает заголовок HTTP 'content-encoding', где:
-
encoding- строковое значение заголовка.
Возвращаемое значение: текущий объект ответа.
Обратите внимание, что установка кодирования контента с помощью этого метода не устанавливает заголовок 'vary' со значением 'accept-encoding'. Для изменения ответа используйте метод response.header().
response.created(uri)
Устанавливает код состояния HTTP в Created (201) и заголовок HTTP 'Location', где:
-
uri- абсолютный или относительный URI, используемый в качестве значения заголовка 'Location'.
Возвращаемое значение: текущий объект ответа.
response.encoding(encoding)
Устанавливает схему кодирования строк, используемую для сериализации данных в полезную нагрузку HTTP, где:
-
encoding- значение свойства кодирования (см. кодировку узла Buffer).
Возвращаемое значение: текущий объект ответа.
response.etag(tag, options)
Устанавливает метку сущности представления, где:
-
tag- строка метки сущности без двойных кавычек. -
options- (необязательно) настройки, где:-
weak- еслиtrue, метка будет префикснута слабым индикатором'W/'. Слабые метки не будут соответствовать идентичным меткам для определения статуса ответа 304. По умолчаниюfalse. -
vary- еслиtrueи кодирование контента установлено или применено к ответу (например, 'gzip' или 'deflate'), имя кодирования будет автоматически добавлено к метке во время передачи (разделенное символом'-'). Игнорируется, когдаweakравноtrue. По умолчаниюtrue.
-
Возвращаемое значение: текущий объект ответа.
response.header(name, value, options)
Устанавливает заголовок HTTP, где:
-
name- имя заголовка. -
value- значение заголовка. -
options- (необязательно) объект, где:-
append- еслиtrue, значение добавляется к существующему значению заголовка, используяseparator. По умолчаниюfalse. -
separator- строка, используемая в качестве разделителя при добавлении к существующему значению. По умолчанию','. -
override- еслиfalse, значение заголовка не устанавливается, если существует. Не применяется, когдаappendравноfalseили еслиnameравно'set-cookie'. По умолчаниюtrue. -
duplicate- еслиfalse, значение заголовка не изменяется, если предоставленное значение уже включено. Не применяется, когдаappendравноfalseили еслиnameравно'set-cookie'. По умолчаниюtrue.
-
Возвращаемое значение: текущий объект ответа.
response.location(uri)
Устанавливает заголовок HTTP 'Location', где:
-
uri- абсолютный или относительный URI, используемый в качестве значения заголовка 'Location'.
Возвращаемое значение: текущий объект ответа.
response.redirect(uri)
Устанавливает ответ HTTP перенаправления (302) и дополняет ответ дополнительными методами, где:
-
uri- абсолютный или относительный URI, используемый для перенаправления клиента на другой ресурс.
Возвращаемое значение: текущий объект ответа.
Дополняет объект ответа методами response.temporary(), response.permanent() и response.rewritable() для лёгкого изменения кода перенаправления по умолчанию (302).
| Постоянно | Временно | |
|---|---|---|
| Переписываемый | 301 | 302 |
| Непереписываемый | 308 | 307 |
response.replacer(method)
Устанавливает аргумент JSON.stringify() replacer, где:
-
method- функция или массив замены. По умолчанию ничего.
Возвращаемое значение: текущий объект ответа.
response.spaces(count)
Устанавливает аргумент JSON.stringify() space, где:
-
count- количество отступов для вложенных ключей объекта. По умолчанию отступы отсутствуют.
Значение возврата: текущий объект ответа.
response.state(name, value, [options])
Устанавливает HTTP-cookie, где:
-
name- имя cookie. -
value- значение cookie. Еслиoptions.encodingне определено, должно быть строкой. Смотритеserver.state()для поддерживаемых значенийencoding. -
options- (необязательно) конфигурация. Если состояние ранее было зарегистрировано на сервере с помощьюserver.state(), указанные ключи вoptionsобъединяются с определениями по умолчанию сервера.
Значение возврата: текущий объект ответа.
response.suffix(suffix)
Устанавливает строковый суффикс при обработке ответа через JSON.stringify(), где:
-
suffix- строковый суффикс.
Значение возврата: текущий объект ответа.
response.ttl(msec)
Переопределяет правило кэширования по умолчанию для срока действия маршрута в этом экземпляре ответа, где:
-
msec- значение срока действия в миллисекундах.
Значение возврата: текущий объект ответа.
response.type(mimeType)
Устанавливает заголовок HTTP 'Content-Type', где:
-
mimeType- тип MIME.
Значение возврата: текущий объект ответа.
Должен использоваться только для переопределения встроенного значения по умолчанию для каждого типа ответа.
response.unstate(name, [options])
Очищает HTTP-cookie, устанавливая значение истечения срока действия, где:
-
name- имя cookie. -
options- (необязательно) конфигурация для истечения срока действия cookie. Если состояние ранее было зарегистрировано на сервере с помощьюserver.state(), указанныеoptionsобъединяются с определением сервера.
Значение возврата: текущий объект ответа.
response.vary(header)
Добавляет предоставленный заголовок в список входов, влияющих на генерацию ответа с помощью заголовка HTTP 'Vary', где:
-
header- имя заголовка HTTP запроса.
Значение возврата: текущий объект ответа.
response.takeover()
Помечает объект ответа как ответ захвата.
Значение возврата: текущий объект ответа.
response.temporary(isTemporary)
Устанавливает код состояния в 302 или 307 (в зависимости от параметра response.rewritable()), где:
-
isTemporary- еслиfalse, устанавливает статус на постоянный. По умолчаниюtrue.
Значение возврата: текущий объект ответа.
Доступно только после вызова метода response.redirect().
response.permanent(isPermanent)
Устанавливает код состояния в 301 или 308 (в зависимости от параметра response.rewritable()), где:
-
isPermanent- еслиfalse, устанавливает статус на временный. По умолчаниюtrue.
Значение возврата: текущий объект ответа.
Доступно только после вызова метода response.redirect().
response.rewritable(isRewritable)
Устанавливает код состояния в 301/302 для перезаписываемого (разрешает изменение метода запроса с 'POST' на 'GET') или 307/308 для неперезаписываемого (не разрешает изменение метода запроса с 'POST' на 'GET'). Точный код зависит от параметра response.temporary() или response.permanent(). Аргументы:
-
isRewritable- еслиfalse, устанавливает на неперезаписываемый. По умолчаниюtrue.
Значение возврата: текущий объект ответа.
Доступно только после вызова метода response.redirect().
Запрос
Объект запроса создается внутри для каждого входящего запроса. Это не тот же объект, который получен от обратного вызова сервера Node HTTP (который доступен через request.raw.req). Свойства запроса изменяются на протяжении всего жизненного цикла запроса.
Свойства запроса
request.app
Доступ: чтение / запись.
Состояние, специфичное для приложения. Предоставляет безопасное место для хранения данных приложения без потенциальных конфликтов с фреймворком. Не должен использоваться плагинами, которые должны использовать plugins[name].
request.auth
Доступ: только для чтения.
Информация об аутентификации:
-
artifacts- объект артефакта, полученный от стратегии аутентификации и используемый в действиях, связанных с аутентификацией. -
credentials- объектcredential, полученный во время процесса аутентификации. Наличие объекта не означает успешной аутентификации. -
error- ошибка аутентификации, если произошел сбой и режим установлен на'try'. -
isAuthenticated-true, если запрос успешно аутентифицирован, в противном случаеfalse. -
isAuthorized-trueесли запрос успешно авторизован по настройкам аутентификации маршрутаaccess. Если в маршруте нет правил доступа или запрос не прошел авторизацию, устанавливаетсяfalse. -
isInjected-trueесли запрос был аутентифицирован с помощьюserver.inject()опцииauth, в противном случаеundefined. -
mode- режим аутентификации маршрута. -
strategy- имя используемой стратегии.
request.events
Доступ: только для чтения и общедоступный интерфейс podium.
request.events поддерживает следующие события:
-
'peek'- генерируется для каждого фрагмента данных полезной нагрузки, считанных из соединения клиента. Подпись метода событияfunction(chunk, encoding). -
'finish'- генерируется, когда чтение полезной нагрузки запроса завершено. Подпись метода событияfunction (). -
'disconnect'- генерируется, когда запрос ошибается или прерывается неожиданно.
const Crypto = require('crypto');
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
const onRequest = function (request, h) {
const hash = Crypto.createHash('sha1');
request.events.on('peek', (chunk) => {
hash.update(chunk);
});
request.events.once('finish', () => {
console.log(hash.digest('hex'));
});
request.events.once('disconnect', () => {
console.error('request aborted');
});
return h.continue;
};
server.ext('onRequest', onRequest);
request.headers
Доступ: только для чтения.
Исходные заголовки запроса (ссылки request.raw.req.headers).
request.info
Доступ: только для чтения.
Информация о запросе:
-
acceptEncoding- предпочтительное кодирование запроса. -
completed- отметка времени завершения обработки запроса (0все еще обрабатывается). -
cors- информация о CORS запроса (доступна только после точки расширения'onRequest', так как CORS настроен на каждый маршрут и решения по маршрутизации не принимаются на данном этапе жизненного цикла запроса), где:-
isOriginMatch-trueесли заголовок запроса 'Origin' соответствует настройкам CORS. Устанавливается вfalseесли заголовок 'Origin' не найден или не соответствует.
-
-
host- содержимое заголовка HTTP 'Host' (например, 'example.com:8080'). -
hostname- имя хоста из заголовка 'Host' (например, 'example.com'). -
id- уникальный идентификатор запроса (в формате '{now}:{server.info.id}:{5-значный счетчик}'). -
received- отметка времени получения запроса. -
referrer- содержимое заголовка HTTP 'Referrer' (или 'Referer'). -
remoteAddress- IP-адрес удаленного клиента. -
remotePort- порт удаленного клиента. -
responded- отметка времени ответа запроса (0ещё не ответил или ответ завершился неудачно, когдаcompletedустановлен).
Обратите внимание, что объект request.info не предназначен для изменения.
request.isInjected
Доступ: только для чтения.
true если запрос был создан с помощью server.inject(), и false в противном случае.
request.logs
Доступ: только для чтения.
Массив, содержащий зарегистрированные события запроса.
Обратите внимание, что этот массив будет пустым, если параметр маршрута log.collect установлен на false.
request.method
Доступ: только для чтения.
Метод запроса в нижнем регистре (например, 'get', 'post').
request.mime
Доступ: только для чтения.
Парсируемый заголовок типа содержимого. Доступен только при включенном анализе полезной нагрузки и отсутствии ошибок полезной нагрузки.
request.orig
Доступ: только для чтения.
Объект, содержащий значения params, query, payload и state до любых изменений валидации. Устанавливается только при выполнении валидации ввода.
request.params
Доступ: только для чтения.
Объект, где каждый ключ — имя параметра пути с соответствующим значением, как описано в Параметрах пути.
request.paramsArray
Доступ: только для чтения.
Массив, содержащий все значения параметров пути params в том порядке, в котором они появляются в пути.
request.path
Доступ: только для чтения.
Компонент pathname URI запроса.
request.payload
Доступ: только для чтения / запись в методе расширения 'onRequest'.
Полезная нагрузка запроса, основанная на маршруте payload.output и настройках payload.parse. Устанавливается в undefined в методах расширения 'onRequest' и может быть переопределён на любое значение, отличное от undefined, чтобы обойти обработку полезной нагрузки.
request.plugins
Доступ: чтение / запись.
Состояние, специфичное для плагинов. Предоставляет место для хранения и передачи данных плагинов на уровне запроса. plugins — это объект, где каждый ключ — имя плагина, а значение — состояние.
request.pre
Доступ: только для чтения.
Объект, где каждый ключ — имя, назначенное функцией методов предварительной обработки маршрута. Значения — это исходные значения, предоставленные функции продолжения в качестве аргумента. Для обернутого объекта ответа используйте responses.
request.response
Доступ: чтение / запись (см. ограничения ниже).
Объект ответа при установке. Объект можно изменить, но нельзя назначить другой объект. Чтобы заменить ответ другим изнутри точки расширения точки расширения, верните новое значение ответа. Содержит ошибку, когда запрос завершается преждевременно при отключении клиента.
request.preResponses
Доступ: только чтение.
То же, что и pre, но представлено как объект ответа, созданный методом pre.
request.query
Доступ: только чтение.
Объект, где каждый ключ — имя параметра запроса, а каждое соответствующее значение — значение параметра или массив значений, если параметр повторяется. Может быть изменён косвенно через request.setUrl.
request.raw
Доступ: только чтение.
Объект, содержащий объекты Node HTTP сервера. Прямое взаимодействие с этими сырыми объектами не рекомендуется.
-
req— объект запроса node. -
res— объект ответа node.
request.route
Доступ: только чтение.
Объект информации о маршруте запроса, где:
-
method— HTTP-метод маршрута. -
path— путь маршрута. -
vhost— опция vhost маршрута, если настроена. -
realm— активный домен, связанный с маршрутом. -
settings— объект опций маршрута со всеми применёнными значениями по умолчанию. -
fingerprint— внутренняя нормализованная строка маршрута, представляющая нормализованный путь.
request.server
Доступ: только чтение и общедоступный интерфейс сервера.
Объект сервера.
request.state
Доступ: только чтение.
Объект, содержащий информацию о состоянии HTTP (куки), где каждый ключ — имя куки, а значение — соответствующее содержимое куки после обработки с использованием любого зарегистрированного определения куки.
request.url
Доступ: только чтение.
Разложенный URI запроса.
request.generateResponse(source, [options])
Возвращает response, который можно передать в h.response(), где:
-
source— значение, устанавливаемое в качестве источника h.response(), необязательно. -
options— необязательный объект со следующими необязательными свойствами:-
variety— строковое имя типа ответа (например,'file'). -
prepare— функция со сигнатуройasync function(response)для подготовки ответа после его возвращения методом жизненного цикла, например, для установки дескриптора файла, где:-
response— объект ответа, который готовится. - должна возвращать подготовленный объект ответа (
response). - может выбросить ошибку, которая используется в качестве подготовленного ответа.
-
-
marshal— функция со сигнатуройasync function(response)для подготовки ответа к передаче клиенту перед отправкой, где:-
response— объект ответа, который маршализуется. - должна возвращать подготовленное значение (не как объект ответа), которое может быть любым значением, принимаемым аргументом
h.response()value. - может выбросить ошибку, которая используется в качестве маршализованного значения.
-
-
close— функция со сигнатуройfunction(response)для закрытия ресурсов, открытых объектом ответа (например, дескрипторы файлов), где:-
response— объект ответа, который маршализуется. - не должна генерировать ошибки (которые регистрируются, но игнорируются).
-
-
request.active()
Возвращает true когда запрос активен и обработка должна продолжаться и false когда запрос был прерван или завершил свой жизненный цикл. Полезно, когда обработка запроса является ресурсоёмкой операцией и должна быть прервана, если запрос больше не активен (например, клиент отключился или прервал запрос).
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
server.route({
method: 'POST',
path: '/worker',
handler: function (request, h) {
// Do some work...
// Check if request is still active
if (!request.active()) {
return h.close;
}
// Do some more work...
return null;
}
});
request.log(tags, [data])
Регистрирует события, специфичные для запроса. При вызове сервер излучает 'request' событие на канале 'app', которое может быть использовано другими слушателями или плагинами. Аргументы:
-
tags— строка или массив строк (например,['error', 'database', 'read']) для идентификации события. Теги используются вместо уровней логирования и предоставляют более выразительный механизм для описания и фильтрации событий. -
data— (необязательно) строка сообщения или объект с данными приложения, которые регистрируются. Еслиdataявляется функцией, её сигнатура —function(), и она вызывается один раз для генерации (возвращаемого значения) фактических данных, излучаемых слушателям.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80, routes: { log: { collect: true } } });
server.events.on({ name: 'request', channels: 'app' }, (request, event, tags) => {
if (tags.error) {
console.log(event);
}
});
const handler = function (request, h) {
request.log(['test', 'error'], 'Test event');
return null;
};Обратите внимание, что любые журналы, генерируемые сервером, будут излучаться с использованием 'request' события на канале 'internal'.
server.events.on({ name: 'request', channels: 'internal' }, (request, event, tags) => {
console.log(event);
});
request.route.auth.access(request)
Проверяет запрос на соответствие конфигурации аутентификации маршрута access, где:
-
request— объект запроса.
Возвращаемое значение: true если бы request прошло требования доступа маршрута.
Обратите внимание, что режим и стратегии аутентификации маршрута игнорируются. Единственное соответствие — между областью видимости request.auth.credentials и информацией об объекте и конфигурацией доступа маршрута access.
Если маршрут использует динамические области видимости, области видимости конструируются на основе request.query, request.params, request.payload и request.auth.credentials, которые могут или не могут совпадать между маршрутом и маршрутом запроса. Если этот метод вызывается с запросом, который ещё не был аутентифицирован (или вообще не был), он вернёт false, если маршрут требует аутентификации.
request.setMethod(method)
Изменяет метод запроса перед тем, как маршрутизатор начнёт обработку запроса, где:
-
method— метод HTTP запроса (например,'GET').
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
const onRequest = function (request, h) {
// Change all requests to 'GET'
request.setMethod('GET');
return h.continue;
};
server.ext('onRequest', onRequest);Может быть вызван только из метода расширения 'onRequest'.
request.setUrl(url, [stripTrailingSlash]
Изменяет URI запроса перед тем, как маршрутизатор начнёт обработку запроса, где:
-
url— новый URI запроса.urlможет быть строкой или экземпляромUrl.URL, в этом случае используетсяurl.href. -
stripTrailingSlash— еслиtrue, удалить конечный слэш из пути. По умолчаниюfalse.
const Hapi = require('@hapi/hapi');
const server = Hapi.server({ port: 80 });
const onRequest = function (request, h) {
// Change all requests to '/test'
request.setUrl('/test');
return h.continue;
};
server.ext('onRequest', onRequest);Может быть вызван только из метода расширения 'onRequest'.
Плагины
Плагины предоставляют способ организации кода приложения, разделяя логику сервера на более мелкие компоненты. Каждый плагин может манипулировать сервером через стандартный интерфейс сервера, но с добавленной возможностью изоляции определённых свойств. Например, установка пути к файлу в одном плагине не влияет на путь к файлу в другом плагине.
Плагин — это объект со следующими свойствами:
-
register— (обязательно) функция регистрации со сигнатуройasync function(server, options), где:-
server— объект сервера со специфическим для плагинаserver.realm. -
options— любые параметры, переданные плагину при регистрации черезserver.register().
-
-
name— (обязательно) строка имени плагина. Имя используется в качестве уникального ключа. Опубликованные плагины (например, опубликованные в реестре npm) должны использовать то же имя, что и имя в файле 'package.json'. Имена должны быть уникальными в каждом приложении. -
version— (необязательно) строка версии плагина. Версия используется только для информации, чтобы позволить другим плагинам узнать загруженные версии. Версия должна совпадать с указанной в файле 'package.json' плагина. -
multiple— (необязательно) еслиtrue, позволяет зарегистрировать плагин несколько раз с тем же сервером. По умолчаниюfalse. -
dependencies— (необязательно) строка или массив строк, указывающие зависимость плагина. Аналогично установке зависимостей черезserver.dependency(). -
requirements— (необязательно) объект, объявляющий поддерживаемый плагином диапазон semver:-
nodeстрока диапазона semver для среды выполнения. -
hapiстрока диапазона semver для фреймворка.
-
-
once— (необязательно) еслиtrue, будет регистрировать плагин только один раз на сервер. Если установлено, переопределяет опциюonce, переданную вserver.register(). По умолчанию переопределения нет.
const plugin = {
name: 'test',
version: '1.0.0',
register: function (server, options) {
server.route({
method: 'GET',
path: '/test',
handler: function (request, h) {
return 'ok';
}
});
}
};В качестве альтернативы, name и version могут быть включены через свойство pkg, содержащее файл 'package.json' для модуля, который уже содержит имя и версию:
const plugin = {
pkg: require('./package.json'),
register: function (server, options) {
server.route({
method: 'GET',
path: '/test',
handler: function (request, h) {
return 'ok';
}
});
}
};
Copyright © 2011-2022, Project contributors Copyright © 2011-2020, Sideway Inc Copyright © 2011-2014, Walmart
Copyright © 2011, Yahoo Inc.
Licensed under the BSD 3-clause License.
https://hapi.dev/api/?v=21.3.2