fastify 2.7.1 → 2.11.0
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 +15 -4
- package/build/build-validation.js +8 -0
- package/docs/Benchmarking.md +2 -2
- package/docs/ContentTypeParser.md +12 -10
- package/docs/Decorators.md +14 -14
- package/docs/Ecosystem.md +7 -1
- package/docs/Errors.md +13 -8
- package/docs/Fluent-Schema.md +9 -12
- package/docs/Getting-Started.md +29 -25
- package/docs/HTTP2.md +1 -1
- package/docs/Hooks.md +201 -186
- package/docs/LTS.md +6 -7
- package/docs/Logging.md +10 -10
- package/docs/Middleware.md +59 -0
- package/docs/Plugins-Guide.md +52 -52
- package/docs/Plugins.md +3 -0
- package/docs/Reply.md +47 -3
- package/docs/Routes.md +120 -8
- package/docs/Server.md +69 -3
- package/docs/Serverless.md +76 -4
- package/docs/TypeScript.md +33 -10
- package/docs/Validation-and-Serialization.md +137 -1
- package/examples/typescript-server.ts +1 -1
- package/fastify.d.ts +52 -13
- package/fastify.js +68 -7
- package/lib/configValidator.js +99 -52
- package/lib/contentTypeParser.js +4 -4
- package/lib/context.js +2 -1
- package/lib/errors.js +21 -18
- package/lib/fourOhFour.js +10 -10
- package/lib/handleRequest.js +1 -2
- package/lib/logger.js +2 -2
- package/lib/pluginUtils.js +32 -0
- package/lib/reply.js +41 -6
- package/lib/route.js +37 -9
- package/lib/schemas.js +23 -12
- package/lib/symbols.js +4 -1
- package/lib/validation.js +15 -9
- package/lib/wrapThenable.js +1 -1
- package/package.json +34 -26
- package/test/404s.test.js +41 -1
- package/test/async-await.js +66 -0
- package/test/custom-parser.test.js +1 -1
- package/test/custom-querystring-parser.test.js +1 -1
- package/test/decorator.test.js +48 -0
- package/test/emit-warning.test.js +3 -3
- package/test/fastify-instance.test.js +29 -0
- package/test/helper.js +7 -7
- package/test/hooks-async.js +4 -3
- package/test/hooks.test.js +27 -8
- package/test/input-validation.test.js +126 -0
- package/test/internals/errors.test.js +9 -1
- package/test/internals/initialConfig.test.js +4 -2
- package/test/internals/plugin.test.js +4 -4
- package/test/internals/reply.test.js +78 -6
- package/test/internals/schemas.test.js +30 -0
- package/test/internals/validation.test.js +18 -0
- package/test/listen.test.js +1 -1
- package/test/logger.test.js +314 -1
- package/test/plugin.test.js +171 -0
- package/test/promises.test.js +55 -0
- package/test/proto-poisoning.test.js +76 -0
- package/test/route-hooks.test.js +109 -91
- package/test/route-prefix.test.js +1 -1
- package/test/schemas.test.js +450 -0
- package/test/shared-schemas.test.js +2 -2
- package/test/stream.test.js +10 -6
- package/test/throw.test.js +48 -2
- package/test/types/index.ts +86 -1
- package/test/validation-error-handling.test.js +3 -3
- package/test/versioned-routes.test.js +1 -1
- package/docs/Middlewares.md +0 -59
package/docs/Hooks.md
CHANGED
|
@@ -2,222 +2,170 @@
|
|
|
2
2
|
|
|
3
3
|
## Hooks
|
|
4
4
|
|
|
5
|
-
Hooks are registered with the `fastify.addHook` method and allow you to listen to specific events in the application or request/response lifecycle. You have to register a hook before the event is triggered otherwise the event is lost.
|
|
5
|
+
Hooks are registered with the `fastify.addHook` method and allow you to listen to specific events in the application or request/response lifecycle. You have to register a hook before the event is triggered, otherwise the event is lost.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
By using hooks you can interact directly with the lifecycle of Fastify. There are Request/Reply hooks and application hooks:
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
9
|
+
- [Request/Reply Hooks](#requestreply-hooks)
|
|
10
|
+
- [onRequest](#onrequest)
|
|
11
|
+
- [preParsing](#preparsing)
|
|
12
|
+
- [preValidation](#prevalidation)
|
|
13
|
+
- [preHandler](#prehandler)
|
|
14
|
+
- [preSerialization](#preserialization)
|
|
15
|
+
- [onError](#onerror)
|
|
16
|
+
- [onSend](#onsend)
|
|
17
|
+
- [onResponse](#onresponse)
|
|
18
|
+
- [Application Hooks](#application-hooks)
|
|
19
|
+
- [onClose](#onclose)
|
|
20
|
+
- [onRoute](#onroute)
|
|
21
|
+
- [onRegister](#onregister)
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
```js
|
|
21
|
-
fastify.addHook('onRequest', (request, reply, done) => {
|
|
22
|
-
// some code
|
|
23
|
-
done()
|
|
24
|
-
})
|
|
23
|
+
**Notice:** the `done` callback is not available when using `async`/`await` or returning a `Promise`. If you do invoke a `done` callback in this situation unexpected behaviour may occur, e.g. duplicate invocation of handlers.
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
// some code
|
|
28
|
-
done()
|
|
29
|
-
})
|
|
25
|
+
## Request/Reply Hooks
|
|
30
26
|
|
|
31
|
-
fastify.
|
|
32
|
-
|
|
33
|
-
done()
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
fastify.addHook('preHandler', (request, reply, done) => {
|
|
37
|
-
// some code
|
|
38
|
-
done()
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
fastify.addHook('preSerialization', (request, reply, payload, done) => {
|
|
42
|
-
// some code
|
|
43
|
-
done()
|
|
44
|
-
})
|
|
27
|
+
[Request](https://github.com/fastify/fastify/blob/master/docs/Request.md) and [Reply](https://github.com/fastify/fastify/blob/master/docs/Reply.md) are the core Fastify objects.<br/>
|
|
28
|
+
`done` is the function to continue with the [lifecycle](https://github.com/fastify/fastify/blob/master/docs/Lifecycle.md).
|
|
45
29
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
done()
|
|
49
|
-
})
|
|
30
|
+
It is pretty easy to understand where each hook is executed by looking at the [lifecycle page](https://github.com/fastify/fastify/blob/master/docs/Lifecycle.md).<br>
|
|
31
|
+
Hooks are affected by Fastify's encapsulation, and can thus be applied to selected routes. See the [Scopes](#scope) section for more information.
|
|
50
32
|
|
|
51
|
-
|
|
52
|
-
// some code
|
|
53
|
-
done()
|
|
54
|
-
})
|
|
33
|
+
There are eight different hooks that you can use in Request/Reply *(in order of execution)*:
|
|
55
34
|
|
|
56
|
-
|
|
57
|
-
|
|
35
|
+
### onRequest
|
|
36
|
+
```js
|
|
37
|
+
fastify.addHook('onRequest', (request, reply, done) => {
|
|
38
|
+
// Some code
|
|
58
39
|
done()
|
|
59
40
|
})
|
|
60
41
|
```
|
|
61
|
-
Or `async/await
|
|
42
|
+
Or `async/await`:
|
|
62
43
|
```js
|
|
63
44
|
fastify.addHook('onRequest', async (request, reply) => {
|
|
64
|
-
//
|
|
45
|
+
// Some code
|
|
65
46
|
await asyncMethod()
|
|
66
|
-
//
|
|
47
|
+
// Error occurred
|
|
67
48
|
if (err) {
|
|
68
|
-
throw new Error('
|
|
49
|
+
throw new Error('Some errors occurred.')
|
|
69
50
|
}
|
|
70
51
|
return
|
|
71
52
|
})
|
|
53
|
+
```
|
|
72
54
|
|
|
73
|
-
|
|
74
|
-
// some code
|
|
75
|
-
await asyncMethod()
|
|
76
|
-
// error occurred
|
|
77
|
-
if (err) {
|
|
78
|
-
throw new Error('some errors occurred.')
|
|
79
|
-
}
|
|
80
|
-
return
|
|
81
|
-
})
|
|
55
|
+
**Notice:** in the [onRequest](#onRequest) hook, `request.body` will always be `null`, because the body parsing happens before the [preHandler](#preHandler) hook.
|
|
82
56
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
throw new Error('some errors occurred.')
|
|
89
|
-
}
|
|
90
|
-
return
|
|
57
|
+
### preParsing
|
|
58
|
+
```js
|
|
59
|
+
fastify.addHook('preParsing', (request, reply, done) => {
|
|
60
|
+
// Some code
|
|
61
|
+
done()
|
|
91
62
|
})
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
63
|
+
```
|
|
64
|
+
Or `async/await`:
|
|
65
|
+
```js
|
|
66
|
+
fastify.addHook('preParsing', async (request, reply) => {
|
|
67
|
+
// Some code
|
|
95
68
|
await asyncMethod()
|
|
96
|
-
//
|
|
69
|
+
// Error occurred
|
|
97
70
|
if (err) {
|
|
98
|
-
throw new Error('
|
|
71
|
+
throw new Error('Some errors occurred.')
|
|
99
72
|
}
|
|
100
73
|
return
|
|
101
74
|
})
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
//
|
|
107
|
-
|
|
108
|
-
throw new Error('some errors occurred.')
|
|
109
|
-
}
|
|
110
|
-
return payload
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
fastify.addHook('onError', async (request, reply, error) => {
|
|
114
|
-
// useful for custom error logging
|
|
115
|
-
// you should not use this hook to update the error
|
|
75
|
+
```
|
|
76
|
+
### preValidation
|
|
77
|
+
```js
|
|
78
|
+
fastify.addHook('preValidation', (request, reply, done) => {
|
|
79
|
+
// Some code
|
|
80
|
+
done()
|
|
116
81
|
})
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
82
|
+
```
|
|
83
|
+
Or `async/await`:
|
|
84
|
+
```js
|
|
85
|
+
fastify.addHook('preValidation', async (request, reply) => {
|
|
86
|
+
// Some code
|
|
120
87
|
await asyncMethod()
|
|
121
|
-
//
|
|
88
|
+
// Error occurred
|
|
122
89
|
if (err) {
|
|
123
|
-
throw new Error('
|
|
90
|
+
throw new Error('Some errors occurred.')
|
|
124
91
|
}
|
|
125
92
|
return
|
|
126
93
|
})
|
|
94
|
+
```
|
|
95
|
+
**Notice:** in the [preValidation](#preValidation) hook, `request.body` will always be `null`, because the body parsing happens before the [preHandler](#preHandler) hook.
|
|
127
96
|
|
|
128
|
-
|
|
97
|
+
### preHandler
|
|
98
|
+
```js
|
|
99
|
+
fastify.addHook('preHandler', (request, reply, done) => {
|
|
129
100
|
// some code
|
|
101
|
+
done()
|
|
102
|
+
})
|
|
103
|
+
```
|
|
104
|
+
Or `async/await`:
|
|
105
|
+
```js
|
|
106
|
+
fastify.addHook('preHandler', async (request, reply) => {
|
|
107
|
+
// Some code
|
|
130
108
|
await asyncMethod()
|
|
131
|
-
//
|
|
109
|
+
// Error occurred
|
|
132
110
|
if (err) {
|
|
133
|
-
throw new Error('
|
|
111
|
+
throw new Error('Some errors occurred.')
|
|
134
112
|
}
|
|
135
113
|
return
|
|
136
114
|
})
|
|
137
115
|
```
|
|
116
|
+
### preSerialization
|
|
138
117
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
**Notice:** in the `onRequest` and `preValidation` hooks, `request.body` will always be `null`, because the body parsing happens before the `preHandler` hook.
|
|
142
|
-
|
|
143
|
-
[Request](https://github.com/fastify/fastify/blob/master/docs/Request.md) and [Reply](https://github.com/fastify/fastify/blob/master/docs/Reply.md) are the core Fastify objects.<br/>
|
|
144
|
-
`done` is the function to continue with the [lifecycle](https://github.com/fastify/fastify/blob/master/docs/Lifecycle.md).
|
|
145
|
-
|
|
146
|
-
It is pretty easy to understand where each hook is executed by looking at the [lifecycle page](https://github.com/fastify/fastify/blob/master/docs/Lifecycle.md).<br>
|
|
147
|
-
Hooks are affected by Fastify's encapsulation, and can thus be applied to selected routes. See the [Scopes](#scope) section for more information.
|
|
148
|
-
|
|
149
|
-
If you get an error during the execution of your hook, just pass it to `done()` and Fastify will automatically close the request and send the appropriate error code to the user.
|
|
118
|
+
If you are using the `preSerialization` hook, you can change (or replace) the payload before it is serialized. For example:
|
|
150
119
|
|
|
151
120
|
```js
|
|
152
|
-
fastify.addHook('
|
|
153
|
-
|
|
121
|
+
fastify.addHook('preSerialization', (request, reply, payload, done) => {
|
|
122
|
+
const err = null;
|
|
123
|
+
const newPayload = { wrapped: payload }
|
|
124
|
+
done(err, newPayload)
|
|
154
125
|
})
|
|
155
126
|
```
|
|
156
|
-
|
|
157
|
-
If you want to pass a custom error code to the user, just use `reply.code()`:
|
|
127
|
+
Or `async/await`
|
|
158
128
|
```js
|
|
159
|
-
fastify.addHook('
|
|
160
|
-
|
|
161
|
-
done(new Error('some error'))
|
|
129
|
+
fastify.addHook('preSerialization', async (request, reply, payload) => {
|
|
130
|
+
return { wrapped: payload }
|
|
162
131
|
})
|
|
163
132
|
```
|
|
164
133
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
#### The `onError` Hook
|
|
168
|
-
|
|
169
|
-
This hook is useful if you need to do some custom error logging or add some specific header in case of error.<br/>
|
|
170
|
-
It is not intended for changing the error, and calling `reply.send` will throw an exception.<br/>
|
|
171
|
-
This hook will be executed only after the `customErrorHandler` has been executed, and only if the `customErrorHandler` sends back an error to the user *(Note that the default `customErrorHandler` always send back the error to the user)*.<br/>
|
|
172
|
-
**Notice:** unlike the other hooks, pass an error to the `done` function is not supported.
|
|
134
|
+
Note: the hook is NOT called if the payload is a `string`, a `Buffer`, a `stream` or `null`.
|
|
173
135
|
|
|
136
|
+
### onError
|
|
174
137
|
```js
|
|
175
138
|
fastify.addHook('onError', (request, reply, error, done) => {
|
|
176
|
-
//
|
|
177
|
-
apm.sendError(error)
|
|
139
|
+
// Some code
|
|
178
140
|
done()
|
|
179
141
|
})
|
|
180
|
-
|
|
181
|
-
// Or async
|
|
182
|
-
fastify.addHook('onError', async (request, reply, error) => {
|
|
183
|
-
// apm stands for Application Performance Monitoring
|
|
184
|
-
apm.sendError(error)
|
|
185
|
-
})
|
|
186
142
|
```
|
|
187
|
-
|
|
188
|
-
#### The `preSerialization` Hook
|
|
189
|
-
|
|
190
|
-
If you are using the `preSerialization` hook, you can change (or replace) the payload before it is serialized. For example:
|
|
191
|
-
|
|
143
|
+
Or `async/await`:
|
|
192
144
|
```js
|
|
193
|
-
fastify.addHook('
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
done(err, newPayload)
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
// Or async
|
|
200
|
-
fastify.addHook('preSerialization', async (request, reply, payload) => {
|
|
201
|
-
return {wrapped: payload }
|
|
145
|
+
fastify.addHook('onError', async (request, reply, error) => {
|
|
146
|
+
// Useful for custom error logging
|
|
147
|
+
// You should not use this hook to update the error
|
|
202
148
|
})
|
|
203
149
|
```
|
|
150
|
+
This hook is useful if you need to do some custom error logging or add some specific header in case of error.<br/>
|
|
151
|
+
It is not intended for changing the error, and calling `reply.send` will throw an exception.<br/>
|
|
152
|
+
This hook will be executed only after the `customErrorHandler` has been executed, and only if the `customErrorHandler` sends an error back to the user *(Note that the default `customErrorHandler` always sends the error back to the user)*.<br/>
|
|
153
|
+
**Notice:** unlike the other hooks, pass an error to the `done` function is not supported.
|
|
204
154
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
#### The `onSend` Hook
|
|
208
|
-
|
|
155
|
+
### onSend
|
|
209
156
|
If you are using the `onSend` hook, you can change the payload. For example:
|
|
210
157
|
|
|
211
158
|
```js
|
|
212
159
|
fastify.addHook('onSend', (request, reply, payload, done) => {
|
|
213
|
-
|
|
214
|
-
|
|
160
|
+
const err = null;
|
|
161
|
+
const newPayload = payload.replace('some-text', 'some-new-text')
|
|
215
162
|
done(err, newPayload)
|
|
216
163
|
})
|
|
217
|
-
|
|
218
|
-
|
|
164
|
+
```
|
|
165
|
+
Or `async/await`:
|
|
166
|
+
```js
|
|
219
167
|
fastify.addHook('onSend', async (request, reply, payload) => {
|
|
220
|
-
|
|
168
|
+
const newPayload = payload.replace('some-text', 'some-new-text')
|
|
221
169
|
return newPayload
|
|
222
170
|
})
|
|
223
171
|
```
|
|
@@ -236,15 +184,55 @@ fastify.addHook('onSend', (request, reply, payload, done) => {
|
|
|
236
184
|
|
|
237
185
|
Note: If you change the payload, you may only change it to a `string`, a `Buffer`, a `stream`, or `null`.
|
|
238
186
|
|
|
239
|
-
|
|
240
|
-
|
|
187
|
+
|
|
188
|
+
### onResponse
|
|
189
|
+
```js
|
|
190
|
+
|
|
191
|
+
fastify.addHook('onResponse', (request, reply, done) => {
|
|
192
|
+
// Some code
|
|
193
|
+
done()
|
|
194
|
+
})
|
|
195
|
+
```
|
|
196
|
+
Or `async/await`:
|
|
197
|
+
```js
|
|
198
|
+
fastify.addHook('onResponse', async (request, reply) => {
|
|
199
|
+
// Some code
|
|
200
|
+
await asyncMethod()
|
|
201
|
+
// Error occurred
|
|
202
|
+
if (err) {
|
|
203
|
+
throw new Error('Some errors occurred.')
|
|
204
|
+
}
|
|
205
|
+
return
|
|
206
|
+
})
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
The `onResponse` hook is executed when a response has been sent, so you will not be able to send more data to the client. It can however be useful for sending data to external services, for example to gather statistics.
|
|
210
|
+
|
|
211
|
+
### Manage Errors from a hook
|
|
212
|
+
If you get an error during the execution of your hook, just pass it to `done()` and Fastify will automatically close the request and send the appropriate error code to the user.
|
|
213
|
+
|
|
214
|
+
```js
|
|
215
|
+
fastify.addHook('onRequest', (request, reply, done) => {
|
|
216
|
+
done(new Error('Some error'))
|
|
217
|
+
})
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
If you want to pass a custom error code to the user, just use `reply.code()`:
|
|
221
|
+
```js
|
|
222
|
+
fastify.addHook('preHandler', (request, reply, done) => {
|
|
223
|
+
reply.code(400)
|
|
224
|
+
done(new Error('Some error'))
|
|
225
|
+
})
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
*The error will be handled by [`Reply`](https://github.com/fastify/fastify/blob/master/docs/Reply.md#errors).*
|
|
241
229
|
|
|
242
230
|
### Respond to a request from a hook
|
|
243
|
-
If needed, you can respond to a request before you reach the route handler
|
|
231
|
+
If needed, you can respond to a request before you reach the route handler, for example when implementing an authentication hook. If you are using `onRequest` or `preHandler` use `reply.send`; if you are using a middleware, use `res.end`.
|
|
244
232
|
|
|
245
233
|
```js
|
|
246
234
|
fastify.addHook('onRequest', (request, reply, done) => {
|
|
247
|
-
reply.send('
|
|
235
|
+
reply.send('Early response')
|
|
248
236
|
})
|
|
249
237
|
|
|
250
238
|
// Works with async functions too
|
|
@@ -264,39 +252,55 @@ fastify.addHook('onRequest', (request, reply, done) => {
|
|
|
264
252
|
|
|
265
253
|
## Application Hooks
|
|
266
254
|
|
|
267
|
-
You
|
|
255
|
+
You can hook into the application-lifecycle as well. It's important to note that these hooks aren't fully encapsulated. The `this` inside the hooks are encapsulated but the handlers can respond to an event outside the encapsulation boundaries.
|
|
268
256
|
|
|
269
|
-
-
|
|
270
|
-
-
|
|
271
|
-
-
|
|
257
|
+
- [onClose](#onclose)
|
|
258
|
+
- [onRoute](#onroute)
|
|
259
|
+
- [onRegister](#onregister)
|
|
272
260
|
|
|
273
261
|
<a name="on-close"></a>
|
|
274
|
-
|
|
275
|
-
|
|
262
|
+
|
|
263
|
+
### onClose
|
|
264
|
+
Triggered when `fastify.close()` is invoked to stop the server. It is useful when [plugins](https://github.com/fastify/fastify/blob/master/docs/Plugins.md) need a "shutdown" event, for example to close an open connection to a database.<br>
|
|
276
265
|
The first argument is the Fastify instance, the second one the `done` callback.
|
|
277
266
|
```js
|
|
278
267
|
fastify.addHook('onClose', (instance, done) => {
|
|
279
|
-
//
|
|
268
|
+
// Some code
|
|
280
269
|
done()
|
|
281
270
|
})
|
|
282
271
|
```
|
|
283
272
|
<a name="on-route"></a>
|
|
284
|
-
|
|
273
|
+
### onRoute
|
|
285
274
|
Triggered when a new route is registered. Listeners are passed a `routeOptions` object as the sole parameter. The interface is synchronous, and, as such, the listeners do not get passed a callback.
|
|
286
275
|
```js
|
|
287
276
|
fastify.addHook('onRoute', (routeOptions) => {
|
|
288
|
-
//
|
|
277
|
+
//Some code
|
|
289
278
|
routeOptions.method
|
|
290
279
|
routeOptions.schema
|
|
291
280
|
routeOptions.url
|
|
292
281
|
routeOptions.bodyLimit
|
|
293
282
|
routeOptions.logLevel
|
|
283
|
+
routeOptions.logSerializers
|
|
294
284
|
routeOptions.prefix
|
|
295
285
|
})
|
|
296
286
|
```
|
|
287
|
+
|
|
288
|
+
If you are authoring a plugin and you need to customize application routes, like modifying the options or adding new route hooks, this is the right place.
|
|
289
|
+
|
|
290
|
+
```js
|
|
291
|
+
fastify.addHook('onRoute', (routeOptions) => {
|
|
292
|
+
function onPreSerialization(request, reply, payload, done) {
|
|
293
|
+
// Your code
|
|
294
|
+
done(null, payload)
|
|
295
|
+
}
|
|
296
|
+
// preSerialization can be an array or undefined
|
|
297
|
+
routeOptions.preSerialization = [...(routeOptions.preSerialization || []), onPreSerialization]
|
|
298
|
+
})
|
|
299
|
+
```
|
|
300
|
+
|
|
297
301
|
<a name="on-register"></a>
|
|
298
|
-
|
|
299
|
-
Triggered when a new plugin
|
|
302
|
+
### onRegister
|
|
303
|
+
Triggered when a new plugin is registered and a new encapsulation context is created. The hook will be executed **before** the registered code.<br/>
|
|
300
304
|
This hook can be useful if you are developing a plugin that needs to know when a plugin context is formed, and you want to operate in that specific context.<br/>
|
|
301
305
|
**Note:** This hook will not be called if a plugin is wrapped inside [`fastify-plugin`](https://github.com/fastify/fastify-plugin).
|
|
302
306
|
```js
|
|
@@ -309,19 +313,22 @@ fastify.register(async (instance, opts) => {
|
|
|
309
313
|
instance.register(async (instance, opts) => {
|
|
310
314
|
instance.data.push('world')
|
|
311
315
|
console.log(instance.data) // ['hello', 'world']
|
|
312
|
-
})
|
|
313
|
-
})
|
|
316
|
+
}, { prefix: '/hola' })
|
|
317
|
+
}, { prefix: '/ciao' })
|
|
314
318
|
|
|
315
319
|
fastify.register(async (instance, opts) => {
|
|
316
320
|
console.log(instance.data) // []
|
|
317
|
-
})
|
|
321
|
+
}, { prefix: '/hello' })
|
|
318
322
|
|
|
319
|
-
fastify.addHook('onRegister', (instance) => {
|
|
320
|
-
//
|
|
323
|
+
fastify.addHook('onRegister', (instance, opts) => {
|
|
324
|
+
// Create a new array from the old one
|
|
321
325
|
// but without keeping the reference
|
|
322
326
|
// allowing the user to have encapsulated
|
|
323
327
|
// instances of the `data` property
|
|
324
328
|
instance.data = instance.data.slice()
|
|
329
|
+
|
|
330
|
+
// the options of the new registered instance
|
|
331
|
+
console.log(opts.prefix)
|
|
325
332
|
})
|
|
326
333
|
```
|
|
327
334
|
|
|
@@ -338,38 +345,42 @@ fastify.addHook('onRequest', function (request, reply, done) {
|
|
|
338
345
|
Note: using an arrow function will break the binding of this to the Fastify instance.
|
|
339
346
|
|
|
340
347
|
<a name="route-hooks"></a>
|
|
348
|
+
|
|
341
349
|
## Route level hooks
|
|
342
|
-
You can declare one or more custom
|
|
343
|
-
If you do so, those hooks always
|
|
344
|
-
This can be useful if you need to
|
|
350
|
+
You can declare one or more custom [onRequest](#onRequest), [onReponse](#onResponse), [preParsing](#preParsing), [preValidation](#preValidation), [preHandler](#preHandler) and [preSerialization](#preSerialization) hook(s) that will be **unique** for the route.
|
|
351
|
+
If you do so, those hooks are always executed as the last hook in their category. <br/>
|
|
352
|
+
This can be useful if you need to implement authentication, where the [preParsing](#preParsing) or [preValidation](#preValidation) hooks are exactly what you need.
|
|
345
353
|
Multiple route-level hooks can also be specified as an array.
|
|
346
354
|
|
|
347
|
-
Let's make an example:
|
|
348
|
-
|
|
349
355
|
```js
|
|
350
356
|
fastify.addHook('onRequest', (request, reply, done) => {
|
|
357
|
+
// Your code
|
|
358
|
+
done()
|
|
359
|
+
})
|
|
360
|
+
|
|
361
|
+
fastify.addHook('onResponse', (request, reply, done) => {
|
|
351
362
|
// your code
|
|
352
363
|
done()
|
|
353
364
|
})
|
|
354
365
|
|
|
355
366
|
fastify.addHook('preParsing', (request, reply, done) => {
|
|
356
|
-
//
|
|
367
|
+
// Your code
|
|
357
368
|
done()
|
|
358
369
|
})
|
|
359
370
|
|
|
360
371
|
fastify.addHook('preValidation', (request, reply, done) => {
|
|
361
|
-
//
|
|
372
|
+
// Your code
|
|
362
373
|
done()
|
|
363
374
|
})
|
|
364
375
|
|
|
365
376
|
fastify.addHook('preHandler', (request, reply, done) => {
|
|
366
|
-
//
|
|
377
|
+
// Your code
|
|
367
378
|
done()
|
|
368
379
|
})
|
|
369
380
|
|
|
370
381
|
fastify.addHook('preSerialization', (request, reply, payload, done) => {
|
|
371
|
-
//
|
|
372
|
-
done()
|
|
382
|
+
// Your code
|
|
383
|
+
done(null, payload)
|
|
373
384
|
})
|
|
374
385
|
|
|
375
386
|
fastify.route({
|
|
@@ -377,29 +388,33 @@ fastify.route({
|
|
|
377
388
|
url: '/',
|
|
378
389
|
schema: { ... },
|
|
379
390
|
onRequest: function (request, reply, done) {
|
|
380
|
-
//
|
|
391
|
+
// This hook will always be executed after the shared `onRequest` hooks
|
|
392
|
+
done()
|
|
393
|
+
},
|
|
394
|
+
onResponse: function (request, reply, done) {
|
|
395
|
+
// this hook will always be executed after the shared `onResponse` hooks
|
|
381
396
|
done()
|
|
382
397
|
},
|
|
383
398
|
preParsing: function (request, reply, done) {
|
|
384
|
-
//
|
|
399
|
+
// This hook will always be executed after the shared `preParsing` hooks
|
|
385
400
|
done()
|
|
386
401
|
},
|
|
387
402
|
preValidation: function (request, reply, done) {
|
|
388
|
-
//
|
|
403
|
+
// This hook will always be executed after the shared `preValidation` hooks
|
|
389
404
|
done()
|
|
390
405
|
},
|
|
391
406
|
preHandler: function (request, reply, done) {
|
|
392
|
-
//
|
|
407
|
+
// This hook will always be executed after the shared `preHandler` hooks
|
|
393
408
|
done()
|
|
394
409
|
},
|
|
395
410
|
// // Example with an array. All hooks support this syntax.
|
|
396
411
|
//
|
|
397
412
|
// preHandler: [function (request, reply, done) {
|
|
398
|
-
// //
|
|
413
|
+
// // This hook will always be executed after the shared `preHandler` hooks
|
|
399
414
|
// done()
|
|
400
415
|
// }],
|
|
401
416
|
preSerialization: (request, reply, payload, done) => {
|
|
402
|
-
//
|
|
417
|
+
// This hook will always be executed after the shared `preSerialization` hooks
|
|
403
418
|
done(null, payload)
|
|
404
419
|
},
|
|
405
420
|
handler: function (request, reply) {
|
package/docs/LTS.md
CHANGED
|
@@ -40,10 +40,9 @@ A "month" is to be a period of 30 consecutive days.
|
|
|
40
40
|
|
|
41
41
|
### CI tested operating systems
|
|
42
42
|
|
|
43
|
-
| CI
|
|
44
|
-
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
|
|
49
|
-
_¹ yarn supports only node >= 8_
|
|
43
|
+
| CI | OS | Version | Package Manager | Node.js |
|
|
44
|
+
|----------------|---------|------------------------|---------------------------|-----------|
|
|
45
|
+
| Github Actions | Linux | Ubuntu 16.04 | npm | 6,8,10,12 |
|
|
46
|
+
| Github Actions | Linux | Ubuntu 16.04 | yarn,pnpm | 8,10 |
|
|
47
|
+
| Github Actions | Windows | Windows Server 2016 R2 | npm | 6,8,10,12 |
|
|
48
|
+
| Github Actions | MacOS | macOS X Mojave 10.14 | npm | 6,8,10,12 |
|
package/docs/Logging.md
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
Logging is disabled by default, and you can enable it by passing
|
|
6
6
|
`{ logger: true }` or `{ logger: { level: 'info' } }` when you create
|
|
7
|
-
|
|
7
|
+
a fastify instance. Note that if the logger is disabled, it is impossible to
|
|
8
8
|
enable it at runtime. We use
|
|
9
9
|
[abstract-logging](https://www.npmjs.com/package/abstract-logging) for
|
|
10
10
|
this purpose.
|
|
11
11
|
|
|
12
|
-
Since Fastify is
|
|
12
|
+
Since Fastify is focused on performance, it uses [pino](https://github.com/pinojs/pino) as its logger, with the default log level, when enabled, set to `'info'`.
|
|
13
13
|
|
|
14
14
|
Enabling the logger is extremely easy:
|
|
15
15
|
|
|
@@ -24,14 +24,14 @@ fastify.get('/', options, function (request, reply) {
|
|
|
24
24
|
})
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
If you want to pass some options to the logger, just pass
|
|
28
|
-
You can find all
|
|
27
|
+
If you want to pass some options to the logger, just pass them to Fastify.
|
|
28
|
+
You can find all available options in the [Pino documentation](https://github.com/pinojs/pino/blob/master/docs/api.md#pinooptions-stream). If you want to specify a file destination, use:
|
|
29
29
|
|
|
30
30
|
```js
|
|
31
31
|
const fastify = require('fastify')({
|
|
32
32
|
logger: {
|
|
33
33
|
level: 'info',
|
|
34
|
-
file: '/path/to/file' //
|
|
34
|
+
file: '/path/to/file' // Will use pino.destination()
|
|
35
35
|
}
|
|
36
36
|
})
|
|
37
37
|
|
|
@@ -41,7 +41,7 @@ fastify.get('/', options, function (request, reply) {
|
|
|
41
41
|
})
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
If you want to pass a custom stream to the Pino instance, just add
|
|
44
|
+
If you want to pass a custom stream to the Pino instance, just add a stream field to the logger object.
|
|
45
45
|
|
|
46
46
|
```js
|
|
47
47
|
const split = require('split2')
|
|
@@ -57,9 +57,9 @@ const fastify = require('fastify')({
|
|
|
57
57
|
|
|
58
58
|
<a name="logging-request-id"></a>
|
|
59
59
|
|
|
60
|
-
By default fastify adds an id to every request for easier tracking. If the "request-id" header is present its value is used, otherwise a new incremental id is generated. See Fastify Factory [`requestIdHeader`](https://github.com/fastify/fastify/blob/master/docs/Server.md#factory-request-id-header) and Fastify Factory [`genReqId`](https://github.com/fastify/fastify/blob/master/docs/Server.md#gen-request-id) for customization options.
|
|
60
|
+
By default, fastify adds an id to every request for easier tracking. If the "request-id" header is present its value is used, otherwise a new incremental id is generated. See Fastify Factory [`requestIdHeader`](https://github.com/fastify/fastify/blob/master/docs/Server.md#factory-request-id-header) and Fastify Factory [`genReqId`](https://github.com/fastify/fastify/blob/master/docs/Server.md#gen-request-id) for customization options.
|
|
61
61
|
|
|
62
|
-
The default logger is configured with a set of standard serializers that serialize objects with `req`, `res`, and `err` properties. This
|
|
62
|
+
The default logger is configured with a set of standard serializers that serialize objects with `req`, `res`, and `err` properties. This behaviour can be customized by specifying custom serializers.
|
|
63
63
|
```js
|
|
64
64
|
const fastify = require('fastify')({
|
|
65
65
|
logger: {
|
|
@@ -79,7 +79,7 @@ const fastify = require('fastify')({
|
|
|
79
79
|
prettyPrint: true,
|
|
80
80
|
serializers: {
|
|
81
81
|
res(res) {
|
|
82
|
-
//
|
|
82
|
+
// The default
|
|
83
83
|
return {
|
|
84
84
|
statusCode: res.statusCode
|
|
85
85
|
}
|
|
@@ -103,7 +103,7 @@ const fastify = require('fastify')({
|
|
|
103
103
|
```
|
|
104
104
|
**Note**: The body not can serialize inside `req` method, because the request is serialized when we create the child logger. At that time, the body is not parsed yet.
|
|
105
105
|
|
|
106
|
-
See
|
|
106
|
+
See an approach to log `req.body`
|
|
107
107
|
|
|
108
108
|
```js
|
|
109
109
|
app.addHook('preHandler', function (req, reply, done) {
|