fastify 3.27.4 → 4.0.0-alpha.3

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 (168) hide show
  1. package/.taprc +3 -0
  2. package/README.md +7 -7
  3. package/build/build-error-serializer.js +27 -0
  4. package/build/build-validation.js +47 -35
  5. package/docs/Guides/Database.md +320 -0
  6. package/docs/Guides/Ecosystem.md +9 -0
  7. package/docs/Guides/Getting-Started.md +7 -7
  8. package/docs/Guides/Plugins-Guide.md +1 -1
  9. package/docs/Guides/Serverless.md +3 -3
  10. package/docs/Guides/Testing.md +2 -2
  11. package/docs/Migration-Guide-V4.md +12 -0
  12. package/docs/Reference/ContentTypeParser.md +4 -0
  13. package/docs/Reference/Decorators.md +2 -2
  14. package/docs/Reference/Encapsulation.md +2 -2
  15. package/docs/Reference/Errors.md +51 -6
  16. package/docs/Reference/HTTP2.md +3 -3
  17. package/docs/Reference/Hooks.md +4 -7
  18. package/docs/Reference/LTS.md +5 -4
  19. package/docs/Reference/Plugins.md +3 -3
  20. package/docs/Reference/Reply.md +73 -22
  21. package/docs/Reference/Request.md +1 -3
  22. package/docs/Reference/Routes.md +22 -15
  23. package/docs/Reference/Server.md +69 -119
  24. package/docs/Reference/TypeScript.md +20 -22
  25. package/docs/Reference/Validation-and-Serialization.md +30 -55
  26. package/docs/Type-Providers.md +257 -0
  27. package/examples/asyncawait.js +1 -1
  28. package/examples/benchmark/hooks-benchmark-async-await.js +1 -1
  29. package/examples/benchmark/hooks-benchmark.js +1 -1
  30. package/examples/benchmark/simple.js +1 -1
  31. package/examples/hooks.js +2 -2
  32. package/examples/http2.js +1 -1
  33. package/examples/https.js +1 -1
  34. package/examples/parser.js +13 -3
  35. package/examples/route-prefix.js +1 -1
  36. package/examples/shared-schema.js +1 -1
  37. package/examples/simple-stream.js +18 -0
  38. package/examples/simple.js +1 -1
  39. package/examples/simple.mjs +1 -1
  40. package/examples/typescript-server.ts +1 -1
  41. package/examples/use-plugin.js +1 -1
  42. package/fastify.d.ts +34 -22
  43. package/fastify.js +40 -36
  44. package/lib/configValidator.js +902 -1023
  45. package/lib/contentTypeParser.js +6 -16
  46. package/lib/context.js +36 -10
  47. package/lib/decorate.js +3 -1
  48. package/lib/error-handler.js +158 -0
  49. package/lib/error-serializer.js +257 -0
  50. package/lib/errors.js +51 -9
  51. package/lib/fourOhFour.js +31 -20
  52. package/lib/handleRequest.js +10 -13
  53. package/lib/hooks.js +14 -9
  54. package/lib/pluginOverride.js +0 -3
  55. package/lib/pluginUtils.js +3 -2
  56. package/lib/reply.js +121 -175
  57. package/lib/request.js +13 -10
  58. package/lib/route.js +131 -138
  59. package/lib/schema-controller.js +2 -2
  60. package/lib/schemas.js +27 -1
  61. package/lib/server.js +242 -116
  62. package/lib/symbols.js +5 -3
  63. package/lib/validation.js +11 -9
  64. package/lib/warnings.js +4 -12
  65. package/lib/wrapThenable.js +4 -11
  66. package/package.json +37 -39
  67. package/test/404s.test.js +258 -125
  68. package/test/500s.test.js +3 -3
  69. package/test/als.test.js +1 -1
  70. package/test/async-await.test.js +20 -76
  71. package/test/bodyLimit.test.js +1 -1
  72. package/test/build-certificate.js +6 -7
  73. package/test/case-insensitive.test.js +4 -4
  74. package/test/close-pipelining.test.js +2 -2
  75. package/test/close.test.js +11 -11
  76. package/test/content-parser.test.js +32 -0
  77. package/test/context-config.test.js +52 -0
  78. package/test/custom-http-server.test.js +14 -7
  79. package/test/custom-parser-async.test.js +1 -66
  80. package/test/custom-parser.test.js +92 -159
  81. package/test/custom-querystring-parser.test.js +3 -3
  82. package/test/decorator.test.js +11 -13
  83. package/test/delete.test.js +6 -6
  84. package/test/encapsulated-error-handler.test.js +50 -0
  85. package/test/esm/index.test.js +0 -14
  86. package/test/fastify-instance.test.js +4 -4
  87. package/test/fluent-schema.test.js +4 -4
  88. package/test/genReqId.test.js +1 -1
  89. package/test/get.test.js +4 -4
  90. package/test/handler-context.test.js +2 -2
  91. package/test/head.test.js +1 -1
  92. package/test/helper.js +19 -4
  93. package/test/hooks-async.test.js +15 -48
  94. package/test/hooks.on-ready.test.js +10 -5
  95. package/test/hooks.test.js +78 -119
  96. package/test/http2/closing.test.js +10 -16
  97. package/test/http2/constraint.test.js +1 -1
  98. package/test/http2/head.test.js +1 -1
  99. package/test/http2/plain.test.js +1 -1
  100. package/test/http2/secure-with-fallback.test.js +1 -1
  101. package/test/http2/secure.test.js +1 -1
  102. package/test/http2/unknown-http-method.test.js +4 -10
  103. package/test/https/custom-https-server.test.js +12 -6
  104. package/test/https/https.test.js +1 -1
  105. package/test/input-validation.js +3 -3
  106. package/test/internals/handleRequest.test.js +6 -43
  107. package/test/internals/initialConfig.test.js +41 -12
  108. package/test/internals/logger.test.js +2 -2
  109. package/test/internals/reply.test.js +317 -48
  110. package/test/internals/request.test.js +13 -7
  111. package/test/internals/server.test.js +88 -0
  112. package/test/listen.deprecated.test.js +202 -0
  113. package/test/listen.test.js +140 -145
  114. package/test/logger.test.js +82 -42
  115. package/test/maxRequestsPerSocket.test.js +8 -6
  116. package/test/middleware.test.js +2 -25
  117. package/test/nullable-validation.test.js +53 -16
  118. package/test/output-validation.test.js +1 -1
  119. package/test/plugin.test.js +47 -21
  120. package/test/pretty-print.test.js +22 -10
  121. package/test/promises.test.js +1 -1
  122. package/test/proto-poisoning.test.js +6 -6
  123. package/test/register.test.js +3 -3
  124. package/test/reply-error.test.js +126 -15
  125. package/test/reply-trailers.test.js +270 -0
  126. package/test/request-error.test.js +3 -6
  127. package/test/route-hooks.test.js +18 -18
  128. package/test/route-prefix.test.js +2 -1
  129. package/test/route.test.js +206 -22
  130. package/test/router-options.test.js +2 -2
  131. package/test/schema-examples.test.js +11 -5
  132. package/test/schema-feature.test.js +25 -20
  133. package/test/schema-serialization.test.js +9 -9
  134. package/test/schema-special-usage.test.js +5 -153
  135. package/test/schema-validation.test.js +9 -9
  136. package/test/skip-reply-send.test.js +2 -2
  137. package/test/stream.test.js +82 -23
  138. package/test/throw.test.js +8 -5
  139. package/test/trust-proxy.test.js +6 -6
  140. package/test/type-provider.test.js +20 -0
  141. package/test/types/fastify.test-d.ts +10 -18
  142. package/test/types/hooks.test-d.ts +61 -5
  143. package/test/types/import.js +2 -0
  144. package/test/types/import.ts +1 -0
  145. package/test/types/instance.test-d.ts +68 -17
  146. package/test/types/logger.test-d.ts +44 -15
  147. package/test/types/reply.test-d.ts +2 -1
  148. package/test/types/request.test-d.ts +71 -1
  149. package/test/types/route.test-d.ts +8 -2
  150. package/test/types/schema.test-d.ts +2 -39
  151. package/test/types/type-provider.test-d.ts +424 -0
  152. package/test/url-rewriting.test.js +3 -3
  153. package/test/validation-error-handling.test.js +8 -8
  154. package/test/versioned-routes.test.js +30 -18
  155. package/test/wrapThenable.test.js +7 -6
  156. package/types/content-type-parser.d.ts +17 -8
  157. package/types/hooks.d.ts +182 -85
  158. package/types/instance.d.ts +286 -118
  159. package/types/logger.d.ts +18 -104
  160. package/types/plugin.d.ts +10 -4
  161. package/types/reply.d.ts +18 -12
  162. package/types/request.d.ts +13 -8
  163. package/types/route.d.ts +62 -34
  164. package/types/schema.d.ts +1 -1
  165. package/types/type-provider.d.ts +99 -0
  166. package/types/utils.d.ts +1 -1
  167. package/lib/schema-compilers.js +0 -12
  168. package/test/emit-warning.test.js +0 -166
@@ -21,6 +21,9 @@ available only in that scope and its children.
21
21
  Fastify automatically adds the parsed request payload to the [Fastify
22
22
  request](./Request.md) object which you can access with `request.body`.
23
23
 
24
+ Note that for `GET` and `HEAD` requests the payload is never parsed. For `OPTIONS` and `DELETE` requests the payload is only parsed if
25
+ the content type is given in the content-type header. If it is not given, the [catch-all](#catch-all) parser is not executed as with `POST`, `PUT` and `PATCH`, but the payload is simply not parsed.
26
+
24
27
  ### Usage
25
28
  ```js
26
29
  fastify.addContentTypeParser('application/jsoff', function (request, payload, done) {
@@ -90,6 +93,7 @@ if (!fastify.hasContentTypeParser('application/jsoff')){
90
93
  }
91
94
  ```
92
95
 
96
+ =======
93
97
  #### removeContentTypeParser
94
98
 
95
99
  With `removeContentTypeParser` a single or an array of content types can be
@@ -265,7 +265,7 @@ server.decorateReply('view', function (template, args) {
265
265
  // Another rendering engine
266
266
  })
267
267
 
268
- server.listen(3000)
268
+ server.listen({ port: 3000 })
269
269
  ```
270
270
 
271
271
 
@@ -291,7 +291,7 @@ server.register(async function (server, opts) {
291
291
  })
292
292
  }, { prefix: '/bar' })
293
293
 
294
- server.listen(3000)
294
+ server.listen({ port: 3000 })
295
295
  ```
296
296
 
297
297
  ### Getters and Setters
@@ -94,7 +94,7 @@ fastify.register(async function publicContext (childServer) {
94
94
  })
95
95
  })
96
96
 
97
- fastify.listen(8000)
97
+ fastify.listen({ port: 8000 })
98
98
  ```
99
99
 
100
100
  The above server example shows all of the encapsulation concepts outlined in the
@@ -180,7 +180,7 @@ fastify.register(async function publicContext (childServer) {
180
180
  }
181
181
  })
182
182
 
183
- fastify.listen(8000)
183
+ fastify.listen({ port: 8000 })
184
184
  ```
185
185
 
186
186
  Restarting the server and re-issuing the requests for `/two` and `/three`:
@@ -56,9 +56,19 @@ From the [Hooks documentation](./Hooks.md#manage-errors-from-a-hook):
56
56
  > `done()` and Fastify will automatically close the request and send the
57
57
  > appropriate error code to the user.
58
58
 
59
- If you have defined a custom error handler for using `setErrorHandler` the error
60
- will be routed there. otherwise, it will be routed to Fastify’s generic error
61
- handler.
59
+ When a custom error handler has been defined through
60
+ [`setErrorHandler`](./Server.md#seterrorhandler), the custom error handler will
61
+ receive the error passed to the `done()` callback (or through other supported
62
+ automatic error handling mechanisms). If `setErrorHandler` has been used
63
+ multiple times to define multiple handlers, the error will be routed to the most
64
+ precedent handler defined within the error [encapsulation context](./Encapsulation.md).
65
+ Error handlers are fully encapsulated, so a `setErrorHandler` call within a
66
+ plugin will limit the error handler to that plugin's context.
67
+
68
+ The root error handler is Fastify's generic error handler. This error handler
69
+ will use the headers and status code in the `Error` object, if they exist. The
70
+ headers and status code will not be automatically set if a custom error handler
71
+ is provided.
62
72
 
63
73
  Some things to consider in your custom error handler:
64
74
 
@@ -70,13 +80,12 @@ Some things to consider in your custom error handler:
70
80
  headers (no serialization)
71
81
 
72
82
  - You can throw a new error in your custom error handler
73
- - errors (new error or the received error parameter re-thrown) - will trigger
74
- the `onError` lifecycle hook and send the error to the user
83
+ - errors (new error or the received error parameter re-thrown) - will call the parent `errorHandler`.
84
+ - `onError` hook will be triggered once only for the first error being thrown.
75
85
  - an error will not be triggered twice from a lifecycle hook - Fastify
76
86
  internally monitors the error invocation to avoid infinite loops for errors
77
87
  thrown in the reply phases of the lifecycle. (those after the route handler)
78
88
 
79
-
80
89
  ### Fastify Error Codes
81
90
  <a id="fastify-error-codes"></a>
82
91
 
@@ -85,6 +94,12 @@ Some things to consider in your custom error handler:
85
94
 
86
95
  The router received an invalid url.
87
96
 
97
+ <a name="FST_ERR_DUPLICATED_ROUTE"></a>
98
+ #### FST_ERR_DUPLICATED_ROUTE
99
+
100
+ The HTTP method already has a registered controller for that URL
101
+
102
+ <a name="FST_ERR_CTP_ALREADY_PRESENT"></a>
88
103
  #### FST_ERR_CTP_ALREADY_PRESENT
89
104
  <a id="FST_ERR_CTP_ALREADY_PRESENT"></a>
90
105
 
@@ -199,3 +214,33 @@ You cannot use `send` inside the `onError` hook.
199
214
  <a id="FST_ERR_SEND_UNDEFINED_ERR"></a>
200
215
 
201
216
  Undefined error has occurred.
217
+
218
+ <a name="FST_ERR_PLUGIN_NOT_VALID"></a>
219
+ #### FST_ERR_PLUGIN_NOT_VALID
220
+
221
+ Plugin must be a function or a promise.
222
+
223
+ <a name="FST_ERR_PLUGIN_TIMEOUT"></a>
224
+ #### FST_ERR_PLUGIN_TIMEOUT
225
+
226
+ Plugin did not start in time. Default timeout (in millis): `10000`
227
+
228
+ <a name="FST_ERR_HOOK_TIMEOUT"></a>
229
+ #### FST_ERR_HOOK_TIMEOUT
230
+
231
+ A callback for a hook timed out
232
+
233
+ <a name="FST_ERR_ROOT_PLG_BOOTED"></a>
234
+ #### FST_ERR_ROOT_PLG_BOOTED
235
+
236
+ Root plugin has already booted (mapped directly from `avvio`)
237
+
238
+ <a name="FST_ERR_PARENT_PLUGIN_BOOTED"></a>
239
+ #### FST_ERR_PARENT_PLUGIN_BOOTED
240
+
241
+ Impossible to load plugin because the parent (mapped directly from `avvio`)
242
+
243
+ <a name="FST_ERR_PLUGIN_CALLBACK_NOT_FN"></a>
244
+ #### FST_ERR_PLUGIN_CALLBACK_NOT_FN
245
+
246
+ Callback for a hook is not a function (mapped directly from `avvio`)
@@ -31,7 +31,7 @@ fastify.get('/', function (request, reply) {
31
31
  reply.code(200).send({ hello: 'world' })
32
32
  })
33
33
 
34
- fastify.listen(3000)
34
+ fastify.listen({ port: 3000 })
35
35
  ```
36
36
 
37
37
  ALPN negotiation allows support for both HTTPS and HTTP/2 over the same socket.
@@ -59,7 +59,7 @@ fastify.get('/', function (request, reply) {
59
59
  reply.code(200).send({ hello: 'world' })
60
60
  })
61
61
 
62
- fastify.listen(3000)
62
+ fastify.listen({ port: 3000 })
63
63
  ```
64
64
 
65
65
  You can test your new server with:
@@ -84,7 +84,7 @@ fastify.get('/', function (request, reply) {
84
84
  reply.code(200).send({ hello: 'world' })
85
85
  })
86
86
 
87
- fastify.listen(3000)
87
+ fastify.listen({ port: 3000 })
88
88
  ```
89
89
 
90
90
  You can test your new server with:
@@ -65,7 +65,7 @@ fastify.addHook('onRequest', async (request, reply) => {
65
65
  ```
66
66
 
67
67
  **Notice:** in the [onRequest](#onrequest) hook, `request.body` will always be
68
- `null`, because the body parsing happens before the
68
+ `undefined`, because the body parsing happens before the
69
69
  [preValidation](#prevalidation) hook.
70
70
 
71
71
  ### preParsing
@@ -95,7 +95,7 @@ fastify.addHook('preParsing', async (request, reply, payload) => {
95
95
  ```
96
96
 
97
97
  **Notice:** in the [preParsing](#preparsing) hook, `request.body` will always be
98
- `null`, because the body parsing happens before the
98
+ `undefined`, because the body parsing happens before the
99
99
  [preValidation](#prevalidation) hook.
100
100
 
101
101
  **Notice:** you should also add a `receivedEncodedLength` property to the
@@ -103,10 +103,6 @@ returned stream. This property is used to correctly match the request payload
103
103
  with the `Content-Length` header value. Ideally, this property should be updated
104
104
  on each received chunk.
105
105
 
106
- **Notice**: The old syntaxes `function(request, reply, done)` and `async
107
- function(request, reply)` for the parser are still supported but they are
108
- deprecated.
109
-
110
106
  ### preValidation
111
107
 
112
108
  If you are using the `preValidation` hook, you can change the payload before it
@@ -322,7 +318,7 @@ fastify.addHook('onRequest', (request, reply, done) => {
322
318
  fastify.addHook('preHandler', async (request, reply) => {
323
319
  await something()
324
320
  reply.send({ hello: 'world' })
325
- return reply // optional in this case, but it is a good practice
321
+ return reply // mandatory, so the request is not executed further
326
322
  })
327
323
  ```
328
324
 
@@ -419,6 +415,7 @@ fastify.addHook('onClose', async (instance) => {
419
415
  Triggered when a new route is registered. Listeners are passed a `routeOptions`
420
416
  object as the sole parameter. The interface is synchronous, and, as such, the
421
417
  listeners are not passed a callback. This hook is encapsulated.
418
+
422
419
  ```js
423
420
  fastify.addHook('onRoute', (routeOptions) => {
424
421
  //Some code
@@ -48,6 +48,7 @@ A "month" is defined as 30 consecutive days.
48
48
  | 1.0.0 | 2018-03-06 | 2019-09-01 | 6, 8, 9, 10, 11 |
49
49
  | 2.0.0 | 2019-02-25 | 2021-01-31 | 6, 8, 10, 12, 14 |
50
50
  | 3.0.0 | 2020-07-07 | TBD | 10, 12, 14, 16 |
51
+ | 4.0.0 | TBD | TBD | 14, 16 |
51
52
 
52
53
  ### CI tested operating systems
53
54
  <a id="supported-os"></a>
@@ -60,10 +61,10 @@ YAML workflow labels below:
60
61
 
61
62
  | OS | YAML Workflow Label | Package Manager | Node.js |
62
63
  |---------|------------------------|---------------------------|--------------|
63
- | Linux | `ubuntu-latest` | npm | 10,12,14,16 |
64
- | Linux | `ubuntu-18.04` | yarn,pnpm | 10,12 |
65
- | Windows | `windows-latest` | npm | 10,12,14,16 |
66
- | MacOS | `macos-latest` | npm | 10,12,14,16 |
64
+ | Linux | `ubuntu-latest` | npm | 14,16 |
65
+ | Linux | `ubuntu-18.04` | yarn,pnpm | 14,16 |
66
+ | Windows | `windows-latest` | npm | 14,16 |
67
+ | MacOS | `macos-latest` | npm | 14,16 |
67
68
 
68
69
  Using [yarn](https://yarnpkg.com/) might require passing the `--ignore-engines`
69
70
  flag.
@@ -124,7 +124,7 @@ fastify.ready(err => console.log(err))
124
124
 
125
125
  // `listen` is a special ready,
126
126
  // so it behaves in the same way
127
- fastify.listen(3000, (err, address) => {
127
+ fastify.listen({ port: 3000 }, (err, address) => {
128
128
  if (err) console.log(err)
129
129
  })
130
130
  ```
@@ -142,7 +142,7 @@ await fastify.after()
142
142
 
143
143
  await fastify.ready()
144
144
 
145
- await fastify.listen(3000)
145
+ await fastify.listen({ port: 3000 })
146
146
  ```
147
147
 
148
148
  #### ESM support
@@ -158,7 +158,7 @@ const fastify = Fastify()
158
158
 
159
159
  fastify.register(import('./plugin.mjs'))
160
160
 
161
- fastify.listen(3000, console.log)
161
+ fastify.listen({ port: 3000 }, console.log)
162
162
 
163
163
 
164
164
  // plugin.mjs
@@ -13,6 +13,9 @@
13
13
  - [.getHeaders()](#getheaders)
14
14
  - [.removeHeader(key)](#removeheaderkey)
15
15
  - [.hasHeader(key)](#hasheaderkey)
16
+ - [.trailer(key, function)](#trailerkey-function)
17
+ - [.hasTrailer(key)](#hastrailerkey)
18
+ - [.removeTrailer(key)](#removetrailerkey)
16
19
  - [.redirect([code,] dest)](#redirectcode--dest)
17
20
  - [.callNotFound()](#callnotfound)
18
21
  - [.getResponseTime()](#getresponsetime)
@@ -47,6 +50,9 @@ object that exposes the following functions and properties:
47
50
  - `.getHeaders()` - Gets a shallow copy of all current response headers.
48
51
  - `.removeHeader(key)` - Remove the value of a previously set header.
49
52
  - `.hasHeader(name)` - Determine if a header has been set.
53
+ - `.trailer(key, function)` - Sets a response trailer.
54
+ - `.hasTrailer(key)` - Determine if a trailer has been set.
55
+ - `.removeTrailer(key)` - Remove the value of a previously set trailer.
50
56
  - `.type(value)` - Sets the header `Content-Type`.
51
57
  - `.redirect([code,] dest)` - Redirect to the specified url, the status code is
52
58
  optional (default to `302`).
@@ -59,12 +65,10 @@ object that exposes the following functions and properties:
59
65
  buffer, JSON, stream, or an Error object.
60
66
  - `.sent` - A boolean value that you can use if you need to know if `send` has
61
67
  already been called.
68
+ - `.hijack()` - interrupt the normal request lifecycle.
62
69
  - `.raw` - The
63
70
  [`http.ServerResponse`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_class_http_serverresponse)
64
71
  from Node core.
65
- - `.res` *(deprecated, use `.raw` instead)* - The
66
- [`http.ServerResponse`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_class_http_serverresponse)
67
- from Node core.
68
72
  - `.log` - The logger instance of the incoming request.
69
73
  - `.request` - The incoming request.
70
74
  - `.context` - Access the [Request's context](./Request.md) property.
@@ -125,6 +129,8 @@ fastify.get('/', async function (req, rep) {
125
129
  Sets a response header. If the value is omitted or undefined, it is coerced to
126
130
  `''`.
127
131
 
132
+ > Note: the header's value must be properly encoded using [`encodeURI`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI) or similar modules such as [`encodeurl`](https://www.npmjs.com/package/encodeurl). Invalid characters will result in a 500 `TypeError` response.
133
+
128
134
  For more information, see
129
135
  [`http.ServerResponse#setHeader`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_response_setheader_name_value).
130
136
 
@@ -199,12 +205,57 @@ reply.getHeader('x-foo') // undefined
199
205
 
200
206
  Returns a boolean indicating if the specified header has been set.
201
207
 
208
+ ### .trailer(key, function)
209
+ <a id="trailer"></a>
210
+
211
+ Sets a response trailer. Trailer usually used when you want some header that require heavy resources to be sent after the `data`, for example `Server-Timing`, `Etag`. It can ensure the client get the response data as soon as possible.
212
+
213
+ *Note: The header `Transfer-Encoding: chunked` will be added once you use the trailer. It is a hard requipment for using trailer in Node.js.*
214
+
215
+ *Note: Currently, the computation function only supports synchronous function. That means `async-await` and `promise` are not supported.*
216
+
217
+ ```js
218
+ reply.trailer('server-timing', function() {
219
+ return 'db;dur=53, app;dur=47.2'
220
+ })
221
+
222
+ const { createHash } = require('crypto')
223
+ // trailer function also recieve two argument
224
+ // @param {object} reply fastify reply
225
+ // @param {string|Buffer|null} payload payload that already sent, note that it will be null when stream is sent
226
+ reply.trailer('content-md5', function(reply, payload) {
227
+ const hash = createHash('md5')
228
+ hash.update(payload)
229
+ return hash.disgest('hex')
230
+ })
231
+ ```
232
+
233
+ ### .hasTrailer(key)
234
+ <a id="hasTrailer"></a>
235
+
236
+ Returns a boolean indicating if the specified trailer has been set.
237
+
238
+ ### .removeTrailer(key)
239
+ <a id="removeTrailer"></a>
240
+
241
+ Remove the value of a previously set trailer.
242
+ ```js
243
+ reply.trailer('server-timing', function() {
244
+ return 'db;dur=53, app;dur=47.2'
245
+ })
246
+ reply.removeTrailer('server-timing')
247
+ reply.getTrailer('server-timing') // undefined
248
+ ```
249
+
250
+
202
251
  ### .redirect([code ,] dest)
203
252
  <a id="redirect"></a>
204
253
 
205
254
  Redirects a request to the specified URL, the status code is optional, default
206
255
  to `302` (if status code is not already set by calling `code`).
207
256
 
257
+ > Note: the input URL must be properly encoded using [`encodeURI`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI) or similar modules such as [`encodeurl`](https://www.npmjs.com/package/encodeurl). Invalid URLs will result in a 500 `TypeError` response.
258
+
208
259
  Example (no `reply.code()` call) sets status code to `302` and redirects to
209
260
  `/home`
210
261
  ```js
@@ -259,6 +310,7 @@ Sets the content type for the response. This is a shortcut for
259
310
  ```js
260
311
  reply.type('text/html')
261
312
  ```
313
+ If the `Content-Type` has a JSON subtype, and the charset parameter is not set, `utf-8` will be used as the charset by default.
262
314
 
263
315
  ### .serializer(func)
264
316
  <a id="serializer"></a>
@@ -315,39 +367,38 @@ Another example of the misuse of `Reply.raw` is explained in
315
367
 
316
368
  As the name suggests, `.sent` is a property to indicate if a response has been
317
369
  sent via `reply.send()`.
370
+ It will also be `true` in case `reply.hijack()` was used.
318
371
 
319
372
  In case a route handler is defined as an async function or it returns a promise,
320
- it is possible to set `reply.sent = true` to indicate that the automatic
373
+ it is possible to call `reply.hijack()` to indicate that the automatic
321
374
  invocation of `reply.send()` once the handler promise resolve should be skipped.
322
- By setting `reply.sent = true`, an application claims full responsibility for
375
+ By calling `reply.hijack()`, an application claims full responsibility for
323
376
  the low-level request and response. Moreover, hooks will not be invoked.
324
377
 
325
- As an example:
378
+ *Modifying the `.sent` property directly is deprecated. Please use the aformentioned
379
+ `.hijack()` method to achieve the same effect.*
380
+
381
+ <a name="hijack"></a>
382
+ ### .hijack()
383
+ Sometimes you might need to halt the execution of the normal request lifecycle and
384
+ handle sending the response manually.
385
+
386
+ To achieve this, Fastify provides the `reply.hijack()` method that can be called
387
+ during the request lifecycle (At any point before `reply.send()` is called), and
388
+ allows you to prevent Fastify from sending the response, and from running the
389
+ remaining hooks (and user handler if the reply was hijacked before).
326
390
 
327
391
  ```js
328
392
  app.get('/', (req, reply) => {
329
- reply.sent = true
393
+ reply.hijack()
330
394
  reply.raw.end('hello world')
331
395
 
332
396
  return Promise.resolve('this will be skipped')
333
397
  })
334
398
  ```
335
399
 
336
- If the handler rejects, the error will be logged.
337
-
338
- ### .hijack()
339
- <a id="hijack"></a>
340
-
341
- Sometimes you might need to halt the execution of the normal request lifecycle
342
- and handle sending the response manually.
343
-
344
- To achieve this, Fastify provides the `reply.hijack()` method that can be called
345
- during the request lifecycle (At any point before `reply.send()` is called), and
346
- allows you to prevent Fastify from sending the response, and from running the
347
- remaining hooks (and user handler if the reply was hijacked before).
348
-
349
- NB (*): If `reply.raw` is used to send a response back to the user, `onResponse`
350
- hooks will still be executed
400
+ If `reply.raw` is used to send a response back to the user, the `onResponse`
401
+ hooks will still be executed.
351
402
 
352
403
  ### .send(data)
353
404
  <a id="send"></a>
@@ -12,10 +12,8 @@ Request is a core Fastify object containing the following fields:
12
12
  - `params` - the params matching the URL
13
13
  - [`headers`](#headers) - the headers getter and setter
14
14
  - `raw` - the incoming HTTP request from Node core
15
- - `req` *(deprecated, use `.raw` instead)* - the incoming HTTP request from Node
16
- core
17
15
  - `server` - The Fastify server instance, scoped to the current [encapsulation
18
- context](./Encapsulation.md)
16
+ >>>>>>> main:docs/Reference/Request.md
19
17
  - `id` - the request ID
20
18
  - `log` - the logger instance of the incoming request
21
19
  - `ip` - the IP address of the incoming request
@@ -32,7 +32,7 @@ fastify.route(options)
32
32
  ### Routes options
33
33
  <a id="options"></a>
34
34
 
35
- * `method`: currently it supports `'DELETE'`, `'GET'`, `'HEAD'`, `'PATCH'`,
35
+ *`method`: currently it supports `'DELETE'`, `'GET'`, `'HEAD'`, `'PATCH'`,
36
36
  `'POST'`, `'PUT'` and `'OPTIONS'`. It could also be an array of methods.
37
37
  * `url`: the path of the URL to match this route (alias: `path`).
38
38
  * `schema`: an object containing the schemas for the request and response. They
@@ -54,6 +54,7 @@ fastify.route(options)
54
54
  option, make sure to define it before the `GET` route.
55
55
  * `attachValidation`: attach `validationError` to request, if there is a schema
56
56
  validation error, instead of sending the error to the error handler.
57
+ The default [error format](https://ajv.js.org/api.html#error-objects) is the Ajv one.
57
58
  * `onRequest(request, reply, done)`: a [function](./Hooks.md#onrequest) as soon
58
59
  that a request is received, it could also be an array of functions.
59
60
  * `preParsing(request, reply, done)`: a [function](./Hooks.md#preparsing) called
@@ -280,11 +281,14 @@ As you can see, we are not calling `reply.send` to send back the data to the
280
281
  user. You just need to return the body and you are done!
281
282
 
282
283
  If you need it you can also send back the data to the user with `reply.send`.
284
+ In this case do not forget to `return reply` or `await reply` in your `async`
285
+ handler or you will introduce a race condition in certain situations.
286
+
283
287
  ```js
284
288
  fastify.get('/', options, async function (request, reply) {
285
289
  var data = await getData()
286
290
  var processed = await processData(data)
287
- reply.send(processed)
291
+ return reply.send(processed)
288
292
  })
289
293
  ```
290
294
 
@@ -316,24 +320,27 @@ fastify.get('/', options, async function (request, reply) {
316
320
  first one that happens takes precedence, the second value will be discarded,
317
321
  and a *warn* log will also be emitted because you tried to send a response
318
322
  twice.
323
+ * Calling `reply.send()` outside of the promise is possible, but requires
324
+ special attention. For more details read
325
+ [promise-resolution](#promise-resolution).
319
326
  * You cannot return `undefined`. For more details read
320
327
  [promise-resolution](#promise-resolution).
321
328
 
322
329
  ### Promise resolution
323
330
  <a id="promise-resolution"></a>
324
331
 
325
- If your handler is an `async` function or returns a promise, you should be aware
326
- of a special behavior that is necessary to support the callback and promise
327
- control-flow. If the handler's promise is resolved with `undefined`, it will be
328
- ignored causing the request to hang and an *error* log to be emitted.
332
+ If your handler is an `async` function or returns a promise, you should be aware of
333
+ a special behaviour which is necessary to support the callback and promise
334
+ control-flow. When the handler's promise is resolved, the reply will be
335
+ automatically sent with its value unless you explicitly await or return `reply`
336
+ in your handler.
329
337
 
330
- 1. If you want to use `async/await` or promises but return a value with
331
- `reply.send`:
332
- - **Do not** `return` any value.
338
+ 1. If you want to use `async/await` or promises but respond a value with `reply.send`:
339
+ - **Do** `return reply` / `await reply`.
333
340
  - **Do not** forget to call `reply.send`.
334
341
  2. If you want to use `async/await` or promises:
335
342
  - **Do not** use `reply.send`.
336
- - **Do not** return `undefined`.
343
+ - **Do** return the value that you want to send.
337
344
 
338
345
  In this way, we can support both `callback-style` and `async-await`, with the
339
346
  minimum trade-off. In spite of so much freedom we highly recommend to go with
@@ -358,7 +365,7 @@ const fastify = require('fastify')()
358
365
  fastify.register(require('./routes/v1/users'), { prefix: '/v1' })
359
366
  fastify.register(require('./routes/v2/users'), { prefix: '/v2' })
360
367
 
361
- fastify.listen(3000)
368
+ fastify.listen({ port: 3000 })
362
369
  ```
363
370
 
364
371
  ```js
@@ -420,7 +427,7 @@ const fastify = require('fastify')({ logger: true })
420
427
  fastify.register(require('./routes/user'), { logLevel: 'warn' })
421
428
  fastify.register(require('./routes/events'), { logLevel: 'debug' })
422
429
 
423
- fastify.listen(3000)
430
+ fastify.listen({ port: 3000 })
424
431
  ```
425
432
 
426
433
  Or you can directly pass it to a route:
@@ -454,7 +461,7 @@ fastify.register(require('./routes/events'), {
454
461
  }
455
462
  })
456
463
 
457
- fastify.listen(3000)
464
+ fastify.listen({ port: 3000 })
458
465
  ```
459
466
 
460
467
  You can inherit serializers by context:
@@ -492,7 +499,7 @@ async function context1 (fastify, opts) {
492
499
  })
493
500
  }
494
501
 
495
- fastify.listen(3000)
502
+ fastify.listen({ port: 3000 })
496
503
  ```
497
504
 
498
505
  ### Config
@@ -512,7 +519,7 @@ function handler (req, reply) {
512
519
  fastify.get('/en', { config: { output: 'hello world!' } }, handler)
513
520
  fastify.get('/it', { config: { output: 'ciao mondo!' } }, handler)
514
521
 
515
- fastify.listen(3000)
522
+ fastify.listen({ port: 3000 })
516
523
  ```
517
524
 
518
525
  ### Constraints