@e22m4u/js-trie-router 0.0.16 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -94
- package/dist/cjs/index.cjs +3 -3
- package/package.json +36 -36
- package/README-ru.md +0 -254
package/README.md
CHANGED
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
## @e22m4u/js-trie-router
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
HTTP маршрутизатор для Node.js на основе
|
|
4
|
+
[префиксного дерева](https://ru.wikipedia.org/wiki/Trie) (trie).
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
- Поддержка [path-to-regexp](https://github.com/pillarjs/path-to-regexp) синтаксиса.
|
|
7
|
+
- Автоматический парсинг JSON-тела запроса.
|
|
8
|
+
- Парсинг строки запроса и заголовка `cookie`.
|
|
9
|
+
- Поддержка `preHandler` и `postHandler` хуков.
|
|
10
|
+
- Позволяет использовать асинхронные обработчики.
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
- Parses JSON request body automatically.
|
|
10
|
-
- Parses query string and `cookie` header.
|
|
11
|
-
- Supports `preHandler` and `postHandler` hooks.
|
|
12
|
-
- Supports asynchronous handlers.
|
|
12
|
+
## Установка
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Node.js 16 or higher is required.
|
|
14
|
+
Требуется Node.js 16 и выше.
|
|
17
15
|
|
|
18
16
|
```bash
|
|
19
17
|
npm install @e22m4u/js-trie-router
|
|
20
18
|
```
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
Модуль поддерживает ESM и CommonJS стандарты.
|
|
23
21
|
|
|
24
22
|
*ESM*
|
|
25
23
|
|
|
@@ -33,51 +31,51 @@ import {TrieRouter} from '@e22m4u/js-trie-router';
|
|
|
33
31
|
const {TrieRouter} = require('@e22m4u/js-trie-router');
|
|
34
32
|
```
|
|
35
33
|
|
|
36
|
-
##
|
|
34
|
+
## Обзор
|
|
37
35
|
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
Базовый пример создания экземпляра роутера, объявления маршрута
|
|
37
|
+
и передачи слушателя запросов HTTP серверу.
|
|
40
38
|
|
|
41
39
|
```js
|
|
42
40
|
import http from 'http';
|
|
43
41
|
import {TrieRouter} from '@e22m4u/js-trie-router';
|
|
44
42
|
|
|
45
|
-
const server = new http.Server(); //
|
|
46
|
-
const router = new TrieRouter(); //
|
|
43
|
+
const server = new http.Server(); // создание экземпляра HTTP сервера
|
|
44
|
+
const router = new TrieRouter(); // создание экземпляра роутера
|
|
47
45
|
|
|
48
|
-
router.defineRoute({
|
|
49
|
-
method: 'GET', //
|
|
50
|
-
path: '/', //
|
|
51
|
-
handler(ctx) { //
|
|
46
|
+
router.defineRoute({
|
|
47
|
+
method: 'GET', // метод запроса "GET", "POST" и т.д.
|
|
48
|
+
path: '/', // шаблон пути, пример "/user/:id"
|
|
49
|
+
handler(ctx) { // обработчик маршрута
|
|
52
50
|
return 'Hello world!';
|
|
53
51
|
},
|
|
54
52
|
});
|
|
55
53
|
|
|
56
|
-
server.on('request', router.requestListener); //
|
|
57
|
-
server.listen(3000, 'localhost'); //
|
|
54
|
+
server.on('request', router.requestListener); // подключение роутера
|
|
55
|
+
server.listen(3000, 'localhost'); // прослушивание запросов
|
|
58
56
|
|
|
59
57
|
// Open in browser http://localhost:3000
|
|
60
58
|
```
|
|
61
59
|
|
|
62
|
-
###
|
|
60
|
+
### Контекст запроса
|
|
63
61
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
Первый параметр обработчика маршрута принимает экземпляр класса
|
|
63
|
+
`RequestContext` с набором свойств, содержащих разобранные
|
|
64
|
+
данные входящего запроса.
|
|
67
65
|
|
|
68
|
-
- `container: ServiceContainer`
|
|
69
|
-
- `req: IncomingMessage`
|
|
70
|
-
- `res: ServerResponse`
|
|
71
|
-
- `params: ParsedParams`
|
|
72
|
-
- `query: ParsedQuery`
|
|
73
|
-
- `headers: ParsedHeaders`
|
|
74
|
-
- `cookie: ParsedCookie`
|
|
75
|
-
- `method: string`
|
|
76
|
-
- `path: string`
|
|
77
|
-
- `pathname: string`
|
|
78
|
-
- `body: unknown`
|
|
66
|
+
- `container: ServiceContainer` экземпляр [сервис-контейнера](https://npmjs.com/package/@e22m4u/js-service)
|
|
67
|
+
- `req: IncomingMessage` нативный поток входящего запроса
|
|
68
|
+
- `res: ServerResponse` нативный поток ответа сервера
|
|
69
|
+
- `params: ParsedParams` объект ключ-значение с параметрами пути
|
|
70
|
+
- `query: ParsedQuery` объект ключ-значение с параметрами строки запроса
|
|
71
|
+
- `headers: ParsedHeaders` объект ключ-значение с заголовками запроса
|
|
72
|
+
- `cookie: ParsedCookie` объект ключ-значение разобранного заголовка `cookie`
|
|
73
|
+
- `method: string` метод запроса в верхнем регистре, например `GET`, `POST` и т.д.
|
|
74
|
+
- `path: string` путь включающий строку запроса, например `/myPath?foo=bar`
|
|
75
|
+
- `pathname: string` путь запроса, например `/myMath`
|
|
76
|
+
- `body: unknown` тело запроса
|
|
79
77
|
|
|
80
|
-
|
|
78
|
+
Пример доступа к контексту из обработчика маршрута.
|
|
81
79
|
|
|
82
80
|
```js
|
|
83
81
|
router.defineRoute({
|
|
@@ -100,12 +98,12 @@ router.defineRoute({
|
|
|
100
98
|
});
|
|
101
99
|
```
|
|
102
100
|
|
|
103
|
-
###
|
|
101
|
+
### Отправка ответа
|
|
104
102
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
Возвращаемое значение обработчика маршрута используется в качестве ответа
|
|
104
|
+
сервера. Тип значения влияет на представление возвращаемых данных. Например,
|
|
105
|
+
если результатом будет являться тип `object`, то такое значение автоматически
|
|
106
|
+
сериализуется в JSON.
|
|
109
107
|
|
|
110
108
|
| value | content-type |
|
|
111
109
|
|-----------|--------------------------|
|
|
@@ -116,20 +114,19 @@ serialized to JSON.
|
|
|
116
114
|
| `Buffer` | application/octet-stream |
|
|
117
115
|
| `Stream` | application/octet-stream |
|
|
118
116
|
|
|
119
|
-
|
|
117
|
+
Пример возвращаемого значения обработчиком маршрута.
|
|
120
118
|
|
|
121
119
|
```js
|
|
122
|
-
router.defineRoute({ //
|
|
120
|
+
router.defineRoute({ // регистрация маршрута
|
|
123
121
|
// ...
|
|
124
|
-
handler(ctx) { //
|
|
125
|
-
return {foo: 'bar'}; //
|
|
122
|
+
handler(ctx) { // обработчик входящего запроса
|
|
123
|
+
return {foo: 'bar'}; // ответ будет представлен в виде JSON
|
|
126
124
|
},
|
|
127
125
|
});
|
|
128
126
|
```
|
|
129
127
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
which can be used for manual response management.
|
|
128
|
+
Контекст запроса `ctx` содержит нативный экземпляр класса `ServerResponse`
|
|
129
|
+
модуля `http`, который может быть использован для ручного управления ответом.
|
|
133
130
|
|
|
134
131
|
```js
|
|
135
132
|
router.defineRoute({
|
|
@@ -142,27 +139,27 @@ router.defineRoute({
|
|
|
142
139
|
});
|
|
143
140
|
```
|
|
144
141
|
|
|
145
|
-
###
|
|
142
|
+
### Хуки маршрута
|
|
146
143
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
144
|
+
Определение маршрута методом `defineRoute` позволяет задать хуки
|
|
145
|
+
для отслеживания и перехвата входящего запроса и ответа
|
|
146
|
+
конкретного маршрута.
|
|
150
147
|
|
|
151
|
-
- `preHandler`
|
|
152
|
-
- `postHandler`
|
|
148
|
+
- `preHandler` выполняется перед вызовом обработчика
|
|
149
|
+
- `postHandler` выполняется после вызова обработчика
|
|
153
150
|
|
|
154
151
|
#### preHandler
|
|
155
152
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
153
|
+
Перед вызовом обработчика маршрута может потребоваться выполнение
|
|
154
|
+
таких операции как авторизация и проверка параметров запроса. Для
|
|
155
|
+
этого можно использовать хук `preHandler`.
|
|
159
156
|
|
|
160
157
|
```js
|
|
161
|
-
router.defineRoute({ //
|
|
158
|
+
router.defineRoute({ // регистрация маршрута
|
|
162
159
|
// ...
|
|
163
160
|
preHandler(ctx) {
|
|
164
|
-
//
|
|
165
|
-
console.log(`
|
|
161
|
+
// перед обработчиком маршрута
|
|
162
|
+
console.log(`Incoming request ${ctx.method} ${ctx.path}`);
|
|
166
163
|
// > incoming request GET /myPath
|
|
167
164
|
},
|
|
168
165
|
handler(ctx) {
|
|
@@ -171,86 +168,85 @@ router.defineRoute({ // register a route
|
|
|
171
168
|
});
|
|
172
169
|
```
|
|
173
170
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
171
|
+
Если хук `preHandler` возвращает значение отличное от `undefined` и `null`,
|
|
172
|
+
то такое значение будет использовано в качестве ответа сервера, а вызов
|
|
173
|
+
обработчика маршрута будет пропущен.
|
|
177
174
|
|
|
178
175
|
```js
|
|
179
|
-
router.defineRoute({ //
|
|
176
|
+
router.defineRoute({ // регистрация маршрута
|
|
180
177
|
// ...
|
|
181
178
|
preHandler(ctx) {
|
|
182
|
-
//
|
|
179
|
+
// возвращение ответа сервера
|
|
183
180
|
return 'Are you authorized?';
|
|
184
181
|
},
|
|
185
182
|
handler(ctx) {
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
// has already sent the data
|
|
183
|
+
// данный обработчик не будет вызван, так как
|
|
184
|
+
// хук "preHandler" уже отправил ответ
|
|
189
185
|
},
|
|
190
186
|
});
|
|
191
187
|
```
|
|
192
188
|
|
|
193
189
|
#### postHandler
|
|
194
190
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
191
|
+
Возвращаемое значение обработчика маршрута передается вторым аргументом
|
|
192
|
+
хука `postHandler`. По аналогии с `preHandler`, если возвращаемое
|
|
193
|
+
значение отличается от `undefined` и `null`, то такое значение будет
|
|
194
|
+
использовано в качестве ответа сервера. Это может быть полезно для
|
|
195
|
+
модификации возвращаемого ответа.
|
|
198
196
|
|
|
199
197
|
```js
|
|
200
198
|
router.defineRoute({
|
|
201
199
|
// ...
|
|
202
200
|
handler(ctx) {
|
|
203
|
-
// return the response data
|
|
204
201
|
return 'Hello world!';
|
|
205
202
|
},
|
|
206
203
|
postHandler(ctx, data) {
|
|
207
|
-
//
|
|
204
|
+
// после обработчика маршрута
|
|
208
205
|
return data.toUpperCase(); // HELLO WORLD!
|
|
209
206
|
},
|
|
210
207
|
});
|
|
211
208
|
```
|
|
212
209
|
|
|
213
|
-
###
|
|
210
|
+
### Глобальные хуки
|
|
214
211
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
212
|
+
Экземпляр роутера `TrieRouter` позволяет задать глобальные хуки, которые
|
|
213
|
+
имеют более высокий приоритет перед хуками маршрута, и вызываются
|
|
214
|
+
в первую очередь.
|
|
218
215
|
|
|
219
|
-
- `preHandler`
|
|
220
|
-
- `postHandler`
|
|
216
|
+
- `preHandler` выполняется перед вызовом обработчика каждого маршрута
|
|
217
|
+
- `postHandler` выполняется после вызова обработчика каждого маршрута
|
|
221
218
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
is the hook name and the second is a function.
|
|
219
|
+
Добавить глобальные хуки можно методом `addHook` экземпляра роутера,
|
|
220
|
+
где первым параметром передается название хука, а вторым его функция.
|
|
225
221
|
|
|
226
222
|
```js
|
|
227
223
|
router.addHook('preHandler', (ctx) => {
|
|
228
|
-
//
|
|
224
|
+
// перед обработчиком маршрута
|
|
229
225
|
});
|
|
230
226
|
|
|
231
227
|
router.addHook('postHandler', (ctx, data) => {
|
|
232
|
-
//
|
|
228
|
+
// после обработчика маршрута
|
|
233
229
|
});
|
|
234
230
|
```
|
|
235
231
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
232
|
+
Аналогично хукам маршрута, если глобальный хук возвращает значение
|
|
233
|
+
отличное от `undefined` и `null`, то такое значение будет использовано
|
|
234
|
+
как ответ сервера.
|
|
239
235
|
|
|
240
|
-
##
|
|
236
|
+
## Отладка
|
|
241
237
|
|
|
242
|
-
|
|
238
|
+
Установка переменной `DEBUG` включает вывод логов.
|
|
243
239
|
|
|
244
240
|
```bash
|
|
245
241
|
DEBUG=jsTrieRouter* npm run test
|
|
246
242
|
```
|
|
247
243
|
|
|
248
|
-
##
|
|
244
|
+
## Тестирование
|
|
249
245
|
|
|
250
246
|
```bash
|
|
251
247
|
npm run test
|
|
252
248
|
```
|
|
253
249
|
|
|
254
|
-
##
|
|
250
|
+
## Лицензия
|
|
255
251
|
|
|
256
252
|
MIT
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -29,8 +29,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
30
|
|
|
31
31
|
// src/index.js
|
|
32
|
-
var
|
|
33
|
-
__export(
|
|
32
|
+
var index_exports = {};
|
|
33
|
+
__export(index_exports, {
|
|
34
34
|
BUFFER_ENCODING_LIST: () => BUFFER_ENCODING_LIST,
|
|
35
35
|
BodyParser: () => BodyParser,
|
|
36
36
|
CookieParser: () => CookieParser,
|
|
@@ -66,7 +66,7 @@ __export(src_exports, {
|
|
|
66
66
|
parseJsonBody: () => parseJsonBody,
|
|
67
67
|
toCamelCase: () => toCamelCase
|
|
68
68
|
});
|
|
69
|
-
module.exports = __toCommonJS(
|
|
69
|
+
module.exports = __toCommonJS(index_exports);
|
|
70
70
|
|
|
71
71
|
// src/route.js
|
|
72
72
|
var import_js_format14 = require("@e22m4u/js-format");
|
package/package.json
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e22m4u/js-trie-router",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "HTTP
|
|
3
|
+
"version": "0.0.18",
|
|
4
|
+
"description": "HTTP маршрутизатор для Node.js на основе префиксного дерева",
|
|
5
|
+
"author": "e22m4u <e22m4u@yandex.ru>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"router",
|
|
9
|
+
"trie",
|
|
10
|
+
"http",
|
|
11
|
+
"server",
|
|
12
|
+
"nodejs"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/e22m4u/js-trie-router",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/e22m4u/js-trie-router.git"
|
|
18
|
+
},
|
|
5
19
|
"type": "module",
|
|
6
20
|
"types": "./src/index.d.ts",
|
|
7
21
|
"module": "./src/index.js",
|
|
@@ -23,47 +37,33 @@
|
|
|
23
37
|
"build:cjs": "rimraf ./dist/cjs && node --no-warnings=ExperimentalWarning build-cjs.js",
|
|
24
38
|
"prepare": "husky"
|
|
25
39
|
},
|
|
26
|
-
"repository": {
|
|
27
|
-
"type": "git",
|
|
28
|
-
"url": "git+https://github.com/e22m4u/js-trie-router.git"
|
|
29
|
-
},
|
|
30
|
-
"keywords": [
|
|
31
|
-
"router",
|
|
32
|
-
"trie",
|
|
33
|
-
"http",
|
|
34
|
-
"server",
|
|
35
|
-
"nodejs"
|
|
36
|
-
],
|
|
37
|
-
"author": "e22m4u <e22m4u@yandex.ru>",
|
|
38
|
-
"license": "MIT",
|
|
39
|
-
"homepage": "https://github.com/e22m4u/js-trie-router",
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@e22m4u/js-format": "~0.1.
|
|
42
|
-
"@e22m4u/js-path-trie": "~0.0.
|
|
43
|
-
"@e22m4u/js-service": "~0.
|
|
44
|
-
"debug": "~4.
|
|
41
|
+
"@e22m4u/js-format": "~0.1.0",
|
|
42
|
+
"@e22m4u/js-path-trie": "~0.0.1",
|
|
43
|
+
"@e22m4u/js-service": "~0.2.0",
|
|
44
|
+
"debug": "~4.4.0",
|
|
45
45
|
"http-errors": "~2.0.0",
|
|
46
46
|
"statuses": "~2.0.1"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@commitlint/cli": "~19.
|
|
50
|
-
"@commitlint/config-conventional": "~19.
|
|
51
|
-
"@eslint/js": "~9.
|
|
52
|
-
"@types/chai-as-promised": "~8.0.
|
|
53
|
-
"c8": "~10.1.
|
|
54
|
-
"chai": "~5.
|
|
55
|
-
"chai-as-promised": "~8.0.
|
|
56
|
-
"esbuild": "~0.
|
|
57
|
-
"eslint": "~9.
|
|
58
|
-
"eslint-config-prettier": "~
|
|
49
|
+
"@commitlint/cli": "~19.8.0",
|
|
50
|
+
"@commitlint/config-conventional": "~19.8.0",
|
|
51
|
+
"@eslint/js": "~9.25.1",
|
|
52
|
+
"@types/chai-as-promised": "~8.0.2",
|
|
53
|
+
"c8": "~10.1.3",
|
|
54
|
+
"chai": "~5.2.0",
|
|
55
|
+
"chai-as-promised": "~8.0.1",
|
|
56
|
+
"esbuild": "~0.25.3",
|
|
57
|
+
"eslint": "~9.25.1",
|
|
58
|
+
"eslint-config-prettier": "~10.1.2",
|
|
59
59
|
"eslint-plugin-chai-expect": "~3.1.0",
|
|
60
|
-
"eslint-plugin-jsdoc": "~50.
|
|
60
|
+
"eslint-plugin-jsdoc": "~50.6.10",
|
|
61
61
|
"eslint-plugin-mocha": "~10.5.0",
|
|
62
|
-
"globals": "~
|
|
62
|
+
"globals": "~16.0.0",
|
|
63
63
|
"husky": "~9.1.7",
|
|
64
|
-
"mocha": "~
|
|
65
|
-
"prettier": "~3.
|
|
66
|
-
"rimraf": "
|
|
67
|
-
"typescript": "~5.
|
|
64
|
+
"mocha": "~11.1.0",
|
|
65
|
+
"prettier": "~3.5.3",
|
|
66
|
+
"rimraf": "~6.0.1",
|
|
67
|
+
"typescript": "~5.8.3"
|
|
68
68
|
}
|
|
69
69
|
}
|
package/README-ru.md
DELETED
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
## @e22m4u/js-trie-router
|
|
2
|
-
|
|
3
|
-
*[English](./README.md) | Русский*
|
|
4
|
-
|
|
5
|
-
HTTP роутер для Node.js на основе
|
|
6
|
-
[префиксного дерева](https://ru.wikipedia.org/wiki/Trie) (trie).
|
|
7
|
-
|
|
8
|
-
- Поддержка [path-to-regexp](https://github.com/pillarjs/path-to-regexp) синтаксиса.
|
|
9
|
-
- Автоматический парсинг JSON-тела запроса.
|
|
10
|
-
- Парсинг строки запроса и заголовка `cookie`.
|
|
11
|
-
- Поддержка `preHandler` и `postHandler` хуков.
|
|
12
|
-
- Позволяет использовать асинхронные обработчики.
|
|
13
|
-
|
|
14
|
-
## Установка
|
|
15
|
-
|
|
16
|
-
Требуется Node.js 16 и выше.
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
npm install @e22m4u/js-trie-router
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
Модуль поддерживает ESM и CommonJS стандарты.
|
|
23
|
-
|
|
24
|
-
*ESM*
|
|
25
|
-
|
|
26
|
-
```js
|
|
27
|
-
import {TrieRouter} from '@e22m4u/js-trie-router';
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
*CommonJS*
|
|
31
|
-
|
|
32
|
-
```js
|
|
33
|
-
const {TrieRouter} = require('@e22m4u/js-trie-router');
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Обзор
|
|
37
|
-
|
|
38
|
-
Базовый пример создания экземпляра роутера, объявления маршрута
|
|
39
|
-
и передачи слушателя запросов HTTP серверу.
|
|
40
|
-
|
|
41
|
-
```js
|
|
42
|
-
import http from 'http';
|
|
43
|
-
import {TrieRouter} from '@e22m4u/js-trie-router';
|
|
44
|
-
|
|
45
|
-
const server = new http.Server(); // создание экземпляра HTTP сервера
|
|
46
|
-
const router = new TrieRouter(); // создание экземпляра роутера
|
|
47
|
-
|
|
48
|
-
router.defineRoute({
|
|
49
|
-
method: 'GET', // метод запроса "GET", "POST" и т.д.
|
|
50
|
-
path: '/', // шаблон пути, пример "/user/:id"
|
|
51
|
-
handler(ctx) { // обработчик маршрута
|
|
52
|
-
return 'Hello world!';
|
|
53
|
-
},
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
server.on('request', router.requestListener); // подключение роутера
|
|
57
|
-
server.listen(3000, 'localhost'); // прослушивание запросов
|
|
58
|
-
|
|
59
|
-
// Open in browser http://localhost:3000
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Контекст запроса
|
|
63
|
-
|
|
64
|
-
Первый параметр обработчика маршрута принимает экземпляр класса
|
|
65
|
-
`RequestContext` с набором свойств, содержащих разобранные
|
|
66
|
-
данные входящего запроса.
|
|
67
|
-
|
|
68
|
-
- `container: ServiceContainer` экземпляр [сервис-контейнера](https://npmjs.com/package/@e22m4u/js-service)
|
|
69
|
-
- `req: IncomingMessage` нативный поток входящего запроса
|
|
70
|
-
- `res: ServerResponse` нативный поток ответа сервера
|
|
71
|
-
- `params: ParsedParams` объект ключ-значение с параметрами пути
|
|
72
|
-
- `query: ParsedQuery` объект ключ-значение с параметрами строки запроса
|
|
73
|
-
- `headers: ParsedHeaders` объект ключ-значение с заголовками запроса
|
|
74
|
-
- `cookie: ParsedCookie` объект ключ-значение разобранного заголовка `cookie`
|
|
75
|
-
- `method: string` метод запроса в верхнем регистре, например `GET`, `POST` и т.д.
|
|
76
|
-
- `path: string` путь включающий строку запроса, например `/myPath?foo=bar`
|
|
77
|
-
- `pathname: string` путь запроса, например `/myMath`
|
|
78
|
-
- `body: unknown` тело запроса
|
|
79
|
-
|
|
80
|
-
Пример доступа к контексту из обработчика маршрута.
|
|
81
|
-
|
|
82
|
-
```js
|
|
83
|
-
router.defineRoute({
|
|
84
|
-
method: 'GET',
|
|
85
|
-
path: '/users/:id',
|
|
86
|
-
handler(ctx) {
|
|
87
|
-
// GET /users/10?include=city
|
|
88
|
-
// Cookie: foo=bar; baz=qux;
|
|
89
|
-
console.log(ctx.req); // IncomingMessage
|
|
90
|
-
console.log(ctx.res); // ServerResponse
|
|
91
|
-
console.log(ctx.params); // {id: 10}
|
|
92
|
-
console.log(ctx.query); // {include: 'city'}
|
|
93
|
-
console.log(ctx.headers); // {cookie: 'foo=bar; baz=qux;'}
|
|
94
|
-
console.log(ctx.cookie); // {foo: 'bar', baz: 'qux'}
|
|
95
|
-
console.log(ctx.method); // "GET"
|
|
96
|
-
console.log(ctx.path); // "/users/10?include=city"
|
|
97
|
-
console.log(ctx.pathname); // "/users/10"
|
|
98
|
-
// ...
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Отправка ответа
|
|
104
|
-
|
|
105
|
-
Возвращаемое значение обработчика маршрута используется в качестве ответа
|
|
106
|
-
сервера. Тип значения влияет на представление возвращаемых данных. Например,
|
|
107
|
-
если результатом будет являться тип `object`, то такое значение автоматически
|
|
108
|
-
сериализуется в JSON.
|
|
109
|
-
|
|
110
|
-
| value | content-type |
|
|
111
|
-
|-----------|--------------------------|
|
|
112
|
-
| `string` | text/plain |
|
|
113
|
-
| `number` | application/json |
|
|
114
|
-
| `boolean` | application/json |
|
|
115
|
-
| `object` | application/json |
|
|
116
|
-
| `Buffer` | application/octet-stream |
|
|
117
|
-
| `Stream` | application/octet-stream |
|
|
118
|
-
|
|
119
|
-
Пример возвращаемого значения обработчиком маршрута.
|
|
120
|
-
|
|
121
|
-
```js
|
|
122
|
-
router.defineRoute({ // регистрация маршрута
|
|
123
|
-
// ...
|
|
124
|
-
handler(ctx) { // обработчик входящего запроса
|
|
125
|
-
return {foo: 'bar'}; // ответ будет представлен в виде JSON
|
|
126
|
-
},
|
|
127
|
-
});
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
Контекст запроса `ctx` содержит нативный экземпляр класса `ServerResponse`
|
|
131
|
-
модуля `http`, который может быть использован для ручного управления ответом.
|
|
132
|
-
|
|
133
|
-
```js
|
|
134
|
-
router.defineRoute({
|
|
135
|
-
// ...
|
|
136
|
-
handler(ctx) {
|
|
137
|
-
res.statusCode = 404;
|
|
138
|
-
res.setHeader('content-type', 'text/plain; charset=utf-8');
|
|
139
|
-
res.end('404 Not Found', 'utf-8');
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### Хуки маршрута
|
|
145
|
-
|
|
146
|
-
Определение маршрута методом `defineRoute` позволяет задать хуки
|
|
147
|
-
для отслеживания и перехвата входящего запроса и ответа
|
|
148
|
-
конкретного маршрута.
|
|
149
|
-
|
|
150
|
-
- `preHandler` выполняется перед вызовом обработчика
|
|
151
|
-
- `postHandler` выполняется после вызова обработчика
|
|
152
|
-
|
|
153
|
-
#### preHandler
|
|
154
|
-
|
|
155
|
-
Перед вызовом обработчика маршрута может потребоваться выполнение
|
|
156
|
-
таких операции как авторизация и проверка параметров запроса. Для
|
|
157
|
-
этого можно использовать хук `preHandler`.
|
|
158
|
-
|
|
159
|
-
```js
|
|
160
|
-
router.defineRoute({ // регистрация маршрута
|
|
161
|
-
// ...
|
|
162
|
-
preHandler(ctx) {
|
|
163
|
-
// перед обработчиком маршрута
|
|
164
|
-
console.log(`Incoming request ${ctx.method} ${ctx.path}`);
|
|
165
|
-
// > incoming request GET /myPath
|
|
166
|
-
},
|
|
167
|
-
handler(ctx) {
|
|
168
|
-
return 'Hello world!';
|
|
169
|
-
},
|
|
170
|
-
});
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
Если хук `preHandler` возвращает значение отличное от `undefined` и `null`,
|
|
174
|
-
то такое значение будет использовано в качестве ответа сервера, а вызов
|
|
175
|
-
обработчика маршрута будет пропущен.
|
|
176
|
-
|
|
177
|
-
```js
|
|
178
|
-
router.defineRoute({ // регистрация маршрута
|
|
179
|
-
// ...
|
|
180
|
-
preHandler(ctx) {
|
|
181
|
-
// возвращение ответа сервера
|
|
182
|
-
return 'Are you authorized?';
|
|
183
|
-
},
|
|
184
|
-
handler(ctx) {
|
|
185
|
-
// данный обработчик не будет вызван, так как
|
|
186
|
-
// хук "preHandler" уже отправил ответ
|
|
187
|
-
},
|
|
188
|
-
});
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
#### postHandler
|
|
192
|
-
|
|
193
|
-
Возвращаемое значение обработчика маршрута передается вторым аргументом
|
|
194
|
-
хука `postHandler`. По аналогии с `preHandler`, если возвращаемое
|
|
195
|
-
значение отличается от `undefined` и `null`, то такое значение будет
|
|
196
|
-
использовано в качестве ответа сервера. Это может быть полезно для
|
|
197
|
-
модификации возвращаемого ответа.
|
|
198
|
-
|
|
199
|
-
```js
|
|
200
|
-
router.defineRoute({
|
|
201
|
-
// ...
|
|
202
|
-
handler(ctx) {
|
|
203
|
-
return 'Hello world!';
|
|
204
|
-
},
|
|
205
|
-
postHandler(ctx, data) {
|
|
206
|
-
// после обработчика маршрута
|
|
207
|
-
return data.toUpperCase(); // HELLO WORLD!
|
|
208
|
-
},
|
|
209
|
-
});
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
### Глобальные хуки
|
|
213
|
-
|
|
214
|
-
Экземпляр роутера `TrieRouter` позволяет задать глобальные хуки, которые
|
|
215
|
-
имеют более высокий приоритет перед хуками маршрута, и вызываются
|
|
216
|
-
в первую очередь.
|
|
217
|
-
|
|
218
|
-
- `preHandler` выполняется перед вызовом обработчика каждого маршрута
|
|
219
|
-
- `postHandler` выполняется после вызова обработчика каждого маршрута
|
|
220
|
-
|
|
221
|
-
Добавить глобальные хуки можно методом `addHook` экземпляра роутера,
|
|
222
|
-
где первым параметром передается название хука, а вторым его функция.
|
|
223
|
-
|
|
224
|
-
```js
|
|
225
|
-
router.addHook('preHandler', (ctx) => {
|
|
226
|
-
// перед обработчиком маршрута
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
router.addHook('postHandler', (ctx, data) => {
|
|
230
|
-
// после обработчика маршрута
|
|
231
|
-
});
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
Аналогично хукам маршрута, если глобальный хук возвращает значение
|
|
235
|
-
отличное от `undefined` и `null`, то такое значение будет использовано
|
|
236
|
-
как ответ сервера.
|
|
237
|
-
|
|
238
|
-
## Отладка
|
|
239
|
-
|
|
240
|
-
Установка переменной `DEBUG` включает вывод логов.
|
|
241
|
-
|
|
242
|
-
```bash
|
|
243
|
-
DEBUG=jsTrieRouter* npm run test
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
## Тестирование
|
|
247
|
-
|
|
248
|
-
```bash
|
|
249
|
-
npm run test
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## Лицензия
|
|
253
|
-
|
|
254
|
-
MIT
|