fastify 2.4.1 → 2.7.1

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.
Files changed (51) hide show
  1. package/README.md +1 -1
  2. package/SECURITY.md +33 -0
  3. package/build/build-validation.js +1 -1
  4. package/docs/Decorators.md +2 -2
  5. package/docs/Ecosystem.md +5 -1
  6. package/docs/Fluent-Schema.md +5 -7
  7. package/docs/Hooks.md +40 -40
  8. package/docs/Logging.md +15 -3
  9. package/docs/Plugins-Guide.md +21 -21
  10. package/docs/Plugins.md +11 -11
  11. package/docs/Reply.md +14 -7
  12. package/docs/Routes.md +6 -6
  13. package/docs/Server.md +40 -19
  14. package/docs/Serverless.md +127 -28
  15. package/docs/Validation-and-Serialization.md +15 -12
  16. package/fastify.d.ts +22 -14
  17. package/fastify.js +21 -0
  18. package/lib/context.js +5 -4
  19. package/lib/decorate.js +2 -0
  20. package/lib/errors.js +1 -0
  21. package/lib/handleRequest.js +2 -2
  22. package/lib/reply.js +23 -6
  23. package/lib/request.js +2 -2
  24. package/lib/route.js +24 -15
  25. package/lib/schemas.js +24 -3
  26. package/lib/symbols.js +1 -0
  27. package/lib/validation.js +19 -0
  28. package/package.json +19 -18
  29. package/test/async-await.js +1 -1
  30. package/test/close-pipelining.test.js +43 -2
  31. package/test/close.test.js +69 -12
  32. package/test/content-length.test.js +2 -2
  33. package/test/decorator.test.js +2 -0
  34. package/test/fluent-schema.js +54 -0
  35. package/test/hooks-async.js +80 -1
  36. package/test/hooks.test.js +4 -4
  37. package/test/http2/closing.js +86 -33
  38. package/test/input-validation.test.js +1 -1
  39. package/test/internals/decorator.test.js +2 -0
  40. package/test/internals/initialConfig.test.js +1 -1
  41. package/test/internals/reply.test.js +276 -1
  42. package/test/internals/validation.test.js +57 -0
  43. package/test/logger.test.js +33 -1
  44. package/test/nullable-validation.test.js +52 -0
  45. package/test/plugin.test.js +2 -0
  46. package/test/register.test.js +2 -0
  47. package/test/route-prefix.test.js +31 -0
  48. package/test/route.test.js +35 -0
  49. package/test/shared-schemas.test.js +3 -3
  50. package/test/types/index.ts +33 -2
  51. package/test/versioned-routes.test.js +3 -3
package/README.md CHANGED
@@ -204,12 +204,12 @@ Team members are listed in alphabetical order.
204
204
  ### Collaborators
205
205
  Great contributors on a specific area in the Fastify ecosystem will be invited to join this group by Lead Maintainers.
206
206
 
207
- * [__Trivikram Kamat__](https://github.com/trivikr), <https://twitter.com/trivikram>, <https://www.npmjs.com/~trivikr>
208
207
  * [__Luciano Mammino__](https://github.com/lmammino), <https://twitter.com/loige>, <https://www.npmjs.com/~lmammino>
209
208
  * [__Evan Shortiss__](https://github.com/evanshortiss), <https://twitter.com/evanshortiss>, <https://www.npmjs.com/~evanshortiss>
210
209
 
211
210
  **Past Collaborators**
212
211
  * [__Çağatay Çalı__](https://github.com/cagataycali), <https://twitter.com/cagataycali>, <https://www.npmjs.com/~cagataycali>
212
+ * [__Trivikram Kamat__](https://github.com/trivikr), <https://twitter.com/trivikram>, <https://www.npmjs.com/~trivikr>
213
213
 
214
214
  ## Acknowledgements
215
215
 
package/SECURITY.md ADDED
@@ -0,0 +1,33 @@
1
+ # Security Policy
2
+
3
+ This document describes the management of vulnerabilities for the Fastify project and it's officials' plugins.
4
+
5
+
6
+ ## Reporting vulnerabilities
7
+
8
+ Individuals who find potential vulnerabilities in Fastify are invited to complete a vulnerability report via the dedicated HackerOne tool for Node.js modules: [https://hackerone.com/nodejs-ecosystem](https://hackerone.com/nodejs-ecosystem).
9
+
10
+ ### How to report a vulnerabiliy
11
+
12
+ It is of the utmost importance that you read carefully [**HOW TO REPORT A VULNERABILIY**](https://github.com/nodejs/security-wg/blob/master/processes/third_party_vuln_process.md) written by the Security Working Group of Node.js.
13
+
14
+
15
+ ## Handling vulnerability reports
16
+
17
+ When a potential vulnerability is reported and confirmed the Fastify Core Team will intervene in the
18
+ `follow-up` stage of the process following the workflow and the timings described in the Security WG's document.
19
+
20
+ ### Vulnerabilities found outside this process
21
+
22
+ ⚠ The Fastify project does not support any reporting outside the HackerOne process.
23
+
24
+
25
+ ## The Fastify Core team
26
+
27
+ The core team is responsible for the management of [this](https://github.com/nodejs/security-wg/blob/master/processes/third_party_vuln_process.md#handling-vulnerability-reports) process.
28
+
29
+ Members of this team are expected to keep all information that they have privileged access to by being
30
+ on the team completely private to the team. This includes agreeing to not notify anyone outside the
31
+ team of issues that have not yet been disclosed publicly, including the existence of issues,
32
+ expectations of upcoming releases, and patching of any issues other than in the process of their work
33
+ as a member of the Fastify Core team.
@@ -72,7 +72,7 @@ const schema = {
72
72
 
73
73
  const validate = ajv.compile(schema)
74
74
 
75
- let moduleCode = `// This file is autogenerated by ${__filename.replace(__dirname, 'build')}, do not edit
75
+ const moduleCode = `// This file is autogenerated by ${__filename.replace(__dirname, 'build')}, do not edit
76
76
  /* istanbul ignore file */
77
77
  // constant needed for customRule0 to work
78
78
  const self = {}
@@ -137,9 +137,9 @@ As an example let's add a user property to the `Request` object:
137
137
  fastify.decorateRequest('user', '')
138
138
 
139
139
  // Update our property
140
- fastify.addHook('preHandler', (req, reply, next) => {
140
+ fastify.addHook('preHandler', (req, reply, done) => {
141
141
  req.user = 'Bob Dylan'
142
- next()
142
+ done()
143
143
  })
144
144
  // And finally access it
145
145
  fastify.get('/', (req, reply) => {
package/docs/Ecosystem.md CHANGED
@@ -47,7 +47,9 @@ Plugins maintained by the fastify team are listed under [Core](#core) while plug
47
47
 
48
48
  - [`apollo-server-fastify`](https://github.com/apollographql/apollo-server/tree/master/packages/apollo-server-fastify) Run an [Apollo Server](https://github.com/apollographql/apollo-server) to serve GraphQL with Fastify.
49
49
  - [`arecibo`](https://github.com/nucleode/arecibo) Fastify ping responder for Kubernetes Liveness and Readiness Probes.
50
+ - [`cls-rtracer`](https://github.com/puzpuzpuz/cls-rtracer) Fastify middleware for CLS-based request id generation. An out-of-the-box solution for adding request ids into your logs.
50
51
  - [`fastify-405`](https://github.com/Eomm/fastify-405) Fastify plugin that adds 405 HTTP status to your routes
52
+ - [`fastify-amqp`](https://github.com/RafaelGSS/fastify-amqp) Fastify AMQP connection plugin, to use with RabbitMQ or another connector. Just a wrapper to [`amqplib`](https://github.com/squaremo/amqp.node).
51
53
  - [`fastify-angular-universal`](https://github.com/exequiel09/fastify-angular-universal) Angular server-side rendering support using [`@angular/platform-server`](https://github.com/angular/angular/tree/master/packages/platform-server) for Fastify
52
54
  - [`fastify-babel`](https://github.com/cfware/fastify-babel) Fastify plugin for development servers which require babel transformations of JavaScript sources.
53
55
  - [`fastify-blipp`](https://github.com/PavelPolyakov/fastify-blipp) Prints your routes to the console, so you definitely know which endpoints are available.
@@ -88,16 +90,18 @@ Plugins maintained by the fastify team are listed under [Core](#core) while plug
88
90
  - [`fastify-mongoose-driver`](https://github.com/alex-ppg/fastify-mongoose) Fastify Mongoose plugin that connects to a MongoDB via the Mongoose plugin with support for Models.
89
91
  - [`fastify-multer`](https://github.com/fox1t/multer) Multer is a plugin for handling multipart/form-data, which is primarily used for uploading files.
90
92
  - [`fastify-nats`](https://github.com/mahmed8003/fastify-nats) Plugin to share [NATS](http://nats.io) client across Fastify.
93
+ - [`fastify-no-additional-properties`](https://github.com/greguz/fastify-no-additional-properties) Add `additionalProperties: false` by default to your JSON Schemas.
91
94
  - [`fastify-no-icon`](https://github.com/jsumners/fastify-no-icon) Plugin to eliminate thrown errors for `/favicon.ico` requests.
92
95
  - [`fastify-nodemailer`](https://github.com/lependu/fastify-nodemailer) Plugin to share [nodemailer](http://nodemailer.com) transporter across Fastify.
93
96
  - [`fastify-normalize-request-reply`](https://github.com/ericrglass/fastify-normalize-request-reply) Plugin to normalize the request and reply to the Express version 4.x request and response, which allows use of middleware, like swagger-stats, that was originally written for Express.
94
- - [`fastify-nuxt`](https://github.com/lyquocnam/fastify-nuxt) VueJS server side rendering support for Fastify with [`NuxtJS`](https://nuxtjs.org/)
95
97
  - [`fastify-oas`](https://gitlab.com/m03geek/fastify-oas) Generates OpenAPI 3.0+ documentation from routes schemas for Fastify.
96
98
  - [`fastify-openapi-glue`](https://github.com/seriousme/fastify-openapi-glue) Glue for Open Api specifications in Fastify, autogenerates routes based on an Open Api Specification
97
99
  - [`fastify-oracle`](https://github.com/cemremengu/fastify-oracle) Attaches an [`oracledb`](https://github.com/oracle/node-oracledb) connection pool to a Fastify server instance.
98
100
  - [`fastify-orientdb`](https://github.com/mahmed8003/fastify-orientdb) Fastify OrientDB connection plugin, with which you can share the OrientDB connection across every part of your server.
101
+ - [`fastify-rbac`](https://gitlab.com/m03geek/fastify-rbac) Fastify role-based access control plugin.
99
102
  - [`fastify-register-routes`](https://github.com/israeleriston/fastify-register-routes) Plugin to automatically load routes from a specified path and optionally limit loaded file names by a regular expression.
100
103
  - [`fastify-response-time`](https://github.com/lolo32/fastify-response-time) Add `X-Response-Time` header at each request for Fastify, in milliseconds.
104
+ - [`fastify-reverse-routes`](https://github.com/dimonnwc3/fastify-reverse-routes) Fastify reverse routes plugin, allows to defined named routes and build path using name and parameters.
101
105
  - [`fastify-rob-config`](https://github.com/jeromemacias/fastify-rob-config) Fastify Rob-Config integration.
102
106
  - [`fastify-schema-constraint`](https://github.com/Eomm/fastify-schema-constraint) Choose the JSON schema to use based on request parameters.
103
107
  - [`fastify-sentry`](https://github.com/alex-ppg/fastify-sentry) Fastify plugin to add the Sentry SDK error handler to requests.
@@ -41,11 +41,12 @@ const paramsJsonSchema = S.object()
41
41
  const headersJsonSchema = S.object()
42
42
  .prop('x-foo', S.string().required())
43
43
 
44
+ // note that there is no need to call `.valueOf()`!
44
45
  const schema = {
45
- body: bodyJsonSchema.valueOf(),
46
- querystring: queryStringJsonSchema.valueOf(),
47
- params: paramsJsonSchema.valueOf(),
48
- headers: headersJsonSchema.valueOf()
46
+ body: bodyJsonSchema,
47
+ querystring: queryStringJsonSchema, // (or) query: queryStringJsonSchema
48
+ params: paramsJsonSchema,
49
+ headers: headersJsonSchema
49
50
  }
50
51
 
51
52
  fastify.post('/the/url', { schema }, handler)
@@ -69,20 +70,17 @@ const addressSchema = S.object()
69
70
  .prop('country').required()
70
71
  .prop('city').required()
71
72
  .prop('zipcode').required()
72
- .valueOf()
73
73
 
74
74
  const commonSchemas = S.object()
75
75
  .id('https://fastify/demo')
76
76
  .definition('addressSchema', addressSchema)
77
77
  .definition('otherSchema', otherSchema) // you can add any schemas you need
78
- .valueOf()
79
78
 
80
79
  fastify.addSchema(commonSchemas)
81
80
 
82
81
  const bodyJsonSchema = S.object()
83
82
  .prop('residence', S.ref('https://fastify/demo#address')).required()
84
83
  .prop('office', S.ref('https://fastify/demo#/definitions/addressSchema')).required()
85
- .valueOf()
86
84
 
87
85
  const schema = { body: bodyJsonSchema }
88
86
 
package/docs/Hooks.md CHANGED
@@ -18,44 +18,44 @@ By using the hooks you can interact directly inside the lifecycle of Fastify. Th
18
18
 
19
19
  Example:
20
20
  ```js
21
- fastify.addHook('onRequest', (request, reply, next) => {
21
+ fastify.addHook('onRequest', (request, reply, done) => {
22
22
  // some code
23
- next()
23
+ done()
24
24
  })
25
25
 
26
- fastify.addHook('preParsing', (request, reply, next) => {
26
+ fastify.addHook('preParsing', (request, reply, done) => {
27
27
  // some code
28
- next()
28
+ done()
29
29
  })
30
30
 
31
- fastify.addHook('preValidation', (request, reply, next) => {
31
+ fastify.addHook('preValidation', (request, reply, done) => {
32
32
  // some code
33
- next()
33
+ done()
34
34
  })
35
35
 
36
- fastify.addHook('preHandler', (request, reply, next) => {
36
+ fastify.addHook('preHandler', (request, reply, done) => {
37
37
  // some code
38
- next()
38
+ done()
39
39
  })
40
40
 
41
- fastify.addHook('preSerialization', (request, reply, payload, next) => {
41
+ fastify.addHook('preSerialization', (request, reply, payload, done) => {
42
42
  // some code
43
- next()
43
+ done()
44
44
  })
45
45
 
46
- fastify.addHook('onError', (request, reply, error, next) => {
46
+ fastify.addHook('onError', (request, reply, error, done) => {
47
47
  // some code
48
- next()
48
+ done()
49
49
  })
50
50
 
51
- fastify.addHook('onSend', (request, reply, payload, next) => {
51
+ fastify.addHook('onSend', (request, reply, payload, done) => {
52
52
  // some code
53
- next()
53
+ done()
54
54
  })
55
55
 
56
- fastify.addHook('onResponse', (request, reply, next) => {
56
+ fastify.addHook('onResponse', (request, reply, done) => {
57
57
  // some code
58
- next()
58
+ done()
59
59
  })
60
60
  ```
61
61
  Or `async/await`
@@ -136,29 +136,29 @@ fastify.addHook('onResponse', async (request, reply) => {
136
136
  })
137
137
  ```
138
138
 
139
- **Notice:** the `next` callback is not available when using `async`/`await` or returning a `Promise`. If you do invoke a `next` callback in this situation unexpected behavior may occur, e.g. duplicate invocation of handlers.
139
+ **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 behavior may occur, e.g. duplicate invocation of handlers.
140
140
 
141
141
  **Notice:** in the `onRequest` and `preValidation` hooks, `request.body` will always be `null`, because the body parsing happens before the `preHandler` hook.
142
142
 
143
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
- `next` is the function to continue with the [lifecycle](https://github.com/fastify/fastify/blob/master/docs/Lifecycle.md).
144
+ `done` is the function to continue with the [lifecycle](https://github.com/fastify/fastify/blob/master/docs/Lifecycle.md).
145
145
 
146
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
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
148
 
149
- If you get an error during the execution of your hook, just pass it to `next()` and Fastify will automatically close the request and send the appropriate error code to the user.
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.
150
150
 
151
151
  ```js
152
- fastify.addHook('onRequest', (request, reply, next) => {
153
- next(new Error('some error'))
152
+ fastify.addHook('onRequest', (request, reply, done) => {
153
+ done(new Error('some error'))
154
154
  })
155
155
  ```
156
156
 
157
157
  If you want to pass a custom error code to the user, just use `reply.code()`:
158
158
  ```js
159
- fastify.addHook('preHandler', (request, reply, next) => {
159
+ fastify.addHook('preHandler', (request, reply, done) => {
160
160
  reply.code(400)
161
- next(new Error('some error'))
161
+ done(new Error('some error'))
162
162
  })
163
163
  ```
164
164
 
@@ -169,13 +169,13 @@ fastify.addHook('preHandler', (request, reply, next) => {
169
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
170
  It is not intended for changing the error, and calling `reply.send` will throw an exception.<br/>
171
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 `next` function is not supported.
172
+ **Notice:** unlike the other hooks, pass an error to the `done` function is not supported.
173
173
 
174
174
  ```js
175
- fastify.addHook('onError', (request, reply, error, next) => {
175
+ fastify.addHook('onError', (request, reply, error, done) => {
176
176
  // apm stands for Application Performance Monitoring
177
177
  apm.sendError(error)
178
- next()
178
+ done()
179
179
  })
180
180
 
181
181
  // Or async
@@ -190,10 +190,10 @@ fastify.addHook('onError', async (request, reply, error) => {
190
190
  If you are using the `preSerialization` hook, you can change (or replace) the payload before it is serialized. For example:
191
191
 
192
192
  ```js
193
- fastify.addHook('preSerialization', (request, reply, payload, next) => {
193
+ fastify.addHook('preSerialization', (request, reply, payload, done) => {
194
194
  var err = null;
195
195
  var newPayload = {wrapped: payload }
196
- next(err, newPayload)
196
+ done(err, newPayload)
197
197
  })
198
198
 
199
199
  // Or async
@@ -209,10 +209,10 @@ Note: the hook is NOT called if the payload is a `string`, a `Buffer`, a `strea
209
209
  If you are using the `onSend` hook, you can change the payload. For example:
210
210
 
211
211
  ```js
212
- fastify.addHook('onSend', (request, reply, payload, next) => {
212
+ fastify.addHook('onSend', (request, reply, payload, done) => {
213
213
  var err = null;
214
214
  var newPayload = payload.replace('some-text', 'some-new-text')
215
- next(err, newPayload)
215
+ done(err, newPayload)
216
216
  })
217
217
 
218
218
  // Or async
@@ -225,10 +225,10 @@ fastify.addHook('onSend', async (request, reply, payload) => {
225
225
  You can also clear the payload to send a response with an empty body by replacing the payload with `null`:
226
226
 
227
227
  ```js
228
- fastify.addHook('onSend', (request, reply, payload, next) => {
228
+ fastify.addHook('onSend', (request, reply, payload, done) => {
229
229
  reply.code(304)
230
230
  const newPayload = null
231
- next(null, newPayload)
231
+ done(null, newPayload)
232
232
  })
233
233
  ```
234
234
 
@@ -243,7 +243,7 @@ The `onResponse` hook is executed when a response has been sent, so you will not
243
243
  If needed, you can respond to a request before you reach the route handler. An example could be an authentication hook. If you are using `onRequest` or `preHandler` use `reply.send`; if you are using a middleware, `res.end`.
244
244
 
245
245
  ```js
246
- fastify.addHook('onRequest', (request, reply, next) => {
246
+ fastify.addHook('onRequest', (request, reply, done) => {
247
247
  reply.send('early response')
248
248
  })
249
249
 
@@ -256,7 +256,7 @@ fastify.addHook('preHandler', async (request, reply) => {
256
256
  If you want to respond with a stream, you should avoid using an `async` function for the hook. If you must use an `async` function, your code will need to follow the pattern in [test/hooks-async.js](https://github.com/fastify/fastify/blob/94ea67ef2d8dce8a955d510cd9081aabd036fa85/test/hooks-async.js#L269-L275).
257
257
 
258
258
  ```js
259
- fastify.addHook('onRequest', (request, reply, next) => {
259
+ fastify.addHook('onRequest', (request, reply, done) => {
260
260
  const stream = fs.createReadStream('some-file', 'utf8')
261
261
  reply.send(stream)
262
262
  })
@@ -330,16 +330,16 @@ fastify.addHook('onRegister', (instance) => {
330
330
  Except for [Application Hooks](#application-hooks), all hooks are encapsulated. This means that you can decide where your hooks should run by using `register` as explained in the [plugins guide](https://github.com/fastify/fastify/blob/master/docs/Plugins-Guide.md). If you pass a function, that function is bound to the right Fastify context and from there you have full access to the Fastify API.
331
331
 
332
332
  ```js
333
- fastify.addHook('onRequest', function (request, reply, next) {
333
+ fastify.addHook('onRequest', function (request, reply, done) {
334
334
  const self = this // Fastify context
335
- next()
335
+ done()
336
336
  })
337
337
  ```
338
338
  Note: using an arrow function will break the binding of this to the Fastify instance.
339
339
 
340
340
  <a name="route-hooks"></a>
341
341
  ## Route level hooks
342
- You can declare one or more custom `onRequest`, `preParsing`, `preValidation`, `preHandler` and `preSerialization` hook(s) that will be unique for the route.
342
+ You can declare one or more custom `onRequest`, `preParsing`, `preValidation`, `preHandler` and `preSerialization` hook(s) that will be **unique** for the route.
343
343
  If you do so, those hooks always be executed as last hook in their category. <br/>
344
344
  This can be useful if you need to run the authentication, and the `preParsing` or `preValidation` hooks are exactly what you need for doing that.
345
345
  Multiple route-level hooks can also be specified as an array.
@@ -367,7 +367,7 @@ fastify.addHook('preHandler', (request, reply, done) => {
367
367
  done()
368
368
  })
369
369
 
370
- fastify.addHook('preSerialization', (request, reply, done) => {
370
+ fastify.addHook('preSerialization', (request, reply, payload, done) => {
371
371
  // your code
372
372
  done()
373
373
  })
@@ -398,9 +398,9 @@ fastify.route({
398
398
  // // this hook will always be executed after the shared `preHandler` hooks
399
399
  // done()
400
400
  // }],
401
- preSerialization: (request, reply, payload, next) => {
401
+ preSerialization: (request, reply, payload, done) => {
402
402
  // manipulate the payload
403
- next(null, payload)
403
+ done(null, payload)
404
404
  },
405
405
  handler: function (request, reply) {
406
406
  reply.send({ hello: 'world' })
package/docs/Logging.md CHANGED
@@ -71,7 +71,7 @@ const fastify = require('fastify')({
71
71
  }
72
72
  })
73
73
  ```
74
- For example, the response payload and headers could be logged using the approach below (even if it is *not* recommended*):
74
+ For example, the response payload and headers could be logged using the approach below (even if it is *not recommended*):
75
75
 
76
76
  ```js
77
77
  const fastify = require('fastify')({
@@ -90,11 +90,10 @@ const fastify = require('fastify')({
90
90
  url: req.url,
91
91
  path: req.path,
92
92
  parameters: req.parameters,
93
- // Including the body and headers in the log could be in violation
93
+ // Including the headers in the log could be in violation
94
94
  // of privacy laws, e.g. GDPR. You should use the "redact" option to
95
95
  // remove sensitive fields. It could also leak authentication data in
96
96
  // the logs.
97
- body: req.body,
98
97
  headers: req.headers
99
98
  };
100
99
  }
@@ -102,6 +101,19 @@ const fastify = require('fastify')({
102
101
  }
103
102
  });
104
103
  ```
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
+
106
+ See a approach to log `req.body`
107
+
108
+ ```js
109
+ app.addHook('preHandler', function (req, reply, done) {
110
+ if (req.body) {
111
+ req.log.info({ body: req.body }, 'parsed body')
112
+ }
113
+ done()
114
+ })
115
+ ```
116
+
105
117
 
106
118
  *This option will be ignored by any logger other than Pino.*
107
119
 
@@ -35,20 +35,20 @@ Fastify helps you a lot in this direction, because thanks to the encapsulation m
35
35
  *Let's return to how to correctly use `register`.*<br>
36
36
  As you probably know, the required plugins must expose a single function with the following signature
37
37
  ```js
38
- module.exports = function (fastify, options, next) {}
38
+ module.exports = function (fastify, options, done) {}
39
39
  ```
40
- Where `fastify` is (pretty obvious) the encapsulated Fastify instance, `options` is the options object and `next` is the function you **must** call when your plugin is ready.
40
+ Where `fastify` is (pretty obvious) the encapsulated Fastify instance, `options` is the options object and `done` is the function you **must** call when your plugin is ready.
41
41
 
42
42
  Fastify's plugin model is fully reentrant and graph-based, it handles without any kind of problem asynchronous code and it guarantees the load order of the plugins, even the close order! *How?* Glad you asked, checkout [`avvio`](https://github.com/mcollina/avvio)! Fastify starts loading the plugin __after__ `.listen()`, `.inject()` or `.ready()` are called.
43
43
 
44
- Inside a plugin you can do whatever you want, register routes, utilities (we'll see this in a moment) and do nested registers, just remember to call `next` when everything is set up!
44
+ Inside a plugin you can do whatever you want, register routes, utilities (we'll see this in a moment) and do nested registers, just remember to call `done` when everything is set up!
45
45
  ```js
46
- module.exports = function (fastify, options, next) {
46
+ module.exports = function (fastify, options, done) {
47
47
  fastify.get('/plugin', (request, reply) => {
48
48
  reply.send({ hello: 'world' })
49
49
  })
50
50
 
51
- next()
51
+ done()
52
52
  }
53
53
  ```
54
54
 
@@ -77,38 +77,38 @@ fastify.decorate('util', (a, b) => a + b)
77
77
  Now you can access your utility just by doing `fastify.util` whenever you need it, even inside your test.<br>
78
78
  And here's starts the magic; do you remember that few lines above we talked about encapsulation? Well, using `register` and `decorate` in conjunction enable exactly that, let me show you an example to clarify this:
79
79
  ```js
80
- fastify.register((instance, opts, next) => {
80
+ fastify.register((instance, opts, done) => {
81
81
  instance.decorate('util', (a, b) => a + b)
82
82
  console.log(instance.util('that is ', ' awesome'))
83
83
 
84
- next()
84
+ done()
85
85
  })
86
86
 
87
- fastify.register((instance, opts, next) => {
87
+ fastify.register((instance, opts, done) => {
88
88
  console.log(instance.util('that is ', ' awesome')) // this will throw an error
89
89
 
90
- next()
90
+ done()
91
91
  })
92
92
  ```
93
93
  Inside the second register call `instance.util` will throw an error, because `util` exists only inside the first register context.<br>
94
94
  Let's step back for a moment and get deeper on this: when using the `register` api you will create a new context every time and this avoids situations like the one mentioned few line above. But pay attention, the encapsulation works only for the ancestors and the brothers, but not for the sons.
95
95
  ```js
96
- fastify.register((instance, opts, next) => {
96
+ fastify.register((instance, opts, done) => {
97
97
  instance.decorate('util', (a, b) => a + b)
98
98
  console.log(instance.util('that is ', ' awesome'))
99
99
 
100
- fastify.register((instance, opts, next) => {
100
+ fastify.register((instance, opts, done) => {
101
101
  console.log(instance.util('that is ', ' awesome')) // this will not throw an error
102
- next()
102
+ done()
103
103
  })
104
104
 
105
- next()
105
+ done()
106
106
  })
107
107
 
108
- fastify.register((instance, opts, next) => {
108
+ fastify.register((instance, opts, done) => {
109
109
  console.log(instance.util('that is ', ' awesome')) // this will throw an error
110
110
 
111
- next()
111
+ done()
112
112
  })
113
113
  ```
114
114
  *Take home message: if you need that an utility is available in every part of your application, pay attention that is declared at the root scope of your application. Otherwise you can use `fastify-plugin` utility as described [here](#distribution).*
@@ -214,7 +214,7 @@ Now for every request you will run your utility, it is obvious that you can regi
214
214
  It can happen that you want a hook that must be executed just for a subset of routes, how can you do that? Yep, encapsulation!
215
215
 
216
216
  ```js
217
- fastify.register((instance, opts, next) => {
217
+ fastify.register((instance, opts, done) => {
218
218
  instance.decorate('util', (request, key, value) => { request[key] = value })
219
219
 
220
220
  instance.addHook('preHandler', (request, reply, done) => {
@@ -226,7 +226,7 @@ fastify.register((instance, opts, next) => {
226
226
  reply.send(request)
227
227
  })
228
228
 
229
- next()
229
+ done()
230
230
  })
231
231
 
232
232
  fastify.get('/plugin2', (request, reply) => {
@@ -260,10 +260,10 @@ Yes, I said that. But what I didn't tell you, is that you can tell to Fastify to
260
260
  const fp = require('fastify-plugin')
261
261
  const dbClient = require('db-client')
262
262
 
263
- function dbPlugin (fastify, opts, next) {
263
+ function dbPlugin (fastify, opts, done) {
264
264
  dbClient.connect(opts.url, (err, conn) => {
265
265
  fastify.decorate('db', conn)
266
- next()
266
+ done()
267
267
  })
268
268
  }
269
269
 
@@ -279,10 +279,10 @@ const fastify = require('fastify')()
279
279
  const fp = require('fastify-plugin')
280
280
  const dbClient = require('db-client')
281
281
 
282
- function dbPlugin (fastify, opts, next) {
282
+ function dbPlugin (fastify, opts, done) {
283
283
  dbClient.connect(opts.url, (err, conn) => {
284
284
  fastify.decorate('db', conn)
285
- next()
285
+ done()
286
286
  })
287
287
  }
288
288
 
package/docs/Plugins.md CHANGED
@@ -45,10 +45,10 @@ The `options` parameter can also be a `Function` which will be evaluated at the
45
45
  ```js
46
46
  const fp = require('fastify-plugin')
47
47
 
48
- fastify.register(fp((fastify, opts, next) => {
48
+ fastify.register(fp((fastify, opts, done) => {
49
49
  fastify.decorate('foo_bar', { hello: 'world' })
50
50
 
51
- next()
51
+ done()
52
52
  }))
53
53
 
54
54
  // The opts argument of fastify-foo will be { hello: 'world' }
@@ -97,27 +97,27 @@ await fastify.listen(3000)
97
97
  ```
98
98
  <a name="create-plugin"></a>
99
99
  ### Create a plugin
100
- Creating a plugin is very easy, you just need to create a function that takes three parameters, the `fastify` instance, an options object and the next callback.<br>
100
+ Creating a plugin is very easy, you just need to create a function that takes three parameters, the `fastify` instance, an `options` object and the `done` callback.<br>
101
101
  Example:
102
102
  ```js
103
- module.exports = function (fastify, opts, next) {
103
+ module.exports = function (fastify, opts, done) {
104
104
  fastify.decorate('utility', () => {})
105
105
 
106
106
  fastify.get('/', handler)
107
107
 
108
- next()
108
+ done()
109
109
  }
110
110
  ```
111
111
  You can also use `register` inside another `register`:
112
112
  ```js
113
- module.exports = function (fastify, opts, next) {
113
+ module.exports = function (fastify, opts, done) {
114
114
  fastify.decorate('utility', () => {})
115
115
 
116
116
  fastify.get('/', handler)
117
117
 
118
118
  fastify.register(require('./other-plugin'))
119
119
 
120
- next()
120
+ done()
121
121
  }
122
122
  ```
123
123
  Sometimes, you will need to know when the server is about to close, for example because you must close a connection to a database. To know when this is going to happen, you can use the [`'onClose'`](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#on-close) hook.
@@ -136,18 +136,18 @@ We recommend to using the `fastify-plugin` module, because it solves this proble
136
136
  ```js
137
137
  const fp = require('fastify-plugin')
138
138
 
139
- module.exports = fp(function (fastify, opts, next) {
139
+ module.exports = fp(function (fastify, opts, done) {
140
140
  fastify.decorate('utility', () => {})
141
- next()
141
+ done()
142
142
  }, '0.x')
143
143
  ```
144
144
  Check the [`fastify-plugin`](https://github.com/fastify/fastify-plugin) documentation to know more about how use this module.
145
145
 
146
146
  If you don't use the `fastify-plugin` module, you can use the `'skip-override'` hidden property, but we do not recommend it. If in the future the Fastify API changes it will be a your responsibility update the module, while if you use `fastify-plugin`, you can be sure about backwards compatibility.
147
147
  ```js
148
- function yourPlugin (fastify, opts, next) {
148
+ function yourPlugin (fastify, opts, done) {
149
149
  fastify.decorate('utility', () => {})
150
- next()
150
+ done()
151
151
  }
152
152
  yourPlugin[Symbol.for('skip-override')] = true
153
153
  module.exports = yourPlugin
package/docs/Reply.md CHANGED
@@ -10,6 +10,7 @@
10
10
  - [.hasHeader(key)](#hasheaderkey)
11
11
  - [.redirect(dest)](#redirectdest)
12
12
  - [.callNotFound()](#callnotfound)
13
+ - [.getResponseTime()](#getresponsetime)
13
14
  - [.type(contentType)](#typecontenttype)
14
15
  - [.serializer(func)](#serializerfunc)
15
16
  - [.sent](#sent)
@@ -109,6 +110,14 @@ Invokes the custom not found handler.
109
110
  reply.callNotFound()
110
111
  ```
111
112
 
113
+ <a name="getResponseTime"></a>
114
+ ### .getResponseTime()
115
+ Invokes the custom response time getter to calculate the amount of time passed since the request was started.
116
+
117
+ ```js
118
+ const milliseconds = reply.getResponseTime()
119
+ ```
120
+
112
121
  <a name="type"></a>
113
122
  ### .type(contentType)
114
123
  Sets the content type for the response.
@@ -274,17 +283,15 @@ The type of the sent payload (after serialization and going through any [`onSend
274
283
  Fastify natively handles promises and supports async-await.<br>
275
284
  *Note that in the following examples we are not using reply.send.*
276
285
  ```js
286
+ const delay = promisify(setTimeout)
287
+
277
288
  fastify.get('/promises', options, function (request, reply) {
278
- return new Promise(function (resolve) {
279
- setTimeout(resolve, 200, { hello: 'world' })
280
- })
289
+ return delay(200).then(() => { return { hello: 'world' }})
281
290
  })
282
291
 
283
292
  fastify.get('/async-await', options, async function (request, reply) {
284
- var res = await new Promise(function (resolve) {
285
- setTimeout(resolve, 200, { hello: 'world' })
286
- })
287
- return res
293
+ await delay(200)
294
+ return { hello: 'world' }
288
295
  })
289
296
  ```
290
297