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.
Files changed (72) hide show
  1. package/README.md +15 -4
  2. package/build/build-validation.js +8 -0
  3. package/docs/Benchmarking.md +2 -2
  4. package/docs/ContentTypeParser.md +12 -10
  5. package/docs/Decorators.md +14 -14
  6. package/docs/Ecosystem.md +7 -1
  7. package/docs/Errors.md +13 -8
  8. package/docs/Fluent-Schema.md +9 -12
  9. package/docs/Getting-Started.md +29 -25
  10. package/docs/HTTP2.md +1 -1
  11. package/docs/Hooks.md +201 -186
  12. package/docs/LTS.md +6 -7
  13. package/docs/Logging.md +10 -10
  14. package/docs/Middleware.md +59 -0
  15. package/docs/Plugins-Guide.md +52 -52
  16. package/docs/Plugins.md +3 -0
  17. package/docs/Reply.md +47 -3
  18. package/docs/Routes.md +120 -8
  19. package/docs/Server.md +69 -3
  20. package/docs/Serverless.md +76 -4
  21. package/docs/TypeScript.md +33 -10
  22. package/docs/Validation-and-Serialization.md +137 -1
  23. package/examples/typescript-server.ts +1 -1
  24. package/fastify.d.ts +52 -13
  25. package/fastify.js +68 -7
  26. package/lib/configValidator.js +99 -52
  27. package/lib/contentTypeParser.js +4 -4
  28. package/lib/context.js +2 -1
  29. package/lib/errors.js +21 -18
  30. package/lib/fourOhFour.js +10 -10
  31. package/lib/handleRequest.js +1 -2
  32. package/lib/logger.js +2 -2
  33. package/lib/pluginUtils.js +32 -0
  34. package/lib/reply.js +41 -6
  35. package/lib/route.js +37 -9
  36. package/lib/schemas.js +23 -12
  37. package/lib/symbols.js +4 -1
  38. package/lib/validation.js +15 -9
  39. package/lib/wrapThenable.js +1 -1
  40. package/package.json +34 -26
  41. package/test/404s.test.js +41 -1
  42. package/test/async-await.js +66 -0
  43. package/test/custom-parser.test.js +1 -1
  44. package/test/custom-querystring-parser.test.js +1 -1
  45. package/test/decorator.test.js +48 -0
  46. package/test/emit-warning.test.js +3 -3
  47. package/test/fastify-instance.test.js +29 -0
  48. package/test/helper.js +7 -7
  49. package/test/hooks-async.js +4 -3
  50. package/test/hooks.test.js +27 -8
  51. package/test/input-validation.test.js +126 -0
  52. package/test/internals/errors.test.js +9 -1
  53. package/test/internals/initialConfig.test.js +4 -2
  54. package/test/internals/plugin.test.js +4 -4
  55. package/test/internals/reply.test.js +78 -6
  56. package/test/internals/schemas.test.js +30 -0
  57. package/test/internals/validation.test.js +18 -0
  58. package/test/listen.test.js +1 -1
  59. package/test/logger.test.js +314 -1
  60. package/test/plugin.test.js +171 -0
  61. package/test/promises.test.js +55 -0
  62. package/test/proto-poisoning.test.js +76 -0
  63. package/test/route-hooks.test.js +109 -91
  64. package/test/route-prefix.test.js +1 -1
  65. package/test/schemas.test.js +450 -0
  66. package/test/shared-schemas.test.js +2 -2
  67. package/test/stream.test.js +10 -6
  68. package/test/throw.test.js +48 -2
  69. package/test/types/index.ts +86 -1
  70. package/test/validation-error-handling.test.js +3 -3
  71. package/test/versioned-routes.test.js +1 -1
  72. package/docs/Middlewares.md +0 -59
@@ -0,0 +1,59 @@
1
+ <h1 align="center">Fastify</h1>
2
+
3
+ ## Middleware
4
+
5
+ Fastify provides an asynchronous [middleware engine](https://github.com/fastify/middie) out-of-the-box, which is compatible with [Express](https://expressjs.com/) and [Restify](http://restify.com/) middleware.
6
+
7
+ *For help with understanding when middleware is executed, take a look at the [lifecycle](https://github.com/fastify/fastify/blob/master/docs/Lifecycle.md) page.*
8
+
9
+ Fastify middleware don't support the full syntax `middleware(err, req, res, next)`, because error handling is done inside Fastify.
10
+ Furthermore, methods added by Express and Restify to the enhanced versions of `req` and `res` are not supported in Fastify middlewares.
11
+
12
+ Also, if you are using middleware that bundles different, smaller middleware, such as [*helmet*](https://helmetjs.github.io/), we recommend using the single modules for better performance.
13
+
14
+ ```js
15
+ fastify.use(require('cors')())
16
+ fastify.use(require('dns-prefetch-control')())
17
+ fastify.use(require('frameguard')())
18
+ fastify.use(require('hide-powered-by')())
19
+ fastify.use(require('hsts')())
20
+ fastify.use(require('ienoopen')())
21
+ fastify.use(require('x-xss-protection')())
22
+ ```
23
+
24
+ or, in the specific case of *helmet*, you can use the [*fastify-helmet*](https://github.com/fastify/fastify-helmet) [plugin](Plugins.md), which is an optimized helmet integration for fastify:
25
+
26
+ ```js
27
+ const fastify = require('fastify')()
28
+ const helmet = require('fastify-helmet')
29
+
30
+ fastify.register(helmet)
31
+ ```
32
+
33
+ Remember that middleware can be encapsulated, this means that you can decide where your middleware should run by using `register` as explained in the [plugins guide](https://github.com/fastify/fastify/blob/master/docs/Plugins-Guide.md).
34
+
35
+ Fastify middleware also do not expose the `send` method or other methods specific to the Fastify [Reply]('./Reply.md' "Reply") instance. This is because Fastify wraps the incoming `req` and `res` Node instances using the [Request](./Request.md "Request") and [Reply](./Reply.md "Reply") objects internally, but this is done after the middleware phase. If you need to create middleware, you have to use the Node `req` and `res` instances. Otherwise, you can use the `preHandler` hook which already has the [Request](./Request.md "Request") and [Reply](./Reply.md "Reply") Fastify instances. For more information, see [Hooks](./Hooks.md "Hooks").
36
+
37
+ <a name="restrict-usage"></a>
38
+ #### Restrict middleware execution to a certain path(s)
39
+ If you need to run a middleware only under certain path(s), just pass the path as first parameter to `use` and you are done!
40
+
41
+ *Note that this does not support routes with parameters, (eg: `/user/:id/comments`) and wildcards are not supported in multiple paths.*
42
+
43
+ ```js
44
+ const path = require('path')
45
+ const serveStatic = require('serve-static')
46
+
47
+ // Single path
48
+ fastify.use('/css', serveStatic(path.join(__dirname, '/assets')))
49
+
50
+ // Wildcard path
51
+ fastify.use('/css/*', serveStatic(path.join(__dirname, '/assets')))
52
+
53
+ // Multiple paths
54
+ fastify.use(['/css', '/js'], serveStatic(path.join(__dirname, '/assets')))
55
+ ```
56
+
57
+ <a name="express-middleware"></a>
58
+ #### Express middleware compatibility
59
+ Express modifies the prototype of the node core Request and Response objects heavily so Fastify cannot guarantee full middleware compatibility. Express specific functionality such as `res.sendFile()`, `res.send()` or `express.Router()` instances will not work with Fastify. For example, [cors](https://github.com/expressjs/cors) is compatible while [passport](https://github.com/jaredhanson/passport) is not.
@@ -16,30 +16,29 @@ Fastify was built from the beginning to be an extremely modular system. We built
16
16
 
17
17
  <a name="register"></a>
18
18
  ## Register
19
- As in JavaScript everything is an object, in Fastify everything is a plugin.<br>
20
- Your routes, your utilities and so on are all plugins. To add a new plugin, whatever its functionality is, in Fastify you have a nice and unique api to use: [`register`](https://github.com/fastify/fastify/blob/master/docs/Plugins.md).
19
+ As with JavaScript, where everything is an object, in Fastify everything is a plugin.<br>
20
+ Your routes, your utilities and so on are all plugins. To add a new plugin, whatever its functionality may be, in Fastify you have a nice and unique API: [`register`](https://github.com/fastify/fastify/blob/master/docs/Plugins.md).
21
21
  ```js
22
22
  fastify.register(
23
23
  require('./my-plugin'),
24
24
  { options }
25
25
  )
26
26
  ```
27
- `register` creates a new Fastify context, this means that if you do any change to the Fastify instance, those changes will not be reflected in the context's ancestors. In other words, encapsulation!
28
-
27
+ `register` creates a new Fastify context, which means that if you perform any changes on the Fastify instance, those changes will not be reflected in the context's ancestors. In other words, encapsulation!
29
28
 
30
29
  *Why is encapsulation important?*<br>
31
- Well, let's say you are creating a new disruptive startup, what do you do? You create an api server with all your stuff, everything in the same place, a monolith!<br>
32
- Ok, you are growing very fast and you want to change your architecture and try microservices. Usually this implies a huge amount of work, because of cross dependencies and the lack of separation of concerns.<br>
33
- Fastify helps you a lot in this direction, because thanks to the encapsulation model it will completely avoid cross dependencies, and will help you structure your code in cohesive blocks.
30
+ Well, let's say you are creating a new disruptive startup, what do you do? You create an API server with all your stuff, everything in the same place, a monolith!<br>
31
+ Ok, you are growing very fast and you want to change your architecture and try microservices. Usually, this implies a huge amount of work, because of cross dependencies and a lack of separation of concerns in the codebase.<br>
32
+ Fastify helps you in that regard. Thanks to the encapsulation model it will completely avoid cross dependencies, and will help you structure your code into cohesive blocks.
34
33
 
35
34
  *Let's return to how to correctly use `register`.*<br>
36
35
  As you probably know, the required plugins must expose a single function with the following signature
37
36
  ```js
38
37
  module.exports = function (fastify, options, done) {}
39
38
  ```
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.
39
+ Where `fastify` is the encapsulated Fastify instance, `options` is the options object and `done` is the function you **must** call when your plugin is ready.
41
40
 
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.
41
+ Fastify's plugin model is fully reentrant and graph-based, it handles asynchronous code without any problems and it enforces both the load and close order of plugins. *How?* Glad you asked, check out [`avvio`](https://github.com/mcollina/avvio)! Fastify starts loading the plugin __after__ `.listen()`, `.inject()` or `.ready()` are called.
43
42
 
44
43
  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
44
  ```js
@@ -52,11 +51,11 @@ module.exports = function (fastify, options, done) {
52
51
  }
53
52
  ```
54
53
 
55
- Well, now you know how to use the `register` api and how it works, but how do we add new functionality to Fastify and even better, share them with other developers?
54
+ Well, now you know how to use the `register` API and how it works, but how do we add new functionality to Fastify and even better, share them with other developers?
56
55
 
57
56
  <a name="decorators"></a>
58
57
  ## Decorators
59
- Okay, let's say that you wrote an utility that is so good that you decided to make it available along all your code. How would you do it? Probably something like the following:
58
+ Okay, let's say that you wrote a utility that is so good that you decided to make it available along with all your code. How would you do it? Probably something like the following:
60
59
  ```js
61
60
  // your-awesome-utility.js
62
61
  module.exports = function (a, b) {
@@ -65,40 +64,42 @@ module.exports = function (a, b) {
65
64
  ```
66
65
  ```js
67
66
  const util = require('./your-awesome-utility')
68
- console.log(util('that is ', ' awesome'))
67
+ console.log(util('that is ', 'awesome'))
69
68
  ```
70
- And now you will import your utility in every file you need it. (And don't forget that you will probably also need it in your test).
69
+ And now you will import your utility in every file you need it in. (And don't forget that you will probably also need it in your tests).
71
70
 
72
- Fastify offers you a way nicer and elegant way to do this, *decorators*.
73
- Create a decorator is extremely easy, just use the [`decorate`](https://github.com/fastify/fastify/blob/master/docs/Decorators.md) api:
71
+ Fastify offers you a more elegant and comfortable way to do this, *decorators*.
72
+ Creating a decorator is extremely easy, just use the [`decorate`](https://github.com/fastify/fastify/blob/master/docs/Decorators.md) API:
74
73
  ```js
75
74
  fastify.decorate('util', (a, b) => a + b)
76
75
  ```
77
- Now you can access your utility just by doing `fastify.util` whenever you need it, even inside your test.<br>
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:
76
+ Now you can access your utility just by calling `fastify.util` whenever you need it - even inside your test.<br>
77
+ And here starts the magic; do you remember how just now we were talking about encapsulation? Well, using `register` and `decorate` in conjunction enable exactly that, let me show you an example to clarify this:
79
78
  ```js
80
79
  fastify.register((instance, opts, done) => {
81
80
  instance.decorate('util', (a, b) => a + b)
82
- console.log(instance.util('that is ', ' awesome'))
81
+ console.log(instance.util('that is ', 'awesome'))
83
82
 
84
83
  done()
85
84
  })
86
85
 
87
86
  fastify.register((instance, opts, done) => {
88
- console.log(instance.util('that is ', ' awesome')) // this will throw an error
87
+ console.log(instance.util('that is ', 'awesome')) // This will throw an error
89
88
 
90
89
  done()
91
90
  })
92
91
  ```
93
92
  Inside the second register call `instance.util` will throw an error, because `util` exists only inside the first register context.<br>
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.
93
+ Let's step back for a moment and dig deeper into this: every time you use the `register` API, a new context is created which avoids the negative situations mentioned above.
94
+
95
+ Do note that encapsulation applies to the ancestors and siblings, but not the children.
95
96
  ```js
96
97
  fastify.register((instance, opts, done) => {
97
98
  instance.decorate('util', (a, b) => a + b)
98
- console.log(instance.util('that is ', ' awesome'))
99
+ console.log(instance.util('that is ', 'awesome'))
99
100
 
100
101
  fastify.register((instance, opts, done) => {
101
- console.log(instance.util('that is ', ' awesome')) // this will not throw an error
102
+ console.log(instance.util('that is ', 'awesome')) // This will not throw an error
102
103
  done()
103
104
  })
104
105
 
@@ -106,14 +107,14 @@ fastify.register((instance, opts, done) => {
106
107
  })
107
108
 
108
109
  fastify.register((instance, opts, done) => {
109
- console.log(instance.util('that is ', ' awesome')) // this will throw an error
110
+ console.log(instance.util('that is ', 'awesome')) // This will throw an error
110
111
 
111
112
  done()
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).*
115
+ *Take home message: if you need an utility which is available in every part of your application, take care that it's declared in the root scope of your application. If that's not an option you can use the `fastify-plugin` utility as described [here](#distribution).*
115
116
 
116
- `decorate` is not the unique api that you can use to extend the server functionalities, you can also use `decorateRequest` and `decorateReply`.
117
+ `decorate` is not the only API that you can use to extend the server functionality, you can also use `decorateRequest` and `decorateReply`.
117
118
 
118
119
  *`decorateRequest` and `decorateReply`? Why do we need them if we already have `decorate`?*<br>
119
120
  Good question, we added them to make Fastify more developer-friendly. Let's see an example:
@@ -128,10 +129,10 @@ fastify.get('/html', (request, reply) => {
128
129
  .send(fastify.html({ hello: 'world' }))
129
130
  })
130
131
  ```
131
- It works, but it can be way better!
132
+ It works, but it could be way better!
132
133
  ```js
133
134
  fastify.decorateReply('html', function (payload) {
134
- this.type('text/html') // this is the 'Reply' object
135
+ this.type('text/html') // This is the 'Reply' object
135
136
  this.send(generateHtml(payload))
136
137
  })
137
138
 
@@ -161,7 +162,7 @@ fastify.decorateRequest('setHeader', function (header) {
161
162
  this.isHappy = this.headers[header]
162
163
  })
163
164
 
164
- fastify.decorateRequest('isHappy', false) // this will be added to the Request object prototype, yay speed!
165
+ fastify.decorateRequest('isHappy', false) // This will be added to the Request object prototype, yay speed!
165
166
 
166
167
  fastify.addHook('preHandler', (request, reply, done) => {
167
168
  request.setHeader('happy')
@@ -173,7 +174,7 @@ fastify.get('/happiness', (request, reply) => {
173
174
  })
174
175
  ```
175
176
 
176
- We've seen how to extend server functionality and how handle the encapsulation system, but what if you need to add a function that must be executed every time that the server "[emits](https://github.com/fastify/fastify/blob/master/docs/Lifecycle.md)" an event?
177
+ We've seen how to extend server functionality and how to handle the encapsulation system, but what if you need to add a function that must be executed every time when the server "[emits](https://github.com/fastify/fastify/blob/master/docs/Lifecycle.md)" an event?
177
178
 
178
179
  <a name="hooks"></a>
179
180
  ## Hooks
@@ -191,9 +192,9 @@ fastify.get('/plugin2', (request, reply) => {
191
192
  reply.send(request)
192
193
  })
193
194
  ```
194
- I think we all agree that this is terrible. Code repeat, awful readability and it cannot scale.
195
+ I think we all agree that this is terrible. Repeated code, awful readability and it cannot scale.
195
196
 
196
- So what can you do to avoid this annoying issue? Yes, you are right, use an [hook](https://github.com/fastify/fastify/blob/master/docs/Hooks.md)!<br>
197
+ So what can you do to avoid this annoying issue? Yes, you are right, use a [hook](https://github.com/fastify/fastify/blob/master/docs/Hooks.md)!<br>
197
198
  ```js
198
199
  fastify.decorate('util', (request, key, value) => { request[key] = value })
199
200
 
@@ -210,8 +211,8 @@ fastify.get('/plugin2', (request, reply) => {
210
211
  reply.send(request)
211
212
  })
212
213
  ```
213
- Now for every request you will run your utility, it is obvious that you can register as many hooks as you need.<br>
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!
214
+ Now for every request, you will run your utility. Obviously you can register as many hooks as you need.<br>
215
+ Sometimes you want a hook that should be executed for just a subset of routes, how can you do that? Yep, encapsulation!
215
216
 
216
217
  ```js
217
218
  fastify.register((instance, opts, done) => {
@@ -235,13 +236,13 @@ fastify.get('/plugin2', (request, reply) => {
235
236
  ```
236
237
  Now your hook will run just for the first route!
237
238
 
238
- As you probably noticed at this time, `request` and `reply` are not the standard Nodejs *request* and *response* objects, but Fastify's objects.<br>
239
+ As you probably noticed by now, `request` and `reply` are not the standard Nodejs *request* and *response* objects, but Fastify's objects.<br>
239
240
 
240
- <a name="middlewares"></a>
241
- ## Middlewares
242
- Fastify [supports](https://github.com/fastify/fastify/blob/master/docs/Middlewares.md) out of the box Express/Restify/Connect middlewares, this means that you can just drop-in your old code and it will work! *(faster, by the way)*<br>
243
- Let's say that you are arriving from Express, and you already have some Middleware that does exactly what you need, and you don't want to redo all the work.
244
- How we can do that? Checkout our middlewares engine, [middie](https://github.com/fastify/middie).
241
+ <a name="middleware"></a>
242
+ ## Middleware
243
+ Fastify [supports](https://github.com/fastify/fastify/blob/master/docs/Middleware.md) Express/Restify/Connect middleware out-of-the-box, which means that you can just drop-in your old code and it will work! *(faster, by the way)*<br>
244
+ Let's say that you are arriving from Express, and you already have some Middleware which does exactly what you need, and you don't want to redo all the work.
245
+ How we can do that? Check out our middleware engine, [middie](https://github.com/fastify/middie).
245
246
  ```js
246
247
  const yourMiddleware = require('your-middleware')
247
248
  fastify.use(yourMiddleware)
@@ -249,13 +250,12 @@ fastify.use(yourMiddleware)
249
250
 
250
251
  <a name="distribution"></a>
251
252
  ## How to handle encapsulation and distribution
252
- Perfect, now you know (almost) all the tools that you can use to extend Fastify. But probably there is something you noted when trying out your code.<br>
253
- How can you distribute your code?
253
+ Perfect, now you know (almost) all of the tools that you can use to extend Fastify. But chances are that you came across one big issue: how is distribution handled?
254
254
 
255
- The preferred way to distribute a utility is to wrap all your code inside a `register`, in this way your plugin can support an asynchronous bootstrap *(since `decorate` is a synchronous api)*, in the case of a database connection for example.
255
+ The preferred way to distribute a utility is to wrap all your code inside a `register`, in this way your plugin can support asynchronous bootstrapping *(since `decorate` is a synchronous API)*, in the case of a database connection for example.
256
256
 
257
- *Wait, what? Didn't you tell me that `register` creates an encapsulation and that what I create inside there will not be available outside?*<br>
258
- Yes, I said that. But what I didn't tell you, is that you can tell to Fastify to avoid this behavior, with the [`fastify-plugin`](https://github.com/fastify/fastify-plugin) module.
257
+ *Wait, what? Didn't you tell me that `register` creates an encapsulation and that the stuff I create inside will not be available outside?*<br>
258
+ Yes, I said that. But what I didn't tell you, is that you can tell to Fastify to avoid this behaviour, with the [`fastify-plugin`](https://github.com/fastify/fastify-plugin) module.
259
259
  ```js
260
260
  const fp = require('fastify-plugin')
261
261
  const dbClient = require('db-client')
@@ -269,7 +269,7 @@ function dbPlugin (fastify, opts, done) {
269
269
 
270
270
  module.exports = fp(dbPlugin)
271
271
  ```
272
- You can also tell to `fastify-plugin` to check the installed version of Fastify, in case of you need a specific api.
272
+ You can also tell `fastify-plugin` to check the installed version of Fastify, in case you need a specific API.
273
273
 
274
274
  As we mentioned earlier, Fastify starts loading its plugins __after__ `.listen()`, `.inject()` or `.ready()` are called and as such, __after__ they have been declared. This means that, even though the plugin may inject variables to the external fastify instance via [`decorate`](https://github.com/fastify/fastify/blob/master/docs/Decorators.md), the decorated variables will not be accessible before calling `.listen()`, `.inject()` or `.ready()`.
275
275
 
@@ -295,14 +295,14 @@ In the above example, the `parent` variable of the function passed in as the sec
295
295
 
296
296
  <a name="handle-errors"></a>
297
297
  ## Handle errors
298
- It can happen that one of your plugins could fail during the startup. Maybe you expect it and you have a custom logic that will be triggered in that case. How can you do this?
299
- The `after` api is what you need. `after` simply registers a callback that will be executed just after a register, and it can take up to three parameters.<br>
300
- The callback changes based on the parameters your are giving:
298
+ It can happen that one of your plugins fails during startup. Maybe you expect it and you have a custom logic that will be triggered in that case. How can you implement this?
299
+ The `after` API is what you need. `after` simply registers a callback that will be executed just after a register, and it can take up to three parameters.<br>
300
+ The callback changes based on the parameters you are giving:
301
301
 
302
302
  1. If no parameter is given to the callback and there is an error, that error will be passed to the next error handler.
303
303
  1. If one parameter is given to the callback, that parameter will be the error object.
304
304
  1. If two parameters are given to the callback, the first will be the error object, the second will be the done callback.
305
- 1. If three parameters are given to the callback, the first will be the error object, the second will be the top level context unless you have specified both server and override, in that case the context will be what the override returns, and the third the done callback.
305
+ 1. If three parameters are given to the callback, the first will be the error object, the second will be the top-level context unless you have specified both server and override, in that case, the context will be what the override returns, and the third the done callback.
306
306
 
307
307
  Let's see how to use it:
308
308
  ```js
@@ -317,14 +317,14 @@ fastify
317
317
  ## Let's start!
318
318
  Awesome, now you know everything you need to know about Fastify and its plugin system to start building your first plugin, and please if you do, tell us! We will add it to the [*ecosystem*](https://github.com/fastify/fastify#ecosystem) section of our documentation!
319
319
 
320
- If you want to see some real world example, checkout:
320
+ If you want to see some real-world example, check out:
321
321
  - [`point-of-view`](https://github.com/fastify/point-of-view)
322
322
  Templates rendering (*ejs, pug, handlebars, marko*) plugin support for Fastify.
323
323
  - [`fastify-mongodb`](https://github.com/fastify/fastify-mongodb)
324
- Fastify MongoDB connection plugin, with this you can share the same MongoDb connection pool in every part of your server.
324
+ Fastify MongoDB connection plugin, with this you can share the same MongoDB connection pool in every part of your server.
325
325
  - [`fastify-multipart`](https://github.com/fastify/fastify-multipart)
326
326
  Multipart support for Fastify
327
327
  - [`fastify-helmet`](https://github.com/fastify/fastify-helmet) Important security headers for Fastify
328
328
 
329
329
 
330
- *Do you feel it's missing something here? Let us know! :)*
330
+ *Do you feel like something is missing here? Let us know! :)*
package/docs/Plugins.md CHANGED
@@ -16,8 +16,11 @@ fastify.register(plugin, [options])
16
16
  The optional `options` parameter for `fastify.register` supports a predefined set of options that Fastify itself will use, except when the plugin has been wrapped with [fastify-plugin](https://github.com/fastify/fastify-plugin). This options object will also be passed to the plugin upon invocation, regardless of whether or not the plugin has been wrapped. The currently supported list of Fastify specific options is:
17
17
 
18
18
  + [`logLevel`](https://github.com/fastify/fastify/blob/master/docs/Routes.md#custom-log-level)
19
+ + [`logSerializers`](https://github.com/fastify/fastify/blob/master/docs/Routes.md#custom-log-serializer)
19
20
  + [`prefix`](https://github.com/fastify/fastify/blob/master/docs/Plugins.md#route-prefixing-options)
20
21
 
22
+ **Note: Those options will be ignored when used with fastify-plugin**
23
+
21
24
  It is possible that Fastify will directly support other options in the future. Thus, to avoid collisions, a plugin should consider namespacing its options. For example, a plugin `foo` might be registered like so:
22
25
 
23
26
  ```js
package/docs/Reply.md CHANGED
@@ -4,7 +4,9 @@
4
4
  - [Reply](#reply)
5
5
  - [Introduction](#introduction)
6
6
  - [.code(statusCode)](#codestatuscode)
7
+ - [.statusCode](#statusCode)
7
8
  - [.header(key, value)](#headerkey-value)
9
+ - [.headers(object)](#headersobject)
8
10
  - [.getHeader(key)](#getheaderkey)
9
11
  - [.removeHeader(key)](#removeheaderkey)
10
12
  - [.hasHeader(key)](#hasheaderkey)
@@ -22,7 +24,8 @@
22
24
  - [Errors](#errors)
23
25
  - [Type of the final payload](#type-of-the-final-payload)
24
26
  - [Async-Await and Promises](#async-await-and-promises)
25
-
27
+ - [.then](#then)
28
+
26
29
  <a name="introduction"></a>
27
30
  ### Introduction
28
31
  The second parameter of the handler function is `Reply`.
@@ -31,7 +34,9 @@ and properties:
31
34
 
32
35
  - `.code(statusCode)` - Sets the status code.
33
36
  - `.status(statusCode)` - An alias for `.code(statusCode)`.
37
+ - `.statusCode` - Read and set the HTTP status code.
34
38
  - `.header(name, value)` - Sets a response header.
39
+ - `.headers(object)` - Sets all the keys of the object as a response headers.
35
40
  - `.getHeader(name)` - Retrieve value of already set header.
36
41
  - `.removeHeader(key)` - Remove the value of a previously set header.
37
42
  - `.hasHeader(name)` - Determine if a header has been set.
@@ -43,7 +48,8 @@ and properties:
43
48
  - `.send(payload)` - Sends the payload to the user, could be a plain text, a buffer, JSON, stream, or an Error object.
44
49
  - `.sent` - A boolean value that you can use if you need to know if `send` has already been called.
45
50
  - `.res` - The [`http.ServerResponse`](https://nodejs.org/dist/latest/docs/api/http.html#http_class_http_serverresponse) from Node core.
46
- - `.log` - the logger instance of the incoming request
51
+ - `.log` - The logger instance of the incoming request.
52
+ - `.request` - The incoming request.
47
53
 
48
54
  ```js
49
55
  fastify.get('/', options, function (request, reply) {
@@ -67,6 +73,15 @@ fastify.get('/', {config: {foo: 'bar'}}, function (request, reply) {
67
73
  ### .code(statusCode)
68
74
  If not set via `reply.code`, the resulting `statusCode` will be `200`.
69
75
 
76
+ <a name="statusCode"></a>
77
+ ### .statusCode
78
+ This property reads and sets the HTTP status code. It is an alias for `reply.code()` when used as a setter.
79
+ ```js
80
+ if (reply.statusCode >= 299) {
81
+ reply.statusCode = 500
82
+ }
83
+ ```
84
+
70
85
  <a name="header"></a>
71
86
  ### .header(key, value)
72
87
  Sets a response header. If the value is omitted or undefined it is coerced
@@ -74,6 +89,16 @@ to `''`.
74
89
 
75
90
  For more information, see [`http.ServerResponse#setHeader`](https://nodejs.org/dist/latest/docs/api/http.html#http_response_setheader_name_value).
76
91
 
92
+ <a name="headers"></a>
93
+ ### .headers(object)
94
+ Sets all the keys of the object as response headers. [`.header`](#headerkey-value) will be called under the hood.
95
+ ```js
96
+ reply.headers({
97
+ 'x-foo': 'foo',
98
+ 'x-bar': 'bar'
99
+ })
100
+ ```
101
+
77
102
  <a name="getHeader"></a>
78
103
  ### .getHeader(key)
79
104
  Retrieves the value of a previously set header.
@@ -224,11 +249,12 @@ If you pass to *send* an object that is an instance of *Error*, Fastify will aut
224
249
  ```js
225
250
  {
226
251
  error: String // the http error message
252
+ code: String // the Fastify error code
227
253
  message: String // the user error message
228
254
  statusCode: Number // the http status code
229
255
  }
230
256
  ```
231
- You can add some custom property to the Error object, such as `statusCode` and `headers`, that will be used to enhance the http response.<br>
257
+ You can add some custom property to the Error object, such as `headers`, that will be used to enhance the http response.<br>
232
258
  *Note: If you are passing an error to `send` and the statusCode is less than 400, Fastify will automatically set it at 500.*
233
259
 
234
260
  Tip: you can simplify errors by using the [`http-errors`](https://npm.im/http-errors) module or [`fastify-sensible`](https://github.com/fastify/fastify-sensible) plugin to generate errors:
@@ -307,3 +333,21 @@ fastify.get('/teapot', async function (request, reply) => {
307
333
  ```
308
334
 
309
335
  If you want to know more please review [Routes#async-await](https://github.com/fastify/fastify/blob/master/docs/Routes.md#async-await).
336
+
337
+ <a name="then"></a>
338
+ ### .then(fullfilled, rejected)
339
+
340
+ As the name suggests, a `Reply` object can be awaited upon, i.e. `await reply` will wait until the reply is sent.
341
+ The `await` syntax calls the `reply.then()`.
342
+
343
+ `reply.then(fullfilled, rejected)` accepts two parameters:
344
+
345
+ - `fullfilled` will be called when a response has been fully sent,
346
+ - `rejected` will be called if the underlying stream had an error, e.g.
347
+ the socket has been destroyed.
348
+
349
+ For more details, see:
350
+
351
+ - https://github.com/fastify/fastify/issues/1864 for the discussion about this feature
352
+ - https://promisesaplus.com/ for the definition of thenables
353
+ - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then for the signature