fastify 5.7.4 → 5.8.1

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 (59) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/SECURITY.md +20 -20
  4. package/build/build-validation.js +2 -0
  5. package/docs/Guides/Ecosystem.md +7 -59
  6. package/docs/Guides/Fluent-Schema.md +2 -1
  7. package/docs/Guides/Migration-Guide-V4.md +9 -8
  8. package/docs/Guides/Migration-Guide-V5.md +1 -1
  9. package/docs/Guides/Serverless.md +1 -1
  10. package/docs/Reference/ContentTypeParser.md +2 -1
  11. package/docs/Reference/Decorators.md +4 -2
  12. package/docs/Reference/Errors.md +5 -0
  13. package/docs/Reference/Hooks.md +85 -23
  14. package/docs/Reference/LTS.md +2 -2
  15. package/docs/Reference/Lifecycle.md +16 -1
  16. package/docs/Reference/Logging.md +11 -7
  17. package/docs/Reference/Middleware.md +3 -2
  18. package/docs/Reference/Reply.md +15 -8
  19. package/docs/Reference/Request.md +17 -1
  20. package/docs/Reference/Routes.md +15 -6
  21. package/docs/Reference/Server.md +135 -14
  22. package/docs/Reference/Type-Providers.md +5 -5
  23. package/docs/Reference/TypeScript.md +14 -10
  24. package/docs/Reference/Validation-and-Serialization.md +28 -1
  25. package/fastify.d.ts +1 -0
  26. package/fastify.js +4 -2
  27. package/lib/config-validator.js +324 -296
  28. package/lib/content-type-parser.js +1 -1
  29. package/lib/content-type.js +9 -3
  30. package/lib/context.js +5 -2
  31. package/lib/errors.js +12 -1
  32. package/lib/reply.js +23 -1
  33. package/lib/request.js +18 -1
  34. package/lib/route.js +45 -4
  35. package/lib/symbols.js +4 -0
  36. package/package.json +5 -5
  37. package/scripts/validate-ecosystem-links.js +179 -0
  38. package/test/content-parser.test.js +25 -1
  39. package/test/content-type.test.js +38 -0
  40. package/test/handler-timeout.test.js +367 -0
  41. package/test/internals/errors.test.js +2 -2
  42. package/test/internals/initial-config.test.js +2 -0
  43. package/test/request-error.test.js +41 -0
  44. package/test/router-options.test.js +42 -0
  45. package/test/scripts/validate-ecosystem-links.test.js +339 -0
  46. package/test/types/dummy-plugin.ts +2 -2
  47. package/test/types/fastify.test-d.ts +1 -0
  48. package/test/types/logger.test-d.ts +17 -18
  49. package/test/types/register.test-d.ts +2 -2
  50. package/test/types/reply.test-d.ts +2 -2
  51. package/test/types/request.test-d.ts +4 -3
  52. package/test/types/route.test-d.ts +6 -0
  53. package/test/types/type-provider.test-d.ts +1 -1
  54. package/test/web-api.test.js +75 -0
  55. package/types/errors.d.ts +2 -0
  56. package/types/logger.d.ts +1 -1
  57. package/types/request.d.ts +2 -0
  58. package/types/route.d.ts +35 -21
  59. package/types/tsconfig.eslint.json +0 -13
@@ -34,7 +34,8 @@ are Request/Reply hooks and application hooks:
34
34
  - [Using Hooks to Inject Custom Properties](#using-hooks-to-inject-custom-properties)
35
35
  - [Diagnostics Channel Hooks](#diagnostics-channel-hooks)
36
36
 
37
- > ℹ️ Note: The `done` callback is not available when using `async`/`await` or
37
+ > ℹ️ Note:
38
+ > The `done` callback is not available when using `async`/`await` or
38
39
  > returning a `Promise`. If you do invoke a `done` callback in this situation
39
40
  > unexpected behavior may occur, e.g. duplicate invocation of handlers.
40
41
 
@@ -68,7 +69,8 @@ fastify.addHook('onRequest', async (request, reply) => {
68
69
  })
69
70
  ```
70
71
 
71
- > ℹ️ Note: In the [onRequest](#onrequest) hook, `request.body` will always be
72
+ > ℹ️ Note:
73
+ > In the [onRequest](#onrequest) hook, `request.body` will always be
72
74
  > `undefined`, because the body parsing happens before the
73
75
  > [preValidation](#prevalidation) hook.
74
76
 
@@ -98,16 +100,19 @@ fastify.addHook('preParsing', async (request, reply, payload) => {
98
100
  })
99
101
  ```
100
102
 
101
- > ℹ️ Note: In the [preParsing](#preparsing) hook, `request.body` will always be
103
+ > ℹ️ Note:
104
+ > In the [preParsing](#preparsing) hook, `request.body` will always be
102
105
  > `undefined`, because the body parsing happens before the
103
106
  > [preValidation](#prevalidation) hook.
104
107
 
105
- > ℹ️ Note: You should also add a `receivedEncodedLength` property to the
108
+ > ℹ️ Note:
109
+ > You should also add a `receivedEncodedLength` property to the
106
110
  > returned stream. This property is used to correctly match the request payload
107
111
  > with the `Content-Length` header value. Ideally, this property should be updated
108
112
  > on each received chunk.
109
113
 
110
- > ℹ️ Note: The size of the returned stream is checked to not exceed the limit
114
+ > ℹ️ Note:
115
+ > The size of the returned stream is checked to not exceed the limit
111
116
  > set in [`bodyLimit`](./Server.md#bodylimit) option.
112
117
 
113
118
  ### preValidation
@@ -166,7 +171,8 @@ fastify.addHook('preSerialization', async (request, reply, payload) => {
166
171
  })
167
172
  ```
168
173
 
169
- > ℹ️ Note: The hook is NOT called if the payload is a `string`, a `Buffer`, a
174
+ > ℹ️ Note:
175
+ > The hook is NOT called if the payload is a `string`, a `Buffer`, a
170
176
  > `stream`, or `null`.
171
177
 
172
178
  ### onError
@@ -192,7 +198,8 @@ an exception.
192
198
  This hook will be executed before
193
199
  the [Custom Error Handler set by `setErrorHandler`](./Server.md#seterrorhandler).
194
200
 
195
- > ℹ️ Note: Unlike the other hooks, passing an error to the `done` function is not
201
+ > ℹ️ Note:
202
+ > Unlike the other hooks, passing an error to the `done` function is not
196
203
  > supported.
197
204
 
198
205
  ### onSend
@@ -229,7 +236,8 @@ fastify.addHook('onSend', (request, reply, payload, done) => {
229
236
  > to `0`, whereas the `Content-Length` header will not be set if the payload is
230
237
  > `null`.
231
238
 
232
- > ℹ️ Note: If you change the payload, you may only change it to a `string`, a
239
+ > ℹ️ Note:
240
+ > If you change the payload, you may only change it to a `string`, a
233
241
  > `Buffer`, a `stream`, a `ReadableStream`, a `Response`, or `null`.
234
242
 
235
243
 
@@ -252,7 +260,8 @@ The `onResponse` hook is executed when a response has been sent, so you will not
252
260
  be able to send more data to the client. It can however be useful for sending
253
261
  data to external services, for example, to gather statistics.
254
262
 
255
- > ℹ️ Note: Setting `disableRequestLogging` to `true` will disable any error log
263
+ > ℹ️ Note:
264
+ > Setting `disableRequestLogging` to `true` will disable any error log
256
265
  > inside the `onResponse` hook. In this case use `try - catch` to log errors.
257
266
 
258
267
  ### onTimeout
@@ -275,6 +284,12 @@ service (if the `connectionTimeout` property is set on the Fastify instance).
275
284
  The `onTimeout` hook is executed when a request is timed out and the HTTP socket
276
285
  has been hung up. Therefore, you will not be able to send data to the client.
277
286
 
287
+ > ℹ️ Note:
288
+ > The `onTimeout` hook is triggered by socket-level timeouts set via
289
+ > `connectionTimeout`. For application-level per-route timeouts, see the
290
+ > [`handlerTimeout`](./Server.md#factory-handler-timeout) option which uses
291
+ > `request.signal` for cooperative cancellation.
292
+
278
293
  ### onRequestAbort
279
294
 
280
295
  ```js
@@ -294,7 +309,8 @@ The `onRequestAbort` hook is executed when a client closes the connection before
294
309
  the entire request has been processed. Therefore, you will not be able to send
295
310
  data to the client.
296
311
 
297
- > ℹ️ Note: Client abort detection is not completely reliable.
312
+ > ℹ️ Note:
313
+ > Client abort detection is not completely reliable.
298
314
  > See: [`Detecting-When-Clients-Abort.md`](../Guides/Detecting-When-Clients-Abort.md)
299
315
 
300
316
  ### Manage Errors from a hook
@@ -448,16 +464,19 @@ fastify.addHook('onListen', async function () {
448
464
  })
449
465
  ```
450
466
 
451
- > ℹ️ Note: This hook will not run when the server is started using
452
- > fastify.inject()` or `fastify.ready()`.
467
+ > ℹ️ Note:
468
+ > This hook will not run when the server is started using
469
+ > `fastify.inject()` or `fastify.ready()`.
453
470
 
454
471
  ### onClose
455
472
  <a id="on-close"></a>
456
473
 
457
- Triggered when `fastify.close()` is invoked to stop the server, after all in-flight
458
- HTTP requests have been completed.
459
- It is useful when [plugins](./Plugins.md) need a "shutdown" event, for example,
460
- to close an open connection to a database.
474
+ Triggered when `fastify.close()` is invoked to stop the server. By the time
475
+ `onClose` hooks execute, the HTTP server has already stopped listening, all
476
+ in-flight HTTP requests have been completed, and connections have been drained.
477
+ This makes `onClose` the safe place for [plugins](./Plugins.md) to release
478
+ resources such as database connection pools, as no new requests will
479
+ arrive.
461
480
 
462
481
  The hook function takes the Fastify instance as a first argument,
463
482
  and a `done` callback for synchronous hook functions.
@@ -475,13 +494,41 @@ fastify.addHook('onClose', async (instance) => {
475
494
  })
476
495
  ```
477
496
 
497
+ #### Execution order
498
+
499
+ When multiple `onClose` hooks are registered across plugins, child-plugin hooks
500
+ execute before parent-plugin hooks. This means a database plugin's `onClose`
501
+ hook will run before the root-level `onClose` hooks:
502
+
503
+ ```js
504
+ fastify.register(function dbPlugin (instance, opts, done) {
505
+ instance.addHook('onClose', async (instance) => {
506
+ // Runs first — close the database pool
507
+ await instance.db.close()
508
+ })
509
+ done()
510
+ })
511
+
512
+ fastify.addHook('onClose', async (instance) => {
513
+ // Runs second — after child plugins have cleaned up
514
+ })
515
+ ```
516
+
517
+ See [`close`](./Server.md#close) for the full shutdown lifecycle.
518
+
478
519
  ### preClose
479
520
  <a id="pre-close"></a>
480
521
 
481
- Triggered when `fastify.close()` is invoked to stop the server, before all in-flight
482
- HTTP requests have been completed.
483
- It is useful when [plugins](./Plugins.md) have set up some state attached
484
- to the HTTP server that would prevent the server to close.
522
+ Triggered when `fastify.close()` is invoked to stop the server. At this
523
+ point the server is already rejecting new requests with `503` (when
524
+ [`return503OnClosing`](./Server.md#factory-return-503-on-closing) is `true`),
525
+ but the HTTP server has not yet stopped listening and in-flight requests are
526
+ still being processed.
527
+
528
+ It is useful when [plugins](./Plugins.md) have set up state attached to the HTTP
529
+ server that would prevent the server from closing, such as open WebSocket
530
+ connections or Server-Sent Events streams that must be explicitly terminated for
531
+ `server.close()` to complete.
485
532
  _It is unlikely you will need to use this hook_,
486
533
  use the [`onClose`](#onclose) for the most common case.
487
534
 
@@ -499,6 +546,18 @@ fastify.addHook('preClose', async () => {
499
546
  })
500
547
  ```
501
548
 
549
+ For example, closing WebSocket connections during shutdown:
550
+
551
+ ```js
552
+ fastify.addHook('preClose', async () => {
553
+ // Close all WebSocket connections so that server.close() can complete.
554
+ // Without this, open connections would keep the server alive.
555
+ for (const ws of activeWebSockets) {
556
+ ws.close(1001, 'Server shutting down')
557
+ }
558
+ })
559
+ ```
560
+
502
561
  ### onRoute
503
562
  <a id="on-route"></a>
504
563
 
@@ -572,7 +631,8 @@ This hook can be useful if you are developing a plugin that needs to know when a
572
631
  plugin context is formed, and you want to operate in that specific context, thus
573
632
  this hook is encapsulated.
574
633
 
575
- > ℹ️ Note: This hook will not be called if a plugin is wrapped inside
634
+ > ℹ️ Note:
635
+ > This hook will not be called if a plugin is wrapped inside
576
636
  > [`fastify-plugin`](https://github.com/fastify/fastify-plugin).
577
637
  ```js
578
638
  fastify.decorate('data', [])
@@ -770,7 +830,8 @@ fastify.route({
770
830
  })
771
831
  ```
772
832
 
773
- > ℹ️ Note: Both options also accept an array of functions.
833
+ > ℹ️ Note:
834
+ > Both options also accept an array of functions.
774
835
 
775
836
  ## Using Hooks to Inject Custom Properties
776
837
  <a id="using-hooks-to-inject-custom-properties"></a>
@@ -857,7 +918,8 @@ channel.subscribe(function ({ fastify }) {
857
918
  })
858
919
  ```
859
920
 
860
- > ℹ️ Note: The TracingChannel class API is currently experimental and may undergo
921
+ > ℹ️ Note:
922
+ > The TracingChannel class API is currently experimental and may undergo
861
923
  > breaking changes even in semver-patch releases of Node.js.
862
924
 
863
925
  Five other events are published on a per-request basis following the
@@ -38,7 +38,7 @@ A "month" is defined as 30 consecutive days.
38
38
  > occasions where we need to release breaking changes as a _minor_ version
39
39
  > release. Such changes will _always_ be noted in the [release
40
40
  > notes](https://github.com/fastify/fastify/releases).
41
- >
41
+ >
42
42
  > To avoid automatically receiving breaking security updates it is possible to
43
43
  > use the tilde (`~`) range qualifier. For example, to get patches for the 3.15
44
44
  > release, and avoid automatically updating to the 3.16 release, specify the
@@ -67,7 +67,7 @@ For more information, see their [Never Ending Support][hd-link] service.
67
67
 
68
68
  Fastify uses GitHub Actions for CI testing, please refer to [GitHub&#39;s
69
69
  documentation regarding workflow
70
- runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources)
70
+ runners](https://docs.github.com/en/actions/reference/runners/github-hosted-runners#supported-runners-and-hardware-resources)
71
71
  for further details on what the latest virtual environment is in relation to the
72
72
  YAML workflow labels below:
73
73
 
@@ -41,6 +41,11 @@ Incoming Request
41
41
  └─▶ onResponse Hook
42
42
  ```
43
43
 
44
+ When `handlerTimeout` is configured, a timer starts after routing. If the
45
+ response is not sent within the allowed time, `request.signal` is aborted and
46
+ a 503 error is sent. The timer is cleared when the response finishes or when
47
+ `reply.hijack()` is called. See [`handlerTimeout`](./Server.md#factory-handler-timeout).
48
+
44
49
  Before or during the `User Handler`, `reply.hijack()` can be called to:
45
50
  - Prevent Fastify from running subsequent hooks and the user handler
46
51
  - Prevent Fastify from sending the response automatically
@@ -81,4 +86,14 @@ submitted, the data flow is as follows:
81
86
  - The [reply serializer](./Server.md#setreplyserializer) if set
82
87
  - The [serializer compiler](./Server.md#setserializercompiler) if a JSON schema
83
88
  is set for the HTTP status code
84
- - The default `JSON.stringify` function
89
+ - The default `JSON.stringify` function
90
+
91
+ ## Shutdown Lifecycle
92
+ <a id="shutdown-lifecycle"></a>
93
+
94
+ When [`fastify.close()`](./Server.md#close) is called, the server goes through a
95
+ graceful shutdown sequence involving
96
+ [`preClose`](./Hooks.md#pre-close) hooks, connection draining, and
97
+ [`onClose`](./Hooks.md#on-close) hooks. See the
98
+ [`close`](./Server.md#close) method documentation for the full step-by-step
99
+ lifecycle.
@@ -65,7 +65,7 @@ fastify.log.info('Something important happened!');
65
65
 
66
66
  #### Passing Logger Options
67
67
  To pass options to the logger, provide them to Fastify. See the
68
- [Pino documentation](https://github.com/pinojs/pino/blob/master/docs/api.md#options)
68
+ [Pino documentation](https://github.com/pinojs/pino/blob/main/docs/api.md#options)
69
69
  for available options. To specify a file destination, use:
70
70
 
71
71
  ```js
@@ -107,7 +107,8 @@ value is used; otherwise, a new incremental ID is generated. See Fastify Factory
107
107
  [`requestIdHeader`](./Server.md#factory-request-id-header) and Fastify Factory
108
108
  [`genReqId`](./Server.md#genreqid) for customization options.
109
109
 
110
- > ⚠ Warning: enabling `requestIdHeader` allows any callers to set `reqId` to a
110
+ > ⚠ Warning:
111
+ > Enabling `requestIdHeader` allows any callers to set `reqId` to a
111
112
  > value of their choosing.
112
113
  > No validation is performed on `requestIdHeader`.
113
114
 
@@ -161,7 +162,8 @@ const fastify = require('fastify')({
161
162
  });
162
163
  ```
163
164
 
164
- > ℹ️ Note: In some cases, the [`Reply`](./Reply.md) object passed to the `res`
165
+ > ℹ️ Note:
166
+ > In some cases, the [`Reply`](./Reply.md) object passed to the `res`
165
167
  > serializer cannot be fully constructed. When writing a custom `res`
166
168
  > serializer, check for the existence of any properties on `reply` aside from
167
169
  > `statusCode`, which is always present. For example, verify the existence of
@@ -188,9 +190,10 @@ const fastify = require('fastify')({
188
190
  });
189
191
  ```
190
192
 
191
- > ℹ️ Note: The body cannot be serialized inside a `req` method because the
192
- request is serialized when the child logger is created. At that time, the body
193
- is not yet parsed.
193
+ > ℹ️ Note:
194
+ > The body cannot be serialized inside a `req` method because the
195
+ > request is serialized when the child logger is created. At that time, the body
196
+ > is not yet parsed.
194
197
 
195
198
  See the following approach to log `req.body`:
196
199
 
@@ -203,7 +206,8 @@ app.addHook('preHandler', function (req, reply, done) {
203
206
  })
204
207
  ```
205
208
 
206
- > ℹ️ Note: Ensure serializers never throw errors, as this can cause the Node
209
+ > ℹ️ Note:
210
+ > Ensure serializers never throw errors, as this can cause the Node
207
211
  > process to exit. See the
208
212
  > [Pino documentation](https://getpino.io/#/docs/api?id=opt-serializers) for more
209
213
  > information.
@@ -50,7 +50,8 @@ that already has the Fastify [Request](./Request.md#request) and
50
50
  To run middleware under certain paths, pass the path as the first parameter to
51
51
  `use`.
52
52
 
53
- > ℹ️ Note: This does not support routes with parameters
53
+ > ℹ️ Note:
54
+ > This does not support routes with parameters
54
55
  > (e.g. `/user/:id/comments`) and wildcards are not supported in multiple paths.
55
56
 
56
57
  ```js
@@ -75,4 +76,4 @@ Fastify offers alternatives to commonly used middleware, such as
75
76
  [`@fastify/cors`](https://github.com/fastify/fastify-cors) for
76
77
  [`cors`](https://github.com/expressjs/cors), and
77
78
  [`@fastify/static`](https://github.com/fastify/fastify-static) for
78
- [`serve-static`](https://github.com/expressjs/serve-static).
79
+ [`serve-static`](https://github.com/expressjs/serve-static).
@@ -152,7 +152,8 @@ fastify.get('/', async function (req, rep) {
152
152
  Sets a response header. If the value is omitted or undefined, it is coerced to
153
153
  `''`.
154
154
 
155
- > ℹ️ Note: The header's value must be properly encoded using
155
+ > ℹ️ Note:
156
+ > The header's value must be properly encoded using
156
157
  > [`encodeURI`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI)
157
158
  > or similar modules such as
158
159
  > [`encodeurl`](https://www.npmjs.com/package/encodeurl). Invalid characters
@@ -261,11 +262,13 @@ requires heavy resources to be sent after the `data`, for example,
261
262
  `Server-Timing` and `Etag`. It can ensure the client receives the response data
262
263
  as soon as possible.
263
264
 
264
- > ℹ️ Note: The header `Transfer-Encoding: chunked` will be added once you use
265
+ > ℹ️ Note:
266
+ > The header `Transfer-Encoding: chunked` will be added once you use
265
267
  > the trailer. It is a hard requirement for using trailer in Node.js.
266
268
 
267
- > ℹ️ Note: Any error passed to `done` callback will be ignored. If you interested
268
- > in the error, you can turn on `debug` level logging.*
269
+ > ℹ️ Note:
270
+ > Any error passed to `done` callback will be ignored. If you are interested
271
+ > in the error, you can turn on `debug` level logging.
269
272
 
270
273
  ```js
271
274
  reply.trailer('server-timing', function() {
@@ -315,7 +318,8 @@ reply.getTrailer('server-timing') // undefined
315
318
  Redirects a request to the specified URL, the status code is optional, default
316
319
  to `302` (if status code is not already set by calling `code`).
317
320
 
318
- > ℹ️ Note: The input URL must be properly encoded using
321
+ > ℹ️ Note:
322
+ > The input URL must be properly encoded using
319
323
  > [`encodeURI`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI)
320
324
  > or similar modules such as
321
325
  > [`encodeurl`](https://www.npmjs.com/package/encodeurl). Invalid URLs will
@@ -673,7 +677,8 @@ If you pass a string to `send` without a `Content-Type`, it will be sent as
673
677
  string to `send`, it will be serialized with the custom serializer if one is
674
678
  set, otherwise, it will be sent unmodified.
675
679
 
676
- > **Note:** Even when the `Content-Type` header is set to `application/json`,
680
+ > ℹ️ Note:
681
+ > Even when the `Content-Type` header is set to `application/json`,
677
682
  > strings are sent unmodified by default. To serialize a string as JSON, you
678
683
  > must set a custom serializer:
679
684
 
@@ -838,7 +843,8 @@ automatically create an error structured as the following:
838
843
  You can add custom properties to the Error object, such as `headers`, that will
839
844
  be used to enhance the HTTP response.
840
845
 
841
- > ℹ️ Note: If you are passing an error to `send` and the statusCode is less than
846
+ > ℹ️ Note:
847
+ > If you are passing an error to `send` and the statusCode is less than
842
848
  > 400, Fastify will automatically set it at 500.
843
849
 
844
850
  Tip: you can simplify errors by using the
@@ -886,7 +892,8 @@ fastify.get('/', {
886
892
  If you want to customize error handling, check out
887
893
  [`setErrorHandler`](./Server.md#seterrorhandler) API.
888
894
 
889
- > ℹ️ Note: you are responsible for logging when customizing the error handler.
895
+ > ℹ️ Note:
896
+ > You are responsible for logging when customizing the error handler.
890
897
 
891
898
  API:
892
899
 
@@ -25,6 +25,11 @@ Request is a core Fastify object containing the following fields:
25
25
  enabled). For HTTP/2 compatibility, it returns `:authority` if no host header
26
26
  exists. The host header may return an empty string if `requireHostHeader` is
27
27
  `false`, not provided with HTTP/1.0, or removed by schema validation.
28
+ ⚠ Security: this value comes from client-controlled headers; only trust it
29
+ when you control proxy behavior and have validated or allow-listed hosts.
30
+ No additional validation is performed beyond RFC parsing (see
31
+ [RFC 9110, section 7.2](https://www.rfc-editor.org/rfc/rfc9110#section-7.2) and
32
+ [RFC 3986, section 3.2.2](https://www.rfc-editor.org/rfc/rfc3986#section-3.2.2)).
28
33
  - `hostname` - The hostname derived from the `host` property of the incoming request.
29
34
  - `port` - The port from the `host` property, which may refer to the port the
30
35
  server is listening on.
@@ -35,12 +40,22 @@ Request is a core Fastify object containing the following fields:
35
40
  case of internal re-routing.
36
41
  - `is404` - `true` if request is being handled by 404 handler, `false` otherwise.
37
42
  - `socket` - The underlying connection of the incoming request.
43
+ - `signal` - An `AbortSignal` that aborts when the handler timeout
44
+ fires or the client disconnects. Created lazily on first access, so
45
+ there is zero overhead when not used. When
46
+ [`handlerTimeout`](./Server.md#factory-handler-timeout) is configured,
47
+ the signal is pre-created and also aborts on timeout. Pass it to
48
+ `fetch()`, database queries, or any API accepting a `signal` option
49
+ for cooperative cancellation. On timeout, `signal.reason` is the
50
+ `FST_ERR_HANDLER_TIMEOUT` error; on client disconnect it is a generic
51
+ `AbortError`. Check `signal.reason.code` to distinguish the two cases.
38
52
  - `context` - Deprecated, use `request.routeOptions.config` instead. A Fastify
39
53
  internal object. Do not use or modify it directly. It is useful to access one
40
54
  special key:
41
55
  - `context.config` - The route [`config`](./Routes.md#routes-config) object.
42
56
  - `routeOptions` - The route [`option`](./Routes.md#routes-options) object.
43
57
  - `bodyLimit` - Either server limit or route limit.
58
+ - `handlerTimeout` - The handler timeout configured for this route.
44
59
  - `config` - The [`config`](./Routes.md#routes-config) object for this route.
45
60
  - `method` - The HTTP method for the route.
46
61
  - `url` - The path of the URL to match this route.
@@ -84,7 +99,8 @@ This operation adds new values to the request headers, accessible via
84
99
  For performance reasons, `Symbol('fastify.RequestAcceptVersion')` may be added
85
100
  to headers on `not found` routes.
86
101
 
87
- > ℹ️ Note: Schema validation may mutate the `request.headers` and
102
+ > ℹ️ Note:
103
+ > Schema validation may mutate the `request.headers` and
88
104
  > `request.raw.headers` objects, causing the headers to become empty.
89
105
 
90
106
  ```js
@@ -115,6 +115,11 @@ fastify.route(options)
115
115
  larger than this number of bytes. Must be an integer. You may also set this
116
116
  option globally when first creating the Fastify instance with
117
117
  `fastify(options)`. Defaults to `1048576` (1 MiB).
118
+ * `handlerTimeout`: maximum number of milliseconds for the route's full
119
+ lifecycle. Overrides the server-level
120
+ [`handlerTimeout`](./Server.md#factory-handler-timeout). Must be a positive
121
+ integer. When the timeout fires, `request.signal` is aborted and a 503 error
122
+ is sent through the error handler (which can be customized per-route).
118
123
  * `logLevel`: set log level for this route. See below.
119
124
  * `logSerializers`: set serializers to log for this route.
120
125
  * `config`: object used to store custom configuration.
@@ -138,7 +143,8 @@ fastify.route(options)
138
143
 
139
144
  * `reply` is defined in [Reply](./Reply.md).
140
145
 
141
- > ℹ️ Note: The documentation for `onRequest`, `preParsing`, `preValidation`,
146
+ > ℹ️ Note:
147
+ > The documentation for `onRequest`, `preParsing`, `preValidation`,
142
148
  > `preHandler`, `preSerialization`, `onSend`, and `onResponse` is detailed in
143
149
  > [Hooks](./Hooks.md). To send a response before the request is handled by the
144
150
  > `handler`, see [Respond to a request from
@@ -234,7 +240,8 @@ const opts = {
234
240
  fastify.get('/', opts)
235
241
  ```
236
242
 
237
- > ℹ️ Note: Specifying the handler in both `options` and as the third parameter to
243
+ > ℹ️ Note:
244
+ > Specifying the handler in both `options` and as the third parameter to
238
245
  > the shortcut method throws a duplicate `handler` error.
239
246
 
240
247
  ### Url building
@@ -403,7 +410,8 @@ This approach supports both `callback-style` and `async-await` with minimal
403
410
  trade-off. However, it is recommended to use only one style for consistent
404
411
  error handling within your application.
405
412
 
406
- > ℹ️ Note: Every async function returns a promise by itself.
413
+ > ℹ️ Note:
414
+ > Every async function returns a promise by itself.
407
415
 
408
416
  ### Route Prefixing
409
417
  <a id="route-prefixing"></a>
@@ -504,7 +512,7 @@ See the `prefixTrailingSlash` route option above to change this behavior.
504
512
 
505
513
  Different log levels can be set for routes in Fastify by passing the `logLevel`
506
514
  option to the plugin or route with the desired
507
- [value](https://github.com/pinojs/pino/blob/master/docs/api.md#level-string).
515
+ [value](https://github.com/pinojs/pino/blob/main/docs/api.md#level-string).
508
516
 
509
517
  Be aware that setting `logLevel` at the plugin level also affects
510
518
  [`setNotFoundHandler`](./Server.md#setnotfoundhandler) and
@@ -533,7 +541,7 @@ Fastify Logger, accessible with `fastify.log`.*
533
541
  <a id="custom-log-serializer"></a>
534
542
 
535
543
  In some contexts, logging a large object may waste resources. Define custom
536
- [`serializers`](https://github.com/pinojs/pino/blob/master/docs/api.md#serializers-object)
544
+ [`serializers`](https://github.com/pinojs/pino/blob/main/docs/api.md#serializers-object)
537
545
  and attach them in the appropriate context.
538
546
 
539
547
  ```js
@@ -636,7 +644,8 @@ has a version set, and will prefer a versioned route to a non-versioned route
636
644
  for the same path. Advanced version ranges and pre-releases currently are not
637
645
  supported.
638
646
 
639
- > **Note:** using this feature can degrade the router’s performance.
647
+ > ℹ️ Note:
648
+ > Using this feature can degrade the router's performance.
640
649
 
641
650
  ```js
642
651
  fastify.route({