fastify 5.2.0 → 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 (83) hide show
  1. package/LICENSE +1 -1
  2. package/PROJECT_CHARTER.md +7 -7
  3. package/README.md +65 -67
  4. package/SPONSORS.md +2 -0
  5. package/build/build-validation.js +1 -1
  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 +52 -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 -99
  34. package/docs/Reference/Routes.md +108 -128
  35. package/docs/Reference/Server.md +19 -17
  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/errors.js +4 -0
  44. package/lib/headRoute.js +4 -2
  45. package/lib/pluginUtils.js +4 -2
  46. package/lib/reply.js +4 -0
  47. package/lib/request.js +13 -9
  48. package/lib/server.js +5 -0
  49. package/lib/validation.js +1 -1
  50. package/lib/warnings.js +9 -0
  51. package/lib/wrapThenable.js +8 -1
  52. package/package.json +28 -17
  53. package/test/build/error-serializer.test.js +2 -1
  54. package/test/bundler/esbuild/package.json +1 -1
  55. package/test/close.test.js +125 -108
  56. package/test/custom-parser-async.test.js +34 -36
  57. package/test/custom-parser.2.test.js +19 -20
  58. package/test/custom-parser.3.test.js +56 -45
  59. package/test/delete.test.js +79 -67
  60. package/test/genReqId.test.js +125 -174
  61. package/test/has-route.test.js +1 -3
  62. package/test/internals/content-type-parser.test.js +1 -1
  63. package/test/internals/errors.test.js +19 -7
  64. package/test/issue-4959.test.js +84 -0
  65. package/test/listen.1.test.js +37 -34
  66. package/test/listen.2.test.js +47 -40
  67. package/test/listen.3.test.js +28 -32
  68. package/test/listen.4.test.js +61 -45
  69. package/test/listen.5.test.js +23 -0
  70. package/test/nullable-validation.test.js +30 -27
  71. package/test/register.test.js +55 -50
  72. package/test/request-error.test.js +114 -94
  73. package/test/route-shorthand.test.js +36 -32
  74. package/test/server.test.js +0 -175
  75. package/test/stream.5.test.js +35 -33
  76. package/test/throw.test.js +87 -91
  77. package/test/toolkit.js +32 -0
  78. package/test/trust-proxy.test.js +23 -23
  79. package/test/types/instance.test-d.ts +1 -0
  80. package/test/upgrade.test.js +32 -30
  81. package/test/web-api.test.js +44 -0
  82. package/types/instance.d.ts +4 -0
  83. package/test/test-reporter.mjs +0 -68
@@ -25,11 +25,11 @@ snippet of code.
25
25
  ### Contents
26
26
 
27
27
  - [AWS](#aws)
28
+ - [Genezio](#genezio)
28
29
  - [Google Cloud Functions](#google-cloud-functions)
29
30
  - [Google Firebase Functions](#google-firebase-functions)
30
31
  - [Google Cloud Run](#google-cloud-run)
31
32
  - [Netlify Lambda](#netlify-lambda)
32
- - [Platformatic Cloud](#platformatic-cloud)
33
33
  - [Vercel](#vercel)
34
34
 
35
35
  ## AWS
@@ -129,6 +129,14 @@ If you need to integrate with more AWS services, take a look at
129
129
  [@h4ad/serverless-adapter](https://viniciusl.com.br/serverless-adapter/docs/main/frameworks/fastify)
130
130
  on Fastify to find out how to integrate.
131
131
 
132
+ ## Genezio
133
+
134
+ [Genezio](https://genezio.com/) is a platform designed to simplify the deployment
135
+ of serverless applications to the cloud.
136
+
137
+ [Genezio has a dedicated guide for deploying a Fastify application.](https://genezio.com/docs/frameworks/fastify/)
138
+
139
+
132
140
  ## Google Cloud Functions
133
141
 
134
142
  ### Creation of Fastify instance
@@ -280,8 +288,8 @@ const { onRequest } = require("firebase-functions/v2/https")
280
288
  ### Creation of Fastify instance
281
289
 
282
290
  Create the Fastify instance and encapsulate the returned application instance
283
- in a function which will register routes, await the server's processing of
284
- plugins, hooks and other settings. As follows:
291
+ in a function that will register routes, await the server's processing of
292
+ plugins, hooks, and other settings. As follows:
285
293
 
286
294
  ```js
287
295
  const fastify = require("fastify")({
@@ -299,7 +307,7 @@ const fastifyApp = async (request, reply) => {
299
307
 
300
308
  Firebase Function's HTTP layer already parses the request
301
309
  and makes a JSON payload available. It also provides access
302
- to the raw body, unparsed, which is useful in order to calculate
310
+ to the raw body, unparsed, which is useful for calculating
303
311
  request signatures to validate HTTP webhooks.
304
312
 
305
313
  Add as follows to the `registerRoutes()` function:
@@ -384,7 +392,7 @@ familiar with gcloud or just follow their
384
392
 
385
393
  ### Adjust Fastify server
386
394
 
387
- In order for Fastify to properly listen for requests within the container, be
395
+ For Fastify to properly listen for requests within the container, be
388
396
  sure to set the correct port and address:
389
397
 
390
398
  ```js
@@ -562,49 +570,7 @@ Add this command to your `package.json` *scripts*
562
570
  }
563
571
  ```
564
572
 
565
- Then it should work fine
566
-
567
- ## Platformatic Cloud
568
-
569
- [Platformatic](https://platformatic.dev) provides zero-configuration deployment
570
- for Node.js applications.
571
- To use it now, you should wrap your existing Fastify application inside a
572
- [Platformatic Service](https://oss.platformatic.dev/docs/reference/service/introduction),
573
- by running the following:
574
-
575
-
576
- ```bash
577
- npm create platformatic@latest -- service
578
- ```
579
-
580
- The wizard would ask you to fill in a few answers:
581
-
582
- ```
583
- ? Where would you like to create your project? .
584
- ? Do you want to run npm install? yes
585
- ? Do you want to use TypeScript? no
586
- ? What port do you want to use? 3042
587
- [13:04:14] INFO: Configuration file platformatic.service.json successfully created.
588
- [13:04:14] INFO: Environment file .env successfully created.
589
- [13:04:14] INFO: Plugins folder "plugins" successfully created.
590
- [13:04:14] INFO: Routes folder "routes" successfully created.
591
- ? Do you want to create the github action to deploy this application to Platformatic Cloud dynamic workspace? no
592
- ? Do you want to create the github action to deploy this application to Platformatic Cloud static workspace? no
593
- ```
594
-
595
- Then, head to [Platformatic Cloud](https://platformatic.cloud) and sign in
596
- with your GitHub account.
597
- Create your first application and a static workspace: be careful to download the
598
- API key as an env file, e.g. `yourworkspace.txt`.
599
-
600
- Then, you can easily deploy your application with the following command:
601
-
602
- ```bash
603
- platformatic deploy --keys `yourworkspace.txt`
604
- ```
605
-
606
- Check out the [Full Guide](https://blog.platformatic.dev/how-to-migrate-a-fastify-app-to-platformatic-service)
607
- on how to wrap Fastify application in Platformatic.
573
+ Then it should work fine.
608
574
 
609
575
  ## Vercel
610
576
 
@@ -83,7 +83,7 @@ Result:
83
83
 
84
84
  Make sure you avoid copying other people's work. Keep it as original as
85
85
  possible. You can learn from what they have done and reference where it is from
86
- if you used a particular quote from their work.
86
+ if you use a particular quote from their work.
87
87
 
88
88
 
89
89
  ## Word Choice
@@ -217,7 +217,7 @@ Styles](https://medium.com/better-programming/string-case-styles-camel-pascal-sn
217
217
 
218
218
  ### Hyperlinks
219
219
 
220
- Hyperlinks should have a clear title of what it references. Here is how your
220
+ Hyperlinks should have a clear title of what they reference. Here is how your
221
221
  hyperlink should look:
222
222
 
223
223
  ```MD
@@ -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', {