fastify 5.2.1 → 5.2.2

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 (73) hide show
  1. package/.vscode/settings.json +22 -0
  2. package/LICENSE +1 -1
  3. package/PROJECT_CHARTER.md +7 -7
  4. package/README.md +24 -25
  5. package/SPONSORS.md +2 -0
  6. package/docs/Guides/Benchmarking.md +4 -4
  7. package/docs/Guides/Database.md +1 -1
  8. package/docs/Guides/Delay-Accepting-Requests.md +10 -10
  9. package/docs/Guides/Ecosystem.md +5 -1
  10. package/docs/Guides/Fluent-Schema.md +1 -1
  11. package/docs/Guides/Getting-Started.md +9 -5
  12. package/docs/Guides/Index.md +1 -1
  13. package/docs/Guides/Migration-Guide-V4.md +1 -1
  14. package/docs/Guides/Migration-Guide-V5.md +12 -2
  15. package/docs/Guides/Plugins-Guide.md +6 -6
  16. package/docs/Guides/Serverless.md +14 -48
  17. package/docs/Guides/Style-Guide.md +2 -2
  18. package/docs/Guides/Testing.md +2 -2
  19. package/docs/Guides/Write-Plugin.md +2 -3
  20. package/docs/Reference/ContentTypeParser.md +58 -78
  21. package/docs/Reference/Decorators.md +50 -60
  22. package/docs/Reference/Encapsulation.md +28 -33
  23. package/docs/Reference/Errors.md +50 -53
  24. package/docs/Reference/HTTP2.md +7 -7
  25. package/docs/Reference/Hooks.md +31 -30
  26. package/docs/Reference/LTS.md +10 -15
  27. package/docs/Reference/Lifecycle.md +19 -24
  28. package/docs/Reference/Logging.md +59 -56
  29. package/docs/Reference/Middleware.md +19 -19
  30. package/docs/Reference/Plugins.md +55 -71
  31. package/docs/Reference/Principles.md +25 -30
  32. package/docs/Reference/Reply.md +11 -10
  33. package/docs/Reference/Request.md +89 -98
  34. package/docs/Reference/Routes.md +108 -128
  35. package/docs/Reference/Server.md +18 -16
  36. package/docs/Reference/Type-Providers.md +19 -21
  37. package/docs/Reference/TypeScript.md +1 -18
  38. package/docs/Reference/Validation-and-Serialization.md +134 -159
  39. package/docs/Reference/Warnings.md +22 -25
  40. package/fastify.js +1 -1
  41. package/lib/contentTypeParser.js +7 -8
  42. package/lib/error-handler.js +14 -12
  43. package/lib/headRoute.js +4 -2
  44. package/lib/pluginUtils.js +4 -2
  45. package/lib/server.js +5 -0
  46. package/lib/validation.js +1 -1
  47. package/lib/warnings.js +9 -0
  48. package/lib/wrapThenable.js +8 -1
  49. package/package.json +10 -10
  50. package/test/build/error-serializer.test.js +2 -1
  51. package/test/bundler/esbuild/package.json +1 -1
  52. package/test/close.test.js +125 -108
  53. package/test/custom-parser-async.test.js +34 -36
  54. package/test/genReqId.test.js +125 -174
  55. package/test/has-route.test.js +1 -3
  56. package/test/internals/content-type-parser.test.js +1 -1
  57. package/test/issue-4959.test.js +84 -0
  58. package/test/listen.1.test.js +37 -34
  59. package/test/listen.2.test.js +47 -40
  60. package/test/listen.3.test.js +28 -32
  61. package/test/listen.4.test.js +61 -45
  62. package/test/listen.5.test.js +23 -0
  63. package/test/register.test.js +55 -50
  64. package/test/request-error.test.js +114 -94
  65. package/test/route-shorthand.test.js +36 -32
  66. package/test/server.test.js +0 -175
  67. package/test/stream.5.test.js +35 -33
  68. package/test/throw.test.js +87 -91
  69. package/test/toolkit.js +32 -0
  70. package/test/trust-proxy.test.js +23 -23
  71. package/test/types/instance.test-d.ts +1 -0
  72. package/test/upgrade.test.js +32 -30
  73. package/types/instance.d.ts +4 -0
@@ -340,10 +340,10 @@ test('should ...', {only: true}, t => ...)
340
340
  ```
341
341
  2. Run `node --test`
342
342
  ```bash
343
- > node --test --test-only --node-arg=--inspect-brk test/<test-file.test.js>
343
+ > node --test --test-only --inspect-brk test/<test-file.test.js>
344
344
  ```
345
345
  - `--test-only` specifies to run tests with the `only` option enabled
346
- - `--node-arg=--inspect-brk` will launch the node debugger
346
+ - `--inspect-brk` will launch the node debugger
347
347
  3. In VS Code, create and launch a `Node.js: Attach` debug configuration. No
348
348
  modification should be necessary.
349
349
 
@@ -14,7 +14,7 @@ suggestion"](https://github.com/fastify/fastify/issues?q=is%3Aissue+is%3Aopen+la
14
14
  in our issue tracker!*
15
15
 
16
16
  ## Code
17
- Fastify uses different techniques to optimize its code, many of them are
17
+ Fastify uses different techniques to optimize its code, many of which are
18
18
  documented in our Guides. We highly recommend you read [the hitchhiker's guide
19
19
  to plugins](./Plugins-Guide.md) to discover all the APIs you can use to build
20
20
  your plugin and learn how to use them.
@@ -53,8 +53,7 @@ Always put an example file in your repository. Examples are very helpful for
53
53
  users and give a very fast way to test your plugin. Your users will be grateful.
54
54
 
55
55
  ## Test
56
- It is extremely important that a plugin is thoroughly tested to verify that is
57
- working properly.
56
+ A plugin **must** be thoroughly tested to verify that is working properly.
58
57
 
59
58
  A plugin without tests will not be accepted to the ecosystem list. A lack of
60
59
  tests does not inspire trust nor guarantee that the code will continue to work
@@ -1,38 +1,32 @@
1
1
  <h1 align="center">Fastify</h1>
2
2
 
3
3
  ## `Content-Type` Parser
4
- Natively, Fastify only supports `'application/json'` and `'text/plain'` content
5
- types. If the content type is not one of these, an
6
- `FST_ERR_CTP_INVALID_MEDIA_TYPE` error will be thrown.
7
- Other common content types are supported through the use of
8
- [plugins](https://fastify.dev/ecosystem/).
4
+ Fastify natively supports `'application/json'` and `'text/plain'` content types
5
+ with a default charset of `utf-8`. These default parsers can be changed or
6
+ removed.
9
7
 
10
- The default charset is `utf-8`. If you need to support different content types,
11
- you can use the `addContentTypeParser` API. *The default JSON and/or plain text
12
- parser can be changed or removed.*
8
+ Unsupported content types will throw an `FST_ERR_CTP_INVALID_MEDIA_TYPE` error.
13
9
 
14
- *Note: If you decide to specify your own content type with the `Content-Type`
15
- header, UTF-8 will not be the default. Be sure to include UTF-8 like this
16
- `text/html; charset=utf-8`.*
10
+ To support other content types, use the `addContentTypeParser` API or an
11
+ existing [plugin](https://fastify.dev/ecosystem/).
17
12
 
18
- As with the other APIs, `addContentTypeParser` is encapsulated in the scope in
19
- which it is declared. This means that if you declare it in the root scope it
20
- will be available everywhere, while if you declare it inside a plugin it will be
21
- available only in that scope and its children.
13
+ As with other APIs, `addContentTypeParser` is encapsulated in the scope in which
14
+ it is declared. If declared in the root scope, it is available everywhere; if
15
+ declared in a plugin, it is available only in that scope and its children.
22
16
 
23
17
  Fastify automatically adds the parsed request payload to the [Fastify
24
- request](./Request.md) object which you can access with `request.body`.
25
-
26
- Note that for `GET` and `HEAD` requests the payload is never parsed. For
27
- `OPTIONS` and `DELETE` requests the payload is only parsed if the content type
28
- is given in the content-type header. If it is not given, the
29
- [catch-all](#catch-all) parser is not executed as with `POST`, `PUT` and
30
- `PATCH`, but the payload is simply not parsed.
31
-
32
- > ## Security Notice
33
- > When using with RegExp to detect `Content-Type`, you should beware of
34
- > how to properly detect the `Content-Type`. For example, if you need
35
- > `application/*`, you should use `/^application\/([\w-]+);?/` to match the
18
+ request](./Request.md) object, accessible via `request.body`.
19
+
20
+ Note that for `GET` and `HEAD` requests, the payload is never parsed. For
21
+ `OPTIONS` and `DELETE` requests, the payload is parsed only if a valid
22
+ `content-type` header is provided. Unlike `POST`, `PUT`, and `PATCH`, the
23
+ [catch-all](#catch-all) parser is not executed, and the payload is simply not
24
+ parsed.
25
+
26
+ > ⚠ Warning:
27
+ > When using regular expressions to detect `Content-Type`, it is important to
28
+ > ensure proper detection. For example, to match `application/*`, use
29
+ > `/^application\/([\w-]+);?/` to match the
36
30
  > [essence MIME type](https://mimesniff.spec.whatwg.org/#mime-type-miscellaneous)
37
31
  > only.
38
32
 
@@ -70,11 +64,10 @@ fastify.addContentTypeParser('text/json', { parseAs: 'string' }, fastify.getDefa
70
64
  ```
71
65
 
72
66
  Fastify first tries to match a content-type parser with a `string` value before
73
- trying to find a matching `RegExp`. If you provide overlapping content types,
74
- Fastify tries to find a matching content type by starting with the last one
75
- passed and ending with the first one. So if you want to specify a general
76
- content type more precisely, first specify the general content type and then the
77
- more specific one, like in the example below.
67
+ trying to find a matching `RegExp`. For overlapping content types, it starts
68
+ with the last one configured and ends with the first (last in, first out).
69
+ To specify a general content type more precisely, first specify the general
70
+ type, then the specific one, as shown below.
78
71
 
79
72
  ```js
80
73
  // Here only the second content type parser is called because its value also matches the first one
@@ -88,10 +81,9 @@ fastify.addContentTypeParser('application/vnd.custom+xml', (request, body, done)
88
81
  ```
89
82
 
90
83
  ### Using addContentTypeParser with fastify.register
91
- When using `addContentTypeParser` in combination with `fastify.register`,
92
- `await` should not be used when registering routes. Using `await` causes
93
- the route registration to be asynchronous and can lead to routes being registered
94
- before the addContentTypeParser has been set.
84
+ When using `addContentTypeParser` with `fastify.register`, avoid `await`
85
+ when registering routes. Using `await` makes route registration asynchronous,
86
+ potentially registering routes before `addContentTypeParser` is set.
95
87
 
96
88
  #### Correct Usage
97
89
  ```js
@@ -109,14 +101,13 @@ fastify.register((fastify, opts) => {
109
101
  });
110
102
  ```
111
103
 
112
- Besides the `addContentTypeParser` API there are further APIs that can be used.
113
- These are `hasContentTypeParser`, `removeContentTypeParser` and
114
- `removeAllContentTypeParsers`.
104
+ In addition to `addContentTypeParser`, the `hasContentTypeParser`,
105
+ `removeContentTypeParser`, and `removeAllContentTypeParsers` APIs are available.
115
106
 
116
107
  #### hasContentTypeParser
117
108
 
118
- You can use the `hasContentTypeParser` API to find if a specific content type
119
- parser already exists.
109
+ Use the `hasContentTypeParser` API to check if a specific content type parser
110
+ exists.
120
111
 
121
112
  ```js
122
113
  if (!fastify.hasContentTypeParser('application/jsoff')){
@@ -130,8 +121,8 @@ if (!fastify.hasContentTypeParser('application/jsoff')){
130
121
 
131
122
  #### removeContentTypeParser
132
123
 
133
- With `removeContentTypeParser` a single or an array of content types can be
134
- removed. The method supports `string` and `RegExp` content types.
124
+ `removeContentTypeParser` can remove a single content type or an array of
125
+ content types, supporting both `string` and `RegExp`.
135
126
 
136
127
  ```js
137
128
  fastify.addContentTypeParser('text/xml', function (request, payload, done) {
@@ -145,16 +136,11 @@ fastify.removeContentTypeParser(['application/json', 'text/plain'])
145
136
  ```
146
137
 
147
138
  #### removeAllContentTypeParsers
148
-
149
- In the example from just above, it is noticeable that we need to specify each
150
- content type that we want to remove. To solve this problem Fastify provides the
151
- `removeAllContentTypeParsers` API. This can be used to remove all currently
152
- existing content type parsers. In the example below we achieve the same as in
153
- the example above except that we do not need to specify each content type to
154
- delete. Just like `removeContentTypeParser`, this API supports encapsulation.
155
- The API is especially useful if you want to register a [catch-all content type
156
- parser](#catch-all) that should be executed for every content type and the
157
- built-in parsers should be ignored as well.
139
+ The `removeAllContentTypeParsers` API removes all existing content type parsers
140
+ eliminating the need to specify each one individually. This API supports
141
+ encapsulation and is useful for registering a
142
+ [catch-all content type parser](#catch-all) that should be executed for every
143
+ content type, ignoring built-in parsers.
158
144
 
159
145
  ```js
160
146
  fastify.removeAllContentTypeParsers()
@@ -166,18 +152,16 @@ fastify.addContentTypeParser('text/xml', function (request, payload, done) {
166
152
  })
167
153
  ```
168
154
 
169
- **Notice**: The old syntaxes `function(req, done)` and `async function(req)` for
170
- the parser are still supported but they are deprecated.
155
+ > 🛈 Note: `function(req, done)` and `async function(req)` are
156
+ > still supported but deprecated.
171
157
 
172
158
  #### Body Parser
173
- You can parse the body of a request in two ways. The first one is shown above:
174
- you add a custom content type parser and handle the request stream. In the
175
- second one, you should pass a `parseAs` option to the `addContentTypeParser`
176
- API, where you declare how you want to get the body. It could be of type
177
- `'string'` or `'buffer'`. If you use the `parseAs` option, Fastify will
178
- internally handle the stream and perform some checks, such as the [maximum
179
- size](./Server.md#factory-body-limit) of the body and the content length. If the
180
- limit is exceeded the custom parser will not be invoked.
159
+ The request body can be parsed in two ways. First, add a custom content type
160
+ parser and handle the request stream. Or second, use the `parseAs` option in the
161
+ `addContentTypeParser` API, specifying `'string'` or `'buffer'`. Fastify will
162
+ handle the stream, check the [maximum size](./Server.md#factory-body-limit) of
163
+ the body, and the content length. If the limit is exceeded, the custom parser
164
+ will not be invoked.
181
165
  ```js
182
166
  fastify.addContentTypeParser('application/json', { parseAs: 'string' }, function (req, body, done) {
183
167
  try {
@@ -195,15 +179,14 @@ See
195
179
  for an example.
196
180
 
197
181
  ##### Custom Parser Options
198
- + `parseAs` (string): Either `'string'` or `'buffer'` to designate how the
199
- incoming data should be collected. Default: `'buffer'`.
182
+ + `parseAs` (string): `'string'` or `'buffer'` to designate how the incoming
183
+ data should be collected. Default: `'buffer'`.
200
184
  + `bodyLimit` (number): The maximum payload size, in bytes, that the custom
201
185
  parser will accept. Defaults to the global body limit passed to the [`Fastify
202
186
  factory function`](./Server.md#bodylimit).
203
187
 
204
188
  #### Catch-All
205
- There are some cases where you need to catch all requests regardless of their
206
- content type. With Fastify, you can just use the `'*'` content type.
189
+ To catch all requests regardless of content type, use the `'*'` content type:
207
190
  ```js
208
191
  fastify.addContentTypeParser('*', function (request, payload, done) {
209
192
  let data = ''
@@ -213,12 +196,10 @@ fastify.addContentTypeParser('*', function (request, payload, done) {
213
196
  })
214
197
  })
215
198
  ```
199
+ All requests without a corresponding content type parser will be handled by
200
+ this function.
216
201
 
217
- Using this, all requests that do not have a corresponding content type parser
218
- will be handled by the specified function.
219
-
220
- This is also useful for piping the request stream. You can define a content
221
- parser like:
202
+ This is also useful for piping the request stream. Define a content parser like:
222
203
 
223
204
  ```js
224
205
  fastify.addContentTypeParser('*', function (request, payload, done) {
@@ -226,7 +207,7 @@ fastify.addContentTypeParser('*', function (request, payload, done) {
226
207
  })
227
208
  ```
228
209
 
229
- and then access the core HTTP request directly for piping it where you want:
210
+ And then access the core HTTP request directly for piping:
230
211
 
231
212
  ```js
232
213
  app.post('/hello', (request, reply) => {
@@ -254,12 +235,11 @@ fastify.route({
254
235
  })
255
236
  ```
256
237
 
257
- For piping file uploads you may want to check out [this
258
- plugin](https://github.com/fastify/fastify-multipart).
238
+ For piping file uploads, check out
239
+ [`@fastify/multipart`](https://github.com/fastify/fastify-multipart).
259
240
 
260
- If you want the content type parser to be executed on all content types and not
261
- only on those that don't have a specific one, you should call the
262
- `removeAllContentTypeParsers` method first.
241
+ To execute the content type parser on all content types, call
242
+ `removeAllContentTypeParsers` first.
263
243
 
264
244
  ```js
265
245
  // Without this call, the request body with the content type application/json would be processed by the built-in JSON parser
@@ -2,16 +2,15 @@
2
2
 
3
3
  ## Decorators
4
4
 
5
- The decorators API allows customization of the core Fastify objects, such as the
6
- server instance itself and any request and reply objects used during the HTTP
7
- request lifecycle. The decorators API can be used to attach any type of property
8
- to the core objects, e.g. functions, plain objects, or native types.
5
+ The decorators API customizes core Fastify objects, such as the server instance
6
+ and any request and reply objects used during the HTTP request lifecycle. It
7
+ can attach any type of property to core objects, e.g., functions, plain
8
+ objects, or native types.
9
9
 
10
- This API is *synchronous*. Attempting to define a decoration asynchronously
11
- could result in the Fastify instance booting before the decoration completes its
12
- initialization. To avoid this issue, and register an asynchronous decoration,
13
- the `register` API, in combination with `fastify-plugin`, must be used instead.
14
- To learn more, see the [Plugins](./Plugins.md) documentation.
10
+ This API is *synchronous*. Defining a decoration asynchronously could result in
11
+ the Fastify instance booting before the decoration completes. To register an
12
+ asynchronous decoration, use the `register` API with `fastify-plugin`. See the
13
+ [Plugins](./Plugins.md) documentation for more details.
15
14
 
16
15
  Decorating core objects with this API allows the underlying JavaScript engine to
17
16
  optimize the handling of server, request, and reply objects. This is
@@ -35,9 +34,9 @@ fastify.get('/', function (req, reply) {
35
34
  })
36
35
  ```
37
36
 
38
- Since the above example mutates the request object after it has already been
39
- instantiated, the JavaScript engine must deoptimize access to the request
40
- object. By using the decoration API this deoptimization is avoided:
37
+ The above example mutates the request object after instantiation, causing the
38
+ JavaScript engine to deoptimize access. Using the decoration API avoids this
39
+ deoptimization:
41
40
 
42
41
  ```js
43
42
  // Decorate request with a 'user' property
@@ -54,17 +53,13 @@ fastify.get('/', (req, reply) => {
54
53
  })
55
54
  ```
56
55
 
57
- Note that it is important to keep the initial shape of a decorated field as
58
- close as possible to the value intended to be set dynamically in the future.
59
- Initialize a decorator as a `''` if the intended value is a string, and as
60
- `null` if it will be an object or a function.
61
-
62
- Remember this example works only with value types as reference types will
63
- thrown and error during the fastify startup. See [decorateRequest](#decorate-request).
64
-
65
- See [JavaScript engine fundamentals: Shapes and Inline
66
- Caches](https://mathiasbynens.be/notes/shapes-ics) for more information on this
67
- topic.
56
+ Keep the initial shape of a decorated field close to its future dynamic value.
57
+ Initialize a decorator as `''` for strings and `null` for objects or functions.
58
+ This works only with value types; reference types will throw an error during
59
+ Fastify startup. See [decorateRequest](#decorate-request) and
60
+ [JavaScript engine fundamentals: Shapes
61
+ and Inline Caches](https://mathiasbynens.be/notes/shapes-ics)
62
+ for more information.
68
63
 
69
64
  ### Usage
70
65
  <a id="usage"></a>
@@ -72,8 +67,7 @@ topic.
72
67
  #### `decorate(name, value, [dependencies])`
73
68
  <a id="decorate"></a>
74
69
 
75
- This method is used to customize the Fastify [server](./Server.md)
76
- instance.
70
+ This method customizes the Fastify [server](./Server.md) instance.
77
71
 
78
72
  For example, to attach a new method to the server instance:
79
73
 
@@ -83,7 +77,7 @@ fastify.decorate('utility', function () {
83
77
  })
84
78
  ```
85
79
 
86
- As mentioned above, non-function values can be attached to the server instance as:
80
+ Non-function values can also be attached to the server instance:
87
81
 
88
82
  ```js
89
83
  fastify.decorate('conf', {
@@ -118,9 +112,9 @@ fastify.get('/', async function (request, reply) {
118
112
  ```
119
113
 
120
114
  The `dependencies` parameter is an optional list of decorators that the
121
- decorator being defined relies upon. This list is simply a list of string names
122
- of other decorators. In the following example, the "utility" decorator depends
123
- upon "greet" and "hi" decorators:
115
+ decorator being defined relies upon. This list contains the names of other
116
+ decorators. In the following example, the "utility" decorator depends on the
117
+ "greet" and "hi" decorators:
124
118
 
125
119
  ```js
126
120
  async function greetDecorator (fastify, opts) {
@@ -155,18 +149,17 @@ fastify.listen({ port: 3000 }, (err, address) => {
155
149
  })
156
150
  ```
157
151
 
158
- Note: using an arrow function will break the binding of `this` to the
159
- `FastifyInstance`.
152
+ Using an arrow function breaks the binding of `this` to
153
+ the `FastifyInstance`.
160
154
 
161
- If a dependency is not satisfied, the `decorate` method will throw an exception.
162
- The dependency check is performed before the server instance is booted. Thus, it
163
- cannot occur during runtime.
155
+ If a dependency is not satisfied, the `decorate` method throws an exception.
156
+ The dependency check occurs before the server instance boots, not during
157
+ runtime.
164
158
 
165
159
  #### `decorateReply(name, value, [dependencies])`
166
160
  <a id="decorate-reply"></a>
167
161
 
168
- As the name suggests, this API is used to add new methods/properties to the core
169
- `Reply` object:
162
+ This API adds new methods/properties to the core `Reply` object:
170
163
 
171
164
  ```js
172
165
  fastify.decorateReply('utility', function () {
@@ -174,29 +167,29 @@ fastify.decorateReply('utility', function () {
174
167
  })
175
168
  ```
176
169
 
177
- Note: using an arrow function will break the binding of `this` to the Fastify
170
+ Using an arrow function will break the binding of `this` to the Fastify
178
171
  `Reply` instance.
179
172
 
180
- Note: using `decorateReply` will throw and error if used with a reference type:
173
+ Using `decorateReply` will throw and error if used with a reference type:
181
174
 
182
175
  ```js
183
176
  // Don't do this
184
177
  fastify.decorateReply('foo', { bar: 'fizz'})
185
178
  ```
186
- In this example, the reference of the object would be shared with all the requests
187
- and **any mutation will impact all requests, potentially creating security
188
- vulnerabilities or memory leaks**, so Fastify blocks it.
179
+ In this example, the object reference would be shared with all requests, and
180
+ **any mutation will impact all requests, potentially creating security
181
+ vulnerabilities or memory leaks**. Fastify blocks this.
189
182
 
190
183
  To achieve proper encapsulation across requests configure a new value for each
191
- incoming request in the [`'onRequest'` hook](./Hooks.md#onrequest). Example:
184
+ incoming request in the [`'onRequest'` hook](./Hooks.md#onrequest).
192
185
 
193
186
  ```js
194
187
  const fp = require('fastify-plugin')
195
188
 
196
189
  async function myPlugin (app) {
197
- app.decorateRequest('foo')
190
+ app.decorateReply('foo')
198
191
  app.addHook('onRequest', async (req, reply) => {
199
- req.foo = { bar: 42 }
192
+ reply.foo = { bar: 42 }
200
193
  })
201
194
  }
202
195
 
@@ -208,8 +201,8 @@ See [`decorate`](#decorate) for information about the `dependencies` parameter.
208
201
  #### `decorateRequest(name, value, [dependencies])`
209
202
  <a id="decorate-request"></a>
210
203
 
211
- As above with [`decorateReply`](#decorate-reply), this API is used add new
212
- methods/properties to the core `Request` object:
204
+ As with [`decorateReply`](#decorate-reply), this API adds new methods/properties
205
+ to the core `Request` object:
213
206
 
214
207
  ```js
215
208
  fastify.decorateRequest('utility', function () {
@@ -217,18 +210,18 @@ fastify.decorateRequest('utility', function () {
217
210
  })
218
211
  ```
219
212
 
220
- Note: using an arrow function will break the binding of `this` to the Fastify
213
+ Using an arrow function will break the binding of `this` to the Fastify
221
214
  `Request` instance.
222
215
 
223
- Note: using `decorateRequest` will emit an error if used with a reference type:
216
+ Using `decorateRequest` will emit an error if used with a reference type:
224
217
 
225
218
  ```js
226
219
  // Don't do this
227
220
  fastify.decorateRequest('foo', { bar: 'fizz'})
228
221
  ```
229
- In this example, the reference of the object would be shared with all the requests
230
- and **any mutation will impact all requests, potentially creating security
231
- vulnerabilities or memory leaks**, so Fastify blocks it.
222
+ In this example, the object reference would be shared with all requests, and
223
+ **any mutation will impact all requests, potentially creating security
224
+ vulnerabilities or memory leaks**. Fastify blocks this.
232
225
 
233
226
  To achieve proper encapsulation across requests configure a new value for each
234
227
  incoming request in the [`'onRequest'` hook](./Hooks.md#onrequest).
@@ -249,7 +242,7 @@ module.exports = fp(myPlugin)
249
242
  ```
250
243
 
251
244
  The hook solution is more flexible and allows for more complex initialization
252
- because you can add more logic to the `onRequest` hook.
245
+ because more logic can be added to the `onRequest` hook.
253
246
 
254
247
  Another approach is to use the getter/setter pattern, but it requires 2 decorators:
255
248
 
@@ -268,8 +261,7 @@ fastify.get('/', async function (req, reply) {
268
261
  })
269
262
  ```
270
263
 
271
- This ensures that the `user` property is always unique for each
272
- request.
264
+ This ensures that the `user` property is always unique for each request.
273
265
 
274
266
  See [`decorate`](#decorate) for information about the `dependencies` parameter.
275
267
 
@@ -305,9 +297,7 @@ fastify.hasReplyDecorator('utility')
305
297
 
306
298
  Defining a decorator (using `decorate`, `decorateRequest`, or `decorateReply`)
307
299
  with the same name more than once in the same **encapsulated** context will
308
- throw an exception.
309
-
310
- As an example, the following will throw:
300
+ throw an exception. For example, the following will throw:
311
301
 
312
302
  ```js
313
303
  const server = require('fastify')()
@@ -358,9 +348,9 @@ server.listen({ port: 3000 })
358
348
  ### Getters and Setters
359
349
  <a id="getters-setters"></a>
360
350
 
361
- Decorators accept special "getter/setter" objects. These objects have functions
362
- named `getter` and `setter` (though the `setter` function is optional). This
363
- allows defining properties via decorators, for example:
351
+ Decorators accept special "getter/setter" objects with `getter` and optional
352
+ `setter` functions. This allows defining properties via decorators,
353
+ for example:
364
354
 
365
355
  ```js
366
356
  fastify.decorate('foo', {
@@ -3,21 +3,20 @@
3
3
  ## Encapsulation
4
4
  <a id="encapsulation"></a>
5
5
 
6
- A fundamental feature of Fastify is the "encapsulation context." The
7
- encapsulation context governs which [decorators](./Decorators.md), registered
8
- [hooks](./Hooks.md), and [plugins](./Plugins.md) are available to
9
- [routes](./Routes.md). A visual representation of the encapsulation context
10
- is shown in the following figure:
6
+ A fundamental feature of Fastify is the "encapsulation context." It governs
7
+ which [decorators](./Decorators.md), registered [hooks](./Hooks.md), and
8
+ [plugins](./Plugins.md) are available to [routes](./Routes.md). A visual
9
+ representation of the encapsulation context is shown in the following figure:
11
10
 
12
11
  ![Figure 1](../resources/encapsulation_context.svg)
13
12
 
14
- In the above figure, there are several entities:
13
+ In the figure above, there are several entities:
15
14
 
16
15
  1. The _root context_
17
16
  2. Three _root plugins_
18
- 3. Two _child contexts_ where each _child context_ has
17
+ 3. Two _child contexts_, each with:
19
18
  * Two _child plugins_
20
- * One _grandchild context_ where each _grandchild context_ has
19
+ * One _grandchild context_, each with:
21
20
  - Three _child plugins_
22
21
 
23
22
  Every _child context_ and _grandchild context_ has access to the _root plugins_.
@@ -26,15 +25,14 @@ _child plugins_ registered within the containing _child context_, but the
26
25
  containing _child context_ **does not** have access to the _child plugins_
27
26
  registered within its _grandchild context_.
28
27
 
29
- Given that everything in Fastify is a [plugin](./Plugins.md), except for the
28
+ Given that everything in Fastify is a [plugin](./Plugins.md) except for the
30
29
  _root context_, every "context" and "plugin" in this example is a plugin
31
- that can consist of decorators, hooks, plugins, and routes. Thus, to put
32
- this example into concrete terms, consider a basic scenario of a REST API
33
- server that has three routes: the first route (`/one`) requires authentication,
34
- the second route (`/two`) does not, and the third route (`/three`) has
35
- access to the same context as the second route. Using
36
- [@fastify/bearer-auth][bearer] to provide the authentication, the code for this
37
- example is as follows:
30
+ that can consist of decorators, hooks, plugins, and routes. To put this
31
+ example into concrete terms, consider a basic scenario of a REST API server
32
+ with three routes: the first route (`/one`) requires authentication, the
33
+ second route (`/two`) does not, and the third route (`/three`) has access to
34
+ the same context as the second route. Using [@fastify/bearer-auth][bearer] to
35
+ provide authentication, the code for this example is as follows:
38
36
 
39
37
  ```js
40
38
  'use strict'
@@ -52,9 +50,9 @@ fastify.register(async function authenticatedContext (childServer) {
52
50
  handler (request, response) {
53
51
  response.send({
54
52
  answer: request.answer,
55
- // request.foo will be undefined as it's only defined in publicContext
53
+ // request.foo will be undefined as it is only defined in publicContext
56
54
  foo: request.foo,
57
- // request.bar will be undefined as it's only defined in grandchildContext
55
+ // request.bar will be undefined as it is only defined in grandchildContext
58
56
  bar: request.bar
59
57
  })
60
58
  }
@@ -71,7 +69,7 @@ fastify.register(async function publicContext (childServer) {
71
69
  response.send({
72
70
  answer: request.answer,
73
71
  foo: request.foo,
74
- // request.bar will be undefined as it's only defined in grandchildContext
72
+ // request.bar will be undefined as it is only defined in grandchildContext
75
73
  bar: request.bar
76
74
  })
77
75
  }
@@ -97,16 +95,16 @@ fastify.register(async function publicContext (childServer) {
97
95
  fastify.listen({ port: 8000 })
98
96
  ```
99
97
 
100
- The above server example shows all of the encapsulation concepts outlined in the
98
+ The server example above demonstrates the encapsulation concepts from the
101
99
  original diagram:
102
100
 
103
101
  1. Each _child context_ (`authenticatedContext`, `publicContext`, and
104
- `grandchildContext`) has access to the `answer` request decorator defined in
105
- the _root context_.
102
+ `grandchildContext`) has access to the `answer` request decorator defined in
103
+ the _root context_.
106
104
  2. Only the `authenticatedContext` has access to the `@fastify/bearer-auth`
107
- plugin.
105
+ plugin.
108
106
  3. Both the `publicContext` and `grandchildContext` have access to the `foo`
109
- request decorator.
107
+ request decorator.
110
108
  4. Only the `grandchildContext` has access to the `bar` request decorator.
111
109
 
112
110
  To see this, start the server and issue requests:
@@ -125,16 +123,13 @@ To see this, start the server and issue requests:
125
123
  ## Sharing Between Contexts
126
124
  <a id="shared-context"></a>
127
125
 
128
- Notice that each context in the prior example inherits _only_ from the parent
129
- contexts. Parent contexts cannot access any entities within their descendent
130
- contexts. This default is occasionally not desired. In such cases, the
131
- encapsulation context can be broken through the usage of
132
- [fastify-plugin][fastify-plugin] such that anything registered in a descendent
133
- context is available to the containing parent context.
126
+ Each context in the prior example inherits _only_ from its parent contexts. Parent
127
+ contexts cannot access entities within their descendant contexts. If needed,
128
+ encapsulation can be broken using [fastify-plugin][fastify-plugin], making
129
+ anything registered in a descendant context available to the parent context.
134
130
 
135
- Assuming the `publicContext` needs access to the `bar` decorator defined
136
- within the `grandchildContext` in the previous example, the code can be
137
- rewritten as:
131
+ To allow `publicContext` access to the `bar` decorator in `grandchildContext`,
132
+ rewrite the code as follows:
138
133
 
139
134
  ```js
140
135
  'use strict'