fastify 5.8.5 → 5.9.0

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 (103) hide show
  1. package/SECURITY.md +1 -1
  2. package/SPONSORS.md +6 -4
  3. package/docs/Guides/Database.md +0 -28
  4. package/docs/Guides/Ecosystem.md +13 -2
  5. package/docs/Guides/Serverless.md +2 -2
  6. package/docs/Guides/Write-Plugin.md +1 -1
  7. package/docs/Reference/Encapsulation.md +27 -26
  8. package/docs/Reference/Errors.md +10 -4
  9. package/docs/Reference/HTTP2.md +10 -10
  10. package/docs/Reference/Hooks.md +4 -4
  11. package/docs/Reference/Index.md +14 -16
  12. package/docs/Reference/LTS.md +12 -13
  13. package/docs/Reference/Lifecycle.md +9 -8
  14. package/docs/Reference/Logging.md +44 -39
  15. package/docs/Reference/Middleware.md +21 -25
  16. package/docs/Reference/Principles.md +2 -2
  17. package/docs/Reference/Reply.md +6 -1
  18. package/docs/Reference/Request.md +27 -16
  19. package/docs/Reference/Routes.md +5 -2
  20. package/docs/Reference/Server.md +31 -3
  21. package/docs/Reference/Type-Providers.md +29 -5
  22. package/docs/Reference/Validation-and-Serialization.md +15 -2
  23. package/docs/Reference/Warnings.md +7 -6
  24. package/eslint.config.js +7 -2
  25. package/fastify.d.ts +8 -3
  26. package/fastify.js +43 -14
  27. package/lib/content-type-parser.js +13 -1
  28. package/lib/decorate.js +11 -3
  29. package/lib/error-handler.js +4 -3
  30. package/lib/error-serializer.js +59 -59
  31. package/lib/errors.js +16 -1
  32. package/lib/four-oh-four.js +14 -9
  33. package/lib/handle-request.js +11 -5
  34. package/lib/plugin-override.js +2 -1
  35. package/lib/plugin-utils.js +5 -5
  36. package/lib/reply.js +63 -8
  37. package/lib/request.js +14 -4
  38. package/lib/route.js +20 -6
  39. package/lib/schema-controller.js +1 -1
  40. package/lib/schemas.js +37 -30
  41. package/lib/symbols.js +3 -1
  42. package/lib/validation.js +1 -13
  43. package/lib/warnings.js +3 -3
  44. package/package.json +13 -15
  45. package/scripts/validate-ecosystem-links.js +1 -0
  46. package/test/bundler/esbuild/package.json +1 -1
  47. package/test/close-pipelining.test.js +1 -2
  48. package/test/custom-http-server.test.js +38 -0
  49. package/test/decorator-instance-properties.test.js +63 -0
  50. package/test/diagnostics-channel/async-error-handler.test.js +74 -0
  51. package/test/hooks.test.js +23 -0
  52. package/test/http-methods/get.test.js +1 -1
  53. package/test/http2/plain.test.js +135 -0
  54. package/test/http2/secure-with-fallback.test.js +1 -1
  55. package/test/https/https.test.js +1 -2
  56. package/test/internals/errors.test.js +31 -1
  57. package/test/internals/plugin.test.js +3 -1
  58. package/test/internals/request.test.js +27 -3
  59. package/test/internals/schema-controller-perf.test.js +33 -0
  60. package/test/logger/logging.test.js +18 -1
  61. package/test/logger/options.test.js +38 -1
  62. package/test/reply-error.test.js +1 -1
  63. package/test/reply-trailers.test.js +70 -0
  64. package/test/request-media-type.test.js +105 -0
  65. package/test/route-prefix.test.js +34 -0
  66. package/test/router-options.test.js +222 -11
  67. package/test/schema-serialization.test.js +108 -0
  68. package/test/schema-validation.test.js +24 -0
  69. package/test/scripts/validate-ecosystem-links.test.js +40 -57
  70. package/test/throw.test.js +14 -0
  71. package/test/trust-proxy.test.js +21 -0
  72. package/test/types/content-type-parser.tst.ts +70 -0
  73. package/test/types/{decorate-request-reply.test-d.ts → decorate-request-reply.tst.ts} +4 -4
  74. package/test/types/{dummy-plugin.ts → dummy-plugin.mts} +1 -1
  75. package/test/types/errors.tst.ts +91 -0
  76. package/test/types/fastify.tst.ts +351 -0
  77. package/test/types/hooks.tst.ts +578 -0
  78. package/test/types/instance.tst.ts +597 -0
  79. package/test/types/{logger.test-d.ts → logger.tst.ts} +61 -62
  80. package/test/types/plugin.tst.ts +96 -0
  81. package/test/types/register.tst.ts +245 -0
  82. package/test/types/reply.tst.ts +297 -0
  83. package/test/types/request.tst.ts +199 -0
  84. package/test/types/route.tst.ts +576 -0
  85. package/test/types/{schema.test-d.ts → schema.tst.ts} +22 -22
  86. package/test/types/{serverFactory.test-d.ts → serverFactory.tst.ts} +4 -4
  87. package/test/types/tsconfig.json +9 -0
  88. package/test/types/{type-provider.test-d.ts → type-provider.tst.ts} +256 -250
  89. package/test/types/using.tst.ts +14 -0
  90. package/types/errors.d.ts +3 -0
  91. package/types/request.d.ts +23 -2
  92. package/test/types/content-type-parser.test-d.ts +0 -72
  93. package/test/types/errors.test-d.ts +0 -90
  94. package/test/types/fastify.test-d.ts +0 -352
  95. package/test/types/hooks.test-d.ts +0 -550
  96. package/test/types/import.ts +0 -2
  97. package/test/types/instance.test-d.ts +0 -588
  98. package/test/types/plugin.test-d.ts +0 -97
  99. package/test/types/register.test-d.ts +0 -237
  100. package/test/types/reply.test-d.ts +0 -254
  101. package/test/types/request.test-d.ts +0 -188
  102. package/test/types/route.test-d.ts +0 -553
  103. package/test/types/using.test-d.ts +0 -17
@@ -13,8 +13,8 @@ As Fastify is focused on performance, it uses
13
13
  [pino](https://github.com/pinojs/pino) as its logger, with the default log
14
14
  level set to `'info'` when enabled.
15
15
 
16
- #### Basic logging setup
17
- Enabling the production JSON logger:
16
+ #### Basic Logging Setup
17
+ The following enables the production JSON logger:
18
18
 
19
19
  ```js
20
20
  const fastify = require('fastify')({
@@ -23,8 +23,8 @@ const fastify = require('fastify')({
23
23
  ```
24
24
 
25
25
  #### Environment-Specific Configuration
26
- Enabling the logger with appropriate configuration for local development,
27
- production, and test environments requires more configuration:
26
+ Enabling the logger for local development, production, and test environments
27
+ requires additional configuration:
28
28
 
29
29
  ```js
30
30
  const envToLogger = {
@@ -41,11 +41,13 @@ const envToLogger = {
41
41
  test: false,
42
42
  }
43
43
  const fastify = require('fastify')({
44
- logger: envToLogger[environment] ?? true // defaults to true if no entry matches in the map
44
+ logger: envToLogger[environment] ?? true // defaults to true if no matching environment is found
45
45
  })
46
46
  ```
47
- ⚠️ `pino-pretty` needs to be installed as a dev dependency. It is not included
48
- by default for performance reasons.
47
+
48
+ > Warning:
49
+ > `pino-pretty` needs to be installed as a dev dependency. It is not included
50
+ > by default for performance reasons.
49
51
 
50
52
  ### Usage
51
53
  The logger can be used in route handlers as follows:
@@ -57,22 +59,22 @@ fastify.get('/', options, function (request, reply) {
57
59
  })
58
60
  ```
59
61
 
60
- Trigger new logs outside route handlers using the Pino instance from the Fastify
61
- instance:
62
+ To log outside route handlers, use the logger available on the Fastify instance:
63
+
62
64
  ```js
63
- fastify.log.info('Something important happened!');
65
+ fastify.log.info('Something important happened!')
64
66
  ```
65
67
 
66
68
  #### Passing Logger Options
67
69
  To pass options to the logger, provide them to Fastify. See the
68
70
  [Pino documentation](https://github.com/pinojs/pino/blob/main/docs/api.md#options)
69
- for available options. To specify a file destination, use:
71
+ for the full list of available options. To specify a file destination, use:
70
72
 
71
73
  ```js
72
74
  const fastify = require('fastify')({
73
75
  logger: {
74
76
  level: 'info',
75
- file: '/path/to/file' // Will use pino.destination()
77
+ file: '/path/to/file' // Uses pino.destination()
76
78
  }
77
79
  })
78
80
 
@@ -103,20 +105,19 @@ const fastify = require('fastify')({
103
105
  #### Request ID Tracking
104
106
  By default, Fastify adds an ID to every request for easier tracking. If the
105
107
  `requestIdHeader` option is set and the corresponding header is present, its
106
- value is used; otherwise, a new incremental ID is generated. See Fastify Factory
107
- [`requestIdHeader`](./Server.md#factory-request-id-header) and Fastify Factory
108
+ value is used; otherwise, a new incremental ID is generated. See the Fastify
109
+ factory options [`requestIdHeader`](./Server.md#factory-request-id-header) and
108
110
  [`genReqId`](./Server.md#genreqid) for customization options.
109
111
 
110
112
  > ⚠ Warning:
111
- > Enabling `requestIdHeader` allows any callers to set `reqId` to a
112
- > value of their choosing.
113
- > No validation is performed on `requestIdHeader`.
113
+ > Enabling `requestIdHeader` allows callers to set `reqId` to an arbitrary
114
+ > value. No validation is performed on the header value.
114
115
 
115
116
  #### Serializers
116
117
  The default logger uses standard serializers for objects with `req`, `res`, and
117
118
  `err` properties. The `req` object is the Fastify [`Request`](./Request.md)
118
119
  object, and the `res` object is the Fastify [`Reply`](./Reply.md) object. This
119
- behavior can be customized with custom serializers.
120
+ behavior can be overridden with custom serializers.
120
121
 
121
122
  ```js
122
123
  const fastify = require('fastify')({
@@ -129,8 +130,12 @@ const fastify = require('fastify')({
129
130
  }
130
131
  })
131
132
  ```
132
- For example, the response payload and headers could be logged using the approach
133
- below (not recommended):
133
+
134
+ > Warning:
135
+ > Logging response headers may expose sensitive data, including authentication
136
+ > data, and may violate privacy regulations.
137
+ > Use [log redaction](#log-redaction) to remove sensitive information.
138
+ > The following example is for demonstration purposes only:
134
139
 
135
140
  ```js
136
141
  const fastify = require('fastify')({
@@ -151,22 +156,19 @@ const fastify = require('fastify')({
151
156
  url: request.url,
152
157
  path: request.routeOptions.url,
153
158
  parameters: request.params,
154
- // Including headers in the log could violate privacy laws,
155
- // e.g., GDPR. Use the "redact" option to remove sensitive
156
- // fields. It could also leak authentication data in the logs.
157
159
  headers: request.headers
158
- };
160
+ }
159
161
  }
160
162
  }
161
163
  }
162
- });
164
+ })
163
165
  ```
164
166
 
165
167
  > ℹ️ Note:
166
168
  > In some cases, the [`Reply`](./Reply.md) object passed to the `res`
167
169
  > serializer cannot be fully constructed. When writing a custom `res`
168
- > serializer, check for the existence of any properties on `reply` aside from
169
- > `statusCode`, which is always present. For example, verify the existence of
170
+ > serializer, verify that any properties other than `statusCode` exist on
171
+ > `reply` before accessing them. For example, verify the existence of
170
172
  > `getHeaders` before calling it:
171
173
 
172
174
  ```js
@@ -187,15 +189,15 @@ const fastify = require('fastify')({
187
189
  },
188
190
  }
189
191
  }
190
- });
192
+ })
191
193
  ```
192
194
 
193
195
  > ℹ️ Note:
194
- > The body cannot be serialized inside a `req` method because the
196
+ > The body cannot be serialized inside the `req` serializer because the
195
197
  > request is serialized when the child logger is created. At that time, the body
196
198
  > is not yet parsed.
197
199
 
198
- See the following approach to log `req.body`:
200
+ To log `req.body`, use the `preHandler` hook:
199
201
 
200
202
  ```js
201
203
  app.addHook('preHandler', function (req, reply, done) {
@@ -207,18 +209,20 @@ app.addHook('preHandler', function (req, reply, done) {
207
209
  ```
208
210
 
209
211
  > ℹ️ Note:
210
- > Ensure serializers never throw errors, as this can cause the Node
212
+ > Ensure serializers never throw errors, as this can cause the Node.js
211
213
  > process to exit. See the
212
- > [Pino documentation](https://getpino.io/#/docs/api?id=opt-serializers) for more
213
- > information.
214
+ > [Pino documentation](https://getpino.io/#/docs/api?id=opt-serializers) for
215
+ > more information.
214
216
 
215
- *Any logger other than Pino will ignore this option.*
217
+ *Any logger other than Pino will ignore the `serializers` option.*
216
218
 
217
219
  ### Using Custom Loggers
218
220
  A custom logger instance can be supplied by passing it as `loggerInstance`. The
219
- logger must conform to the Pino interface, with methods: `info`, `error`,
220
- `debug`, `fatal`, `warn`, `trace`, `silent`, `child`, and a string property
221
- `level`.
221
+ logger must conform to the Pino interface with the following:
222
+
223
+ - **Methods:** `info`, `error`, `debug`, `fatal`, `warn`, `trace`, `silent`,
224
+ `child`
225
+ - **Properties:** `level` (string)
222
226
 
223
227
  Example:
224
228
 
@@ -239,7 +243,7 @@ fastify.get('/', function (request, reply) {
239
243
 
240
244
  ### Log Redaction
241
245
 
242
- [Pino](https://getpino.io) supports low-overhead log redaction for obscuring
246
+ [Pino](https://getpino.io) supports low-overhead log redaction for masking
243
247
  values of specific properties in recorded logs. For example, log all HTTP
244
248
  headers except the `Authorization` header for security:
245
249
 
@@ -265,4 +269,5 @@ const fastify = Fastify({
265
269
  })
266
270
  ```
267
271
 
268
- See https://getpino.io/#/docs/redaction for more details.
272
+ See the [Pino redaction documentation](https://getpino.io/#/docs/redaction) for
273
+ more details.
@@ -2,15 +2,13 @@
2
2
 
3
3
  ## Middleware
4
4
 
5
- Starting with Fastify v3.0.0, middleware is not supported out of the box and
6
- requires an external plugin such as
5
+ As of Fastify v3.0.0, middleware is not supported out of the box and requires
6
+ an external plugin such as
7
7
  [`@fastify/express`](https://github.com/fastify/fastify-express) or
8
8
  [`@fastify/middie`](https://github.com/fastify/middie).
9
9
 
10
-
11
- An example of registering the
12
- [`@fastify/express`](https://github.com/fastify/fastify-express) plugin to `use`
13
- Express middleware:
10
+ The following example registers the `@fastify/express` plugin and uses Express
11
+ middleware:
14
12
 
15
13
  ```js
16
14
  await fastify.register(require('@fastify/express'))
@@ -22,37 +20,35 @@ fastify.use(require('ienoopen')())
22
20
  fastify.use(require('x-xss-protection')())
23
21
  ```
24
22
 
25
- [`@fastify/middie`](https://github.com/fastify/middie) can also be used,
26
- which provides support for simple Express-style middleware with improved
27
- performance:
23
+ [`@fastify/middie`](https://github.com/fastify/middie) can also be used, which
24
+ provides support for simple Express-style middleware with improved performance:
28
25
 
29
26
  ```js
30
27
  await fastify.register(require('@fastify/middie'))
31
28
  fastify.use(require('cors')())
32
29
  ```
33
30
 
34
- Middleware can be encapsulated, allowing control over where it runs using
35
- `register` as explained in the [plugins guide](../Guides/Plugins-Guide.md).
31
+ Middleware can be encapsulated using `register`, which controls where it runs,
32
+ as explained in the [Plugins Guide](../Guides/Plugins-Guide.md).
36
33
 
37
- Fastify middleware does not expose the `send` method or other methods specific
38
- to the Fastify [Reply](./Reply.md#reply) instance. This is because Fastify wraps
39
- the incoming `req` and `res` Node instances using the
40
- [Request](./Request.md#request) and [Reply](./Reply.md#reply) objects
41
- internally, but this is done after the middleware phase. To create middleware,
42
- use the Node `req` and `res` instances. Alternatively, use the `preHandler` hook
43
- that already has the Fastify [Request](./Request.md#request) and
44
- [Reply](./Reply.md#reply) instances. For more information, see
45
- [Hooks](./Hooks.md#hooks).
34
+ This is because Fastify wraps the incoming Node.js `req` and `res` objects into
35
+ [Request](./Request.md#request) and [Reply](./Reply.md#reply) instances after
36
+ the middleware phase. As a result, Fastify middleware does not expose the `send`
37
+ method or other methods specific to the Fastify [Reply](./Reply.md#reply)
38
+ instance. To create middleware, use the Node.js `req` and `res` objects.
39
+ Alternatively, use the `preHandler` hook, which has access to the Fastify
40
+ [Request](./Request.md#request) and [Reply](./Reply.md#reply) instances. For
41
+ more information, see [Hooks](./Hooks.md).
46
42
 
47
- #### Restrict middleware execution to certain paths
43
+ ### Restrict Middleware Execution to Certain Paths
48
44
  <a id="restrict-usage"></a>
49
45
 
50
- To run middleware under certain paths, pass the path as the first parameter to
46
+ To restrict middleware to specific paths, pass the path as the first argument to
51
47
  `use`.
52
48
 
53
49
  > ℹ️ Note:
54
50
  > This does not support routes with parameters
55
- > (e.g. `/user/:id/comments`) and wildcards are not supported in multiple paths.
51
+ > (e.g., `/user/:id/comments`). Wildcards are not supported in multiple paths.
56
52
 
57
53
  ```js
58
54
  const path = require('node:path')
@@ -68,9 +64,9 @@ fastify.use('/css/(.*)', serveStatic(path.join(__dirname, '/assets')))
68
64
  fastify.use(['/css', '/js'], serveStatic(path.join(__dirname, '/assets')))
69
65
  ```
70
66
 
71
- ### Alternatives
67
+ ### Fastify Alternatives
72
68
 
73
- Fastify offers alternatives to commonly used middleware, such as
69
+ Fastify offers native alternatives to commonly used middleware, such as
74
70
  [`@fastify/helmet`](https://github.com/fastify/fastify-helmet) for
75
71
  [`helmet`](https://github.com/helmetjs/helmet),
76
72
  [`@fastify/cors`](https://github.com/fastify/fastify-cors) for
@@ -3,8 +3,8 @@
3
3
  Every decision in the Fastify framework and its official plugins is guided by
4
4
  the following technical principles:
5
5
 
6
- 1. Zero overhead in production
7
- 2. Good developer experience
6
+ 1. "Zero" overhead in production
7
+ 2. "Good" developer experience
8
8
  3. Works great for small & big projects alike
9
9
  4. Easy to migrate to microservices (or even serverless) and back
10
10
  5. Security & data validation
@@ -219,7 +219,7 @@ reply.getHeaders() // { 'x-foo': 'foo', 'x-bar': 'bar' }
219
219
  ```
220
220
 
221
221
  ### .removeHeader(key)
222
- <a id="getHeader"></a>
222
+ <a id="removeHeader"></a>
223
223
 
224
224
  Remove the value of a previously set header.
225
225
  ```js
@@ -705,6 +705,11 @@ If you are sending a stream and you have not set a `'Content-Type'` header,
705
705
  As noted above, streams are considered to be pre-serialized, so they will be
706
706
  sent unmodified without response validation.
707
707
 
708
+ When sending streams over HTTP/2, Fastify does not change the chunks emitted by
709
+ the stream. If a stream can emit very large chunks, split them in your
710
+ application code, for example by using `fs.createReadStream()` or a transform
711
+ stream that emits smaller chunks.
712
+
708
713
  See special note about error handling for streams in
709
714
  [`setErrorHandler`](./Server.md#seterrorhandler).
710
715
 
@@ -16,28 +16,39 @@ Request is a core Fastify object containing the following fields:
16
16
  [encapsulation context](./Encapsulation.md).
17
17
  - `id` - The request ID.
18
18
  - `log` - The logger instance of the incoming request.
19
- - `ip` - The IP address of the incoming request.
20
- - `ips` - An array of the IP addresses, ordered from closest to furthest, in the
21
- `X-Forwarded-For` header of the incoming request (only when the
22
- [`trustProxy`](./Server.md#factory-trust-proxy) option is enabled).
19
+ - `ip` - The IP address of the incoming request. This value is taken from
20
+ `socket.remoteAddress` (or from `X-Forwarded-For` when
21
+ [`trustProxy`](./Server.md#factory-trust-proxy) is enabled).
22
+ - `ips` - An array of IP addresses, ordered from closest to furthest, from
23
+ `X-Forwarded-For` (only when
24
+ [`trustProxy`](./Server.md#factory-trust-proxy) is enabled).
23
25
  - `host` - The host of the incoming request (derived from `X-Forwarded-Host`
24
- header when the [`trustProxy`](./Server.md#factory-trust-proxy) option is
25
- enabled). For HTTP/2 compatibility, it returns `:authority` if no host header
26
- exists. The host header may return an empty string if `requireHostHeader` is
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)).
33
- - `hostname` - The hostname derived from the `host` property of the incoming request.
34
- - `port` - The port from the `host` property, which may refer to the port the
26
+ when [`trustProxy`](./Server.md#factory-trust-proxy) is enabled). For HTTP/2
27
+ compatibility, it returns `:authority` if no host header exists. The host
28
+ header may return an empty string if `requireHostHeader` is `false`, not
29
+ provided with HTTP/1.0, or removed by schema validation.
30
+ - `hostname` - The hostname parsed from `request.host`.
31
+ - `port` - The port parsed from `request.host`, which may refer to the port the
35
32
  server is listening on.
36
- - `protocol` - The protocol of the incoming request (`https` or `http`).
33
+ - `protocol` - The protocol of the incoming request (`https` or `http`). This
34
+ value comes from `socket.encrypted` (or `X-Forwarded-Proto` when
35
+ [`trustProxy`](./Server.md#factory-trust-proxy) is enabled).
36
+
37
+ > ⚠️ Security:
38
+ > `request.ip`, `request.ips`, `request.host`, `request.hostname`,
39
+ > `request.port`, and `request.protocol` come from request metadata
40
+ > (socket and/or forwarding headers) and should be treated as untrusted input.
41
+ > Fastify does not perform security validation for business logic.
42
+ > If these values are used in security-sensitive decisions, they must
43
+ > be validated explicitly (for example: trusted proxy configuration,
44
+ > allow-lists, strict parsing, and normalization).
45
+
37
46
  - `method` - The method of the incoming request.
38
47
  - `url` - The URL of the incoming request.
39
48
  - `originalUrl` - Similar to `url`, allows access to the original `url` in
40
49
  case of internal re-routing.
50
+ - `mediaType` - The media type extracted from `Content-Type` header. When `Content-Type`
51
+ header is missing, it will return `undefined`.
41
52
  - `is404` - `true` if request is being handled by 404 handler, `false` otherwise.
42
53
  - `socket` - The underlying connection of the incoming request.
43
54
  - `signal` - An `AbortSignal` that aborts when the handler timeout
@@ -102,7 +102,7 @@ fastify.route(options)
102
102
  schemas for request validations. See the [Validation and
103
103
  Serialization](./Validation-and-Serialization.md#schema-validator)
104
104
  documentation.
105
- * `serializerCompiler({ { schema, method, url, httpStatus, contentType } })`:
105
+ * `serializerCompiler({ schema, method, url, httpStatus, contentType })`:
106
106
  function that builds schemas for response serialization. See the [Validation and
107
107
  Serialization](./Validation-and-Serialization.md#schema-serializer)
108
108
  documentation.
@@ -513,6 +513,9 @@ See the `prefixTrailingSlash` route option above to change this behavior.
513
513
  Different log levels can be set for routes in Fastify by passing the `logLevel`
514
514
  option to the plugin or route with the desired
515
515
  [value](https://github.com/pinojs/pino/blob/main/docs/api.md#level-string).
516
+ If a route `logLevel` is invalid, Fastify throws
517
+ [`FST_ERR_ROUTE_LOG_LEVEL_INVALID`](./Errors.md#fst_err_route_log_level_invalid)
518
+ during route registration.
516
519
 
517
520
  Be aware that setting `logLevel` at the plugin level also affects
518
521
  [`setNotFoundHandler`](./Server.md#setnotfoundhandler) and
@@ -670,7 +673,7 @@ fastify.inject({
670
673
 
671
674
  > ⚠ Warning:
672
675
  > Set a
673
- > [`Vary`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary)
676
+ > [`Vary`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Vary)
674
677
  > header in responses with the value used for versioning
675
678
  > (e.g., `'Accept-Version'`) to prevent cache poisoning attacks.
676
679
  > This can also be configured in a Proxy/CDN.
@@ -48,6 +48,7 @@ describes the properties available in that options object.
48
48
  - [`ignoreTrailingSlash`](#ignoretrailingslash)
49
49
  - [`maxParamLength`](#maxparamlength)
50
50
  - [`onBadUrl`](#onbadurl)
51
+ - [`onMaxParamLength`](#onmaxparamlength)
51
52
  - [`querystringParser`](#querystringparser)
52
53
  - [`useSemicolonDelimiter`](#usesemicolondelimiter)
53
54
  - [Instance](#instance)
@@ -560,6 +561,12 @@ For more examples, refer to the
560
561
  You may access the `ip`, `ips`, `host` and `protocol` values on the
561
562
  [`request`](./Request.md) object.
562
563
 
564
+ > ⚠️ Security:
565
+ > These values are derived from socket/forwarding metadata and must be treated
566
+ > as untrusted input unless your proxy chain is explicitly trusted and
567
+ > validated. Do not use them directly for authorization or other
568
+ > security-sensitive decisions without explicit validation.
569
+
563
570
  ```js
564
571
  fastify.get('/', (request, reply) => {
565
572
  console.log(request.ip)
@@ -720,7 +727,7 @@ const fastify = require('fastify')({
720
727
  res.code(400)
721
728
  return res.send("Provided header is not valid")
722
729
  } else {
723
- res.send(err)
730
+ res.send(error)
724
731
  }
725
732
  }
726
733
  })
@@ -921,7 +928,7 @@ const fastify = require('fastify')({
921
928
  ```
922
929
 
923
930
  ### `defaultRoute`
924
- <a id="on-bad-url"></a>
931
+ <a id="default-route"></a>
925
932
 
926
933
  Fastify uses [find-my-way](https://github.com/delvedor/find-my-way) which supports,
927
934
  can pass a default route with the option defaultRoute.
@@ -1037,6 +1044,27 @@ const fastify = require('fastify')({
1037
1044
  As with `defaultRoute`, `req` and `res` are the raw Node.js request/response
1038
1045
  objects and do not provide Fastify's decorated helpers.
1039
1046
 
1047
+ ### `onMaxParamLength`
1048
+ <a id="on-max-param-length"></a>
1049
+
1050
+ Fastify uses [find-my-way](https://github.com/delvedor/find-my-way) which supports,
1051
+ the use case of a provide custom handler when `maxParamLength ` is exceed.
1052
+
1053
+ ```js
1054
+ const fastify = require('fastify')({
1055
+ routerOptions: {
1056
+ maxParamLength: 10,
1057
+ onMaxParamLength: (path, req, res) => {
1058
+ res.statusCode = 414
1059
+ res.end(`Bad path: ${path}`)
1060
+ }
1061
+ }
1062
+ })
1063
+ ```
1064
+
1065
+ As with `defaultRoute`, `req` and `res` are the raw Node.js request/response
1066
+ objects and do not provide Fastify's decorated helpers.
1067
+
1040
1068
  ### `querystringParser`
1041
1069
  <a id="querystringparser"></a>
1042
1070
 
@@ -2249,7 +2277,7 @@ fastify.get('/', {
2249
2277
  return
2250
2278
  }
2251
2279
 
2252
- fastify.errorHandler(error, request, response)
2280
+ fastify.errorHandler(error, request, reply)
2253
2281
  }
2254
2282
  }, handler)
2255
2283
  ```
@@ -23,8 +23,7 @@ See also the Type Provider wrapper packages for each of the packages respectivel
23
23
 
24
24
  - [`@fastify/type-provider-json-schema-to-ts`](https://github.com/fastify/fastify-type-provider-json-schema-to-ts)
25
25
  - [`@fastify/type-provider-typebox`](https://github.com/fastify/fastify-type-provider-typebox)
26
- - [`fastify-type-provider-zod`](https://github.com/turkerdev/fastify-type-provider-zod)
27
- (3rd party)
26
+ - [`@fastify/type-provider-zod`](https://github.com/fastify/fastify-type-provider-zod)
28
27
 
29
28
  ### Json Schema to Ts
30
29
 
@@ -88,14 +87,39 @@ server.get('/route', {
88
87
  ```
89
88
 
90
89
  See the [TypeBox
91
- documentation](https://sinclairzx81.github.io/typebox/#/docs/overview/2_setup)
90
+ documentation](https://sinclairzx81.github.io/typebox/)
92
91
  for setting-up AJV to work with TypeBox.
93
92
 
94
93
  ### Zod
95
94
 
96
- See [official documentation](https://github.com/turkerdev/fastify-type-provider-zod)
97
- for Zod Type Provider instructions.
95
+ The following sets up a Zod Type Provider:
98
96
 
97
+ ```bash
98
+ $ npm i zod @fastify/type-provider-zod
99
+ ```
100
+
101
+ ```typescript
102
+ import fastify from 'fastify'
103
+ import { ZodTypeProvider, serializerCompiler, validatorCompiler } from '@fastify/type-provider-zod'
104
+ import { z } from 'zod/v4'
105
+
106
+ const server = fastify()
107
+ server.setValidatorCompiler(validatorCompiler)
108
+ server.setSerializerCompiler(serializerCompiler)
109
+
110
+ server.withTypeProvider<ZodTypeProvider>().get('/route', {
111
+ schema: {
112
+ querystring: z.object({
113
+ foo: z.number(),
114
+ bar: z.string()
115
+ })
116
+ }
117
+ }, (request, reply) => {
118
+
119
+ // type Query = { foo: number, bar: string }
120
+ const { foo, bar } = request.query // type safe!
121
+ })
122
+ ```
99
123
 
100
124
  ### Scoped Type-Provider
101
125
 
@@ -300,6 +300,12 @@ Note that Ajv will try to [coerce](https://ajv.js.org/coercion.html) values to
300
300
  the types specified in the schema `type` keywords, both to pass validation and
301
301
  to use the correctly typed data afterwards.
302
302
 
303
+ > ⚠ Important:
304
+ > Fastify uses a custom [AJV configuration][1] such as `coerceTypes: 'array'`.
305
+ > Evaluate its behavior and verify if it meets the project requirements.
306
+
307
+ [1]: https://github.com/fastify/ajv-compiler?tab=readme-ov-file#ajv-configuration
308
+
303
309
  The Ajv default configuration in Fastify supports coercing array parameters in
304
310
  `querystring`. Example:
305
311
 
@@ -583,6 +589,11 @@ fastify.post('/the/url', {
583
589
  }, handler)
584
590
  ```
585
591
 
592
+ Fastify supports different JSON Schema validators via
593
+ `setValidatorCompiler`. Community plugins that integrate alternative JSON
594
+ Schema validators are listed on the
595
+ [Ecosystem](https://fastify.dev/docs/latest/Guides/Ecosystem/) page.
596
+
586
597
  ##### Custom Validator Best Practices
587
598
 
588
599
  When implementing custom validators, follow these patterns to ensure compatibility
@@ -920,8 +931,10 @@ For custom error responses in the schema, see
920
931
  [example](https://github.com/fastify/example/blob/HEAD/validation-messages/custom-errors-messages.js)
921
932
  usage.
922
933
 
923
- > Install version 1.0.1 of `ajv-errors`, as later versions are not compatible
924
- > with AJV v6 (the version shipped by Fastify v3).
934
+ > Fastify v5 uses AJV v8 and requires a compatible `ajv-errors` version.
935
+ > Fastify v3 requires `ajv-errors@1.0.1`, which supports AJV v6.
936
+ > See the [AJV compiler versions table](https://github.com/fastify/ajv-compiler/#versions)
937
+ > for the AJV version used by each Fastify release.
925
938
 
926
939
  Below is an example showing how to add **custom error messages for each
927
940
  property** of a schema by supplying custom AJV options. Inline comments in the
@@ -6,7 +6,8 @@
6
6
  - [Warnings In Fastify](#warnings-in-fastify)
7
7
  - [Fastify Warning Codes](#fastify-warning-codes)
8
8
  - [FSTWRN001](#FSTWRN001)
9
- - [FSTWRN002](#FSTWRN002)
9
+ - [FSTWRN003](#FSTWRN003)
10
+ - [FSTWRN004](#FSTWRN004)
10
11
  - [Fastify Deprecation Codes](#fastify-deprecation-codes)
11
12
  - [FSTDEP022](#FSTDEP022)
12
13
 
@@ -14,7 +15,7 @@
14
15
 
15
16
  ### Warnings In Fastify
16
17
 
17
- Fastify uses Node.js's [warning event](https://nodejs.org/api/process.html#event-warning)
18
+ Fastify uses the Node.js [warning event](https://nodejs.org/api/process.html#event-warning)
18
19
  API to notify users of deprecated features and coding mistakes. Fastify's
19
20
  warnings are recognizable by the `FSTWRN` and `FSTDEP` prefixes. When
20
21
  encountering such a warning, it is highly recommended to determine the cause
@@ -22,7 +23,7 @@ using the [`--trace-warnings`](https://nodejs.org/api/cli.html#trace-warnings)
22
23
  and [`--trace-deprecation`](https://nodejs.org/api/cli.html#trace-deprecation)
23
24
  flags. These produce stack traces pointing to where the issue occurs in the
24
25
  application's code. Issues opened about warnings without this information will
25
- be closed due to lack of details.
26
+ be closed.
26
27
 
27
28
  Warnings can also be disabled, though it is not recommended. If necessary, use
28
29
  one of the following methods:
@@ -33,15 +34,15 @@ one of the following methods:
33
34
 
34
35
  For more information on disabling warnings, see [Node's documentation](https://nodejs.org/api/cli.html).
35
36
 
36
- Disabling warnings may cause issues when upgrading Fastify versions. Only
37
- experienced users should consider disabling warnings.
37
+ Disabling warnings is not recommended and may cause unexpected behavior.
38
38
 
39
39
  ### Fastify Warning Codes
40
40
 
41
41
  | Code | Description | How to solve | Discussion |
42
42
  | ---- | ----------- | ------------ | ---------- |
43
43
  | <a id="FSTWRN001">FSTWRN001</a> | The specified schema for a route is missing. This may indicate the schema is not well specified. | Check the schema for the route. | [#4647](https://github.com/fastify/fastify/pull/4647) |
44
- | <a id="FSTWRN002">FSTWRN002</a> | The %s plugin being registered mixes async and callback styles, which will result in an error in `fastify@5`. | Do not mix async and callback style. | [#5139](https://github.com/fastify/fastify/pull/5139) |
44
+ | <a id="FSTWRN003">FSTWRN003</a> | The `%s` plugin mixes async and callback styles, which may lead to unhandled rejections. | Do not mix async and callback style. | [#6011](https://github.com/fastify/fastify/pull/6011) |
45
+ | <a id="FSTWRN004">FSTWRN004</a> | An `errorHandler` is being overridden in the same scope, which can lead to subtle bugs. | Avoid calling `setErrorHandler` more than once in the same scope. For more information, see [Server documentation](https://fastify.dev/docs/latest/Reference/Server/#allowerrorhandleroverride). | [#6104](https://github.com/fastify/fastify/pull/6104) |
45
46
 
46
47
 
47
48
  ### Fastify Deprecation Codes
package/eslint.config.js CHANGED
@@ -6,8 +6,7 @@ module.exports = [
6
6
  ignores: [
7
7
  'lib/config-validator.js',
8
8
  'lib/error-serializer.js',
9
- 'test/same-shape.test.js',
10
- 'test/types/import.js'
9
+ 'test/same-shape.test.js'
11
10
  ],
12
11
  ts: true
13
12
  }),
@@ -31,5 +30,11 @@ module.exports = [
31
30
  rules: {
32
31
  'max-len': 'off'
33
32
  }
33
+ },
34
+ {
35
+ files: ['test/types/**/*'],
36
+ rules: {
37
+ '@typescript-eslint/no-unused-vars': 'off'
38
+ }
34
39
  }
35
40
  ]