fastify 3.27.3 → 4.0.0-alpha.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 (164) 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/Getting-Started.md +7 -7
  7. package/docs/Guides/Plugins-Guide.md +1 -1
  8. package/docs/Guides/Serverless.md +3 -3
  9. package/docs/Guides/Testing.md +2 -2
  10. package/docs/Migration-Guide-V4.md +12 -0
  11. package/docs/Reference/ContentTypeParser.md +4 -0
  12. package/docs/Reference/Decorators.md +2 -2
  13. package/docs/Reference/Encapsulation.md +2 -2
  14. package/docs/Reference/Errors.md +51 -6
  15. package/docs/Reference/HTTP2.md +3 -3
  16. package/docs/Reference/Hooks.md +4 -7
  17. package/docs/Reference/LTS.md +5 -4
  18. package/docs/Reference/Plugins.md +3 -3
  19. package/docs/Reference/Reply.md +23 -22
  20. package/docs/Reference/Request.md +1 -3
  21. package/docs/Reference/Routes.md +22 -15
  22. package/docs/Reference/Server.md +69 -119
  23. package/docs/Reference/TypeScript.md +20 -22
  24. package/docs/Reference/Validation-and-Serialization.md +30 -55
  25. package/docs/Type-Providers.md +257 -0
  26. package/examples/asyncawait.js +1 -1
  27. package/examples/benchmark/hooks-benchmark-async-await.js +1 -1
  28. package/examples/benchmark/hooks-benchmark.js +1 -1
  29. package/examples/benchmark/simple.js +1 -1
  30. package/examples/hooks.js +2 -2
  31. package/examples/http2.js +1 -1
  32. package/examples/https.js +1 -1
  33. package/examples/parser.js +1 -1
  34. package/examples/route-prefix.js +1 -1
  35. package/examples/shared-schema.js +1 -1
  36. package/examples/simple-stream.js +18 -0
  37. package/examples/simple.js +1 -1
  38. package/examples/simple.mjs +1 -1
  39. package/examples/typescript-server.ts +1 -1
  40. package/examples/use-plugin.js +1 -1
  41. package/fastify.d.ts +34 -22
  42. package/fastify.js +40 -36
  43. package/lib/configValidator.js +902 -1023
  44. package/lib/contentTypeParser.js +6 -16
  45. package/lib/context.js +36 -10
  46. package/lib/decorate.js +3 -1
  47. package/lib/error-handler.js +158 -0
  48. package/lib/error-serializer.js +257 -0
  49. package/lib/errors.js +43 -9
  50. package/lib/fourOhFour.js +31 -20
  51. package/lib/handleRequest.js +10 -13
  52. package/lib/hooks.js +14 -9
  53. package/lib/pluginOverride.js +0 -3
  54. package/lib/pluginUtils.js +3 -2
  55. package/lib/reply.js +29 -158
  56. package/lib/request.js +13 -10
  57. package/lib/route.js +131 -138
  58. package/lib/schema-controller.js +2 -2
  59. package/lib/schemas.js +27 -1
  60. package/lib/server.js +241 -116
  61. package/lib/symbols.js +4 -3
  62. package/lib/validation.js +2 -1
  63. package/lib/warnings.js +4 -12
  64. package/lib/wrapThenable.js +4 -11
  65. package/package.json +37 -39
  66. package/test/404s.test.js +258 -125
  67. package/test/500s.test.js +3 -3
  68. package/test/als.test.js +1 -1
  69. package/test/async-await.test.js +20 -76
  70. package/test/bodyLimit.test.js +1 -1
  71. package/test/build-certificate.js +6 -7
  72. package/test/case-insensitive.test.js +4 -4
  73. package/test/close-pipelining.test.js +2 -2
  74. package/test/close.test.js +11 -11
  75. package/test/content-parser.test.js +32 -0
  76. package/test/context-config.test.js +52 -0
  77. package/test/custom-http-server.test.js +14 -7
  78. package/test/custom-parser-async.test.js +1 -66
  79. package/test/custom-parser.test.js +92 -159
  80. package/test/custom-querystring-parser.test.js +3 -3
  81. package/test/decorator.test.js +11 -13
  82. package/test/delete.test.js +6 -6
  83. package/test/encapsulated-error-handler.test.js +50 -0
  84. package/test/esm/index.test.js +0 -14
  85. package/test/fastify-instance.test.js +4 -4
  86. package/test/fluent-schema.test.js +4 -4
  87. package/test/genReqId.test.js +1 -1
  88. package/test/get.test.js +4 -4
  89. package/test/handler-context.test.js +2 -2
  90. package/test/head.test.js +1 -1
  91. package/test/helper.js +19 -4
  92. package/test/hooks-async.test.js +15 -48
  93. package/test/hooks.on-ready.test.js +10 -5
  94. package/test/hooks.test.js +78 -119
  95. package/test/http2/closing.test.js +10 -16
  96. package/test/http2/constraint.test.js +1 -1
  97. package/test/http2/head.test.js +1 -1
  98. package/test/http2/plain.test.js +1 -1
  99. package/test/http2/secure-with-fallback.test.js +1 -1
  100. package/test/http2/secure.test.js +1 -1
  101. package/test/http2/unknown-http-method.test.js +4 -10
  102. package/test/https/custom-https-server.test.js +12 -6
  103. package/test/https/https.test.js +1 -1
  104. package/test/input-validation.js +3 -3
  105. package/test/internals/handleRequest.test.js +6 -43
  106. package/test/internals/initialConfig.test.js +41 -12
  107. package/test/internals/logger.test.js +2 -2
  108. package/test/internals/reply.test.js +281 -40
  109. package/test/internals/request.test.js +13 -7
  110. package/test/internals/server.test.js +88 -0
  111. package/test/listen.deprecated.test.js +202 -0
  112. package/test/listen.test.js +118 -150
  113. package/test/logger.test.js +82 -42
  114. package/test/maxRequestsPerSocket.test.js +8 -6
  115. package/test/middleware.test.js +2 -25
  116. package/test/nullable-validation.test.js +53 -16
  117. package/test/output-validation.test.js +1 -1
  118. package/test/plugin.test.js +47 -21
  119. package/test/pretty-print.test.js +22 -10
  120. package/test/promises.test.js +1 -1
  121. package/test/proto-poisoning.test.js +6 -6
  122. package/test/register.test.js +3 -3
  123. package/test/reply-error.test.js +126 -15
  124. package/test/request-error.test.js +3 -6
  125. package/test/route-hooks.test.js +18 -18
  126. package/test/route-prefix.test.js +2 -1
  127. package/test/route.test.js +206 -22
  128. package/test/router-options.test.js +2 -2
  129. package/test/schema-examples.test.js +11 -5
  130. package/test/schema-feature.test.js +25 -20
  131. package/test/schema-serialization.test.js +9 -9
  132. package/test/schema-special-usage.test.js +5 -153
  133. package/test/schema-validation.test.js +9 -9
  134. package/test/skip-reply-send.test.js +2 -2
  135. package/test/stream.test.js +82 -23
  136. package/test/throw.test.js +8 -5
  137. package/test/trust-proxy.test.js +6 -6
  138. package/test/type-provider.test.js +20 -0
  139. package/test/types/fastify.test-d.ts +10 -18
  140. package/test/types/import.js +2 -0
  141. package/test/types/import.ts +1 -0
  142. package/test/types/instance.test-d.ts +68 -17
  143. package/test/types/logger.test-d.ts +44 -15
  144. package/test/types/reply.test-d.ts +2 -1
  145. package/test/types/route.test-d.ts +8 -2
  146. package/test/types/schema.test-d.ts +2 -39
  147. package/test/types/type-provider.test-d.ts +417 -0
  148. package/test/url-rewriting.test.js +3 -3
  149. package/test/validation-error-handling.test.js +8 -8
  150. package/test/versioned-routes.test.js +30 -18
  151. package/test/wrapThenable.test.js +7 -6
  152. package/types/content-type-parser.d.ts +17 -8
  153. package/types/hooks.d.ts +102 -59
  154. package/types/instance.d.ts +244 -118
  155. package/types/logger.d.ts +18 -104
  156. package/types/plugin.d.ts +10 -4
  157. package/types/reply.d.ts +18 -12
  158. package/types/request.d.ts +10 -5
  159. package/types/route.d.ts +42 -31
  160. package/types/schema.d.ts +1 -1
  161. package/types/type-provider.d.ts +99 -0
  162. package/types/utils.d.ts +1 -1
  163. package/lib/schema-compilers.js +0 -12
  164. package/test/emit-warning.test.js +0 -166
@@ -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
@@ -59,12 +59,10 @@ object that exposes the following functions and properties:
59
59
  buffer, JSON, stream, or an Error object.
60
60
  - `.sent` - A boolean value that you can use if you need to know if `send` has
61
61
  already been called.
62
+ - `.hijack()` - interrupt the normal request lifecycle.
62
63
  - `.raw` - The
63
64
  [`http.ServerResponse`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_class_http_serverresponse)
64
65
  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
66
  - `.log` - The logger instance of the incoming request.
69
67
  - `.request` - The incoming request.
70
68
  - `.context` - Access the [Request's context](./Request.md) property.
@@ -125,6 +123,8 @@ fastify.get('/', async function (req, rep) {
125
123
  Sets a response header. If the value is omitted or undefined, it is coerced to
126
124
  `''`.
127
125
 
126
+ > 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.
127
+
128
128
  For more information, see
129
129
  [`http.ServerResponse#setHeader`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_response_setheader_name_value).
130
130
 
@@ -205,6 +205,8 @@ Returns a boolean indicating if the specified header has been set.
205
205
  Redirects a request to the specified URL, the status code is optional, default
206
206
  to `302` (if status code is not already set by calling `code`).
207
207
 
208
+ > 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.
209
+
208
210
  Example (no `reply.code()` call) sets status code to `302` and redirects to
209
211
  `/home`
210
212
  ```js
@@ -315,39 +317,38 @@ Another example of the misuse of `Reply.raw` is explained in
315
317
 
316
318
  As the name suggests, `.sent` is a property to indicate if a response has been
317
319
  sent via `reply.send()`.
320
+ It will also be `true` in case `reply.hijack()` was used.
318
321
 
319
322
  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
323
+ it is possible to call `reply.hijack()` to indicate that the automatic
321
324
  invocation of `reply.send()` once the handler promise resolve should be skipped.
322
- By setting `reply.sent = true`, an application claims full responsibility for
325
+ By calling `reply.hijack()`, an application claims full responsibility for
323
326
  the low-level request and response. Moreover, hooks will not be invoked.
324
327
 
325
- As an example:
328
+ *Modifying the `.sent` property directly is deprecated. Please use the aformentioned
329
+ `.hijack()` method to achieve the same effect.*
330
+
331
+ <a name="hijack"></a>
332
+ ### .hijack()
333
+ Sometimes you might need to halt the execution of the normal request lifecycle and
334
+ handle sending the response manually.
335
+
336
+ To achieve this, Fastify provides the `reply.hijack()` method that can be called
337
+ during the request lifecycle (At any point before `reply.send()` is called), and
338
+ allows you to prevent Fastify from sending the response, and from running the
339
+ remaining hooks (and user handler if the reply was hijacked before).
326
340
 
327
341
  ```js
328
342
  app.get('/', (req, reply) => {
329
- reply.sent = true
343
+ reply.hijack()
330
344
  reply.raw.end('hello world')
331
345
 
332
346
  return Promise.resolve('this will be skipped')
333
347
  })
334
348
  ```
335
349
 
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
350
+ If `reply.raw` is used to send a response back to the user, the `onResponse`
351
+ hooks will still be executed.
351
352
 
352
353
  ### .send(data)
353
354
  <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