@e22m4u/js-trie-router
ES-модуль HTTP роутера для Node.js, использующий
Trie
для разрешения маршрутов.
- Поддержка path-to-regexp синтаксиса.
- Автоматический парсинг JSON-тела запроса.
- Парсинг строки запроса и заголовка
cookie
. - Поддержка
preHandler
и postHandler
хуков. - Позволяет использовать асинхронные обработчики.
Установка
npm install @e22m4u/js-trie-router
Для загрузки ES-модуля требуется установить "type": "module"
в файле
package.json
, или использовать .mjs
расширение.
Обзор
Базовый пример создания экземпляра роутера, объявления маршрута
и передачи слушателя запросов http
серверу.
import http from 'http';
import {TrieRouter} from '@e22m4u/js-path-trie';
const server = new http.Server();
const router = new TrieRouter();
router.defineRoute({
method: 'GET',
path: '/',
handler(ctx) {
return 'Hello world!';
},
});
server.on('request', router.requestListener);
server.listen(3000, 'localhost');
Контекст запроса
Первый параметр обработчика маршрута принимает экземпляр класса
RequestContext
с набором свойств, содержащих разобранные
данные входящего запроса.
container: ServiceContainer
экземпляр сервис-контейнераreq: IncomingMessage
нативный поток запроса модуля http
res: ServerResponse
нативный поток ответа модуля http
params: ParsedParams
объект ключ-значение с параметрами путиquery: ParsedQuery
объект ключ-значение с параметрами строки запросаheaders: ParsedHeaders
объект ключ-значение с заголовками запросаcookie: ParsedCookie
объект ключ-значение разобранного заголовка cookie
method: string
метод запроса в верхнем регистре, например GET
, POST
и т.д.path: string
путь включающий строку запроса, например /myPath?foo=bar
pathname: string
путь запроса, например /myMath
Пример доступа к контексту из обработчика маршрута.
router.defineRoute({
method: 'GET',
path: '/users/:id',
handler(ctx) {
console.log(ctx.req);
console.log(ctx.res);
console.log(ctx.params);
console.log(ctx.query);
console.log(ctx.headers);
console.log(ctx.cookie);
console.log(ctx.method);
console.log(ctx.path);
console.log(ctx.pathname);
},
});
Отправка ответа
Возвращаемое значение обработчика маршрута используется в качестве ответа
сервера. Тип значения влияет на представление возвращаемых данных. Например,
если результатом будет являться тип object
, то такое значение автоматически
сериализуется в JSON.
value | content-type |
---|
string | text/plain |
number | application/json |
boolean | application/json |
object | application/json |
Buffer | application/octet-stream |
Stream | application/octet-stream |
Пример возвращаемого значения обработчиком маршрута.
router.defineRoute({
handler(ctx) {
return {foo: 'bar'};
},
});
Контекст запроса ctx
содержит нативный экземпляр класса ServerResponse
,
который может быть использован для ручного управления ответом.
router.defineRoute({
handler(ctx) {
res.statusCode = 404;
res.setHeader('content-type', 'text/plain; charset=utf-8');
res.end('404 Not Found', 'utf-8');
},
});
Хуки маршрута
Определение маршрута методом defineRoute
позволяет задать хуки
для отслеживания и перехвата входящего запроса и ответа
конкретного маршрута.
preHandler
выполняется перед вызовом обработчикаpostHandler
выполняется после вызова обработчика
preHandler
Перед вызовом обработчика маршрута может потребоваться выполнение
таких операции как авторизация и проверка параметров запроса. Для
этого можно использовать хук preHandler
.
router.defineRoute({
preHandler(ctx) {
console.log(`Incoming request ${ctx.method} ${ctx.path}`);
},
handler(ctx) {
return 'Hello world!';
},
});
Если хук preHandler
возвращает значение отличное от undefined
и null
,
то такое значение будет использовано в качестве ответа сервера, а вызов
обработчика маршрута будет пропущен.
router.defineRoute({
preHandler(ctx) {
return 'Are you authorized?';
},
handler(ctx) {
},
});
postHandler
Возвращаемое значение обработчика маршрута передается вторым аргументом
хука postHandler
. По аналогии с preHandler
, если возвращаемое
значение отличается от undefined
и null
, то такое значение будет
использовано в качестве ответа сервера. Это может быть полезно для
модификации возвращаемого ответа.
router.defineRoute({
handler(ctx) {
return 'Hello world!';
},
postHandler(ctx, data) {
return data.toUpperCase();
},
});
Глобальные хуки
Экземпляр роутера TrieRouter
позволяет задать глобальные хуки, которые
имеют более высокий приоритет перед хуками маршрута, и вызываются
в первую очередь.
preHandler
выполняется перед вызовом обработчикаpostHandler
выполняется после вызова обработчика
Добавить глобальные хуки можно методом addHook
экземпляра роутера,
где первым параметром передается название хука, а вторым его функция.
router.addHook('preHandler', (ctx) => {
});
router.addHook('postHandler', (ctx, data) => {
});
Аналогично хукам маршрута, если глобальный хук возвращает значение
отличное от undefined
и null
, то такое значение будет использовано
как ответ сервера.
Отладка
Установка переменной DEBUG
перед командой запуска включает вывод логов.
DEBUG=jsPathTrie* npm run test
Тестирование
npm run test
Лицензия
MIT