fastify 5.8.4 → 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.
- package/SECURITY.md +1 -1
- package/SPONSORS.md +6 -4
- package/docs/Guides/Database.md +0 -28
- package/docs/Guides/Ecosystem.md +17 -2
- package/docs/Guides/Serverless.md +2 -2
- package/docs/Guides/Write-Plugin.md +1 -1
- package/docs/Reference/Encapsulation.md +27 -26
- package/docs/Reference/Errors.md +10 -4
- package/docs/Reference/HTTP2.md +10 -10
- package/docs/Reference/Hooks.md +4 -4
- package/docs/Reference/Index.md +14 -16
- package/docs/Reference/LTS.md +12 -13
- package/docs/Reference/Lifecycle.md +9 -8
- package/docs/Reference/Logging.md +44 -39
- package/docs/Reference/Middleware.md +21 -25
- package/docs/Reference/Principles.md +2 -2
- package/docs/Reference/Reply.md +6 -1
- package/docs/Reference/Request.md +27 -16
- package/docs/Reference/Routes.md +5 -2
- package/docs/Reference/Server.md +31 -3
- package/docs/Reference/Type-Providers.md +29 -5
- package/docs/Reference/Validation-and-Serialization.md +15 -2
- package/docs/Reference/Warnings.md +7 -6
- package/eslint.config.js +7 -2
- package/fastify.d.ts +8 -3
- package/fastify.js +43 -14
- package/lib/content-type-parser.js +13 -1
- package/lib/decorate.js +11 -3
- package/lib/error-handler.js +4 -3
- package/lib/error-serializer.js +59 -59
- package/lib/errors.js +16 -1
- package/lib/four-oh-four.js +14 -9
- package/lib/handle-request.js +11 -5
- package/lib/plugin-override.js +2 -1
- package/lib/plugin-utils.js +5 -5
- package/lib/reply.js +63 -8
- package/lib/request.js +23 -19
- package/lib/route.js +20 -6
- package/lib/schema-controller.js +1 -1
- package/lib/schemas.js +37 -30
- package/lib/symbols.js +3 -1
- package/lib/validation.js +1 -13
- package/lib/warnings.js +3 -3
- package/package.json +16 -18
- package/scripts/validate-ecosystem-links.js +1 -0
- package/test/bundler/esbuild/package.json +1 -1
- package/test/close-pipelining.test.js +1 -2
- package/test/custom-http-server.test.js +38 -0
- package/test/decorator-instance-properties.test.js +63 -0
- package/test/diagnostics-channel/async-error-handler.test.js +74 -0
- package/test/hooks.test.js +23 -0
- package/test/http-methods/get.test.js +1 -1
- package/test/http2/plain.test.js +135 -0
- package/test/http2/secure-with-fallback.test.js +1 -1
- package/test/https/https.test.js +1 -2
- package/test/internals/errors.test.js +31 -1
- package/test/internals/plugin.test.js +3 -1
- package/test/internals/request.test.js +27 -3
- package/test/internals/schema-controller-perf.test.js +33 -0
- package/test/logger/logging.test.js +18 -1
- package/test/logger/options.test.js +38 -1
- package/test/reply-error.test.js +1 -1
- package/test/reply-trailers.test.js +70 -0
- package/test/request-media-type.test.js +105 -0
- package/test/request-port.test.js +72 -0
- package/test/route-prefix.test.js +34 -0
- package/test/router-options.test.js +222 -11
- package/test/schema-serialization.test.js +108 -0
- package/test/schema-validation.test.js +45 -0
- package/test/scripts/validate-ecosystem-links.test.js +40 -57
- package/test/throw.test.js +14 -0
- package/test/trust-proxy.test.js +74 -0
- package/test/types/content-type-parser.tst.ts +70 -0
- package/test/types/{decorate-request-reply.test-d.ts → decorate-request-reply.tst.ts} +4 -4
- package/test/types/{dummy-plugin.ts → dummy-plugin.mts} +1 -1
- package/test/types/errors.tst.ts +91 -0
- package/test/types/fastify.tst.ts +351 -0
- package/test/types/hooks.tst.ts +578 -0
- package/test/types/instance.tst.ts +597 -0
- package/test/types/{logger.test-d.ts → logger.tst.ts} +61 -62
- package/test/types/plugin.tst.ts +96 -0
- package/test/types/register.tst.ts +245 -0
- package/test/types/reply.tst.ts +297 -0
- package/test/types/request.tst.ts +199 -0
- package/test/types/route.tst.ts +576 -0
- package/test/types/{schema.test-d.ts → schema.tst.ts} +22 -22
- package/test/types/{serverFactory.test-d.ts → serverFactory.tst.ts} +4 -4
- package/test/types/tsconfig.json +9 -0
- package/test/types/{type-provider.test-d.ts → type-provider.tst.ts} +256 -250
- package/test/types/using.tst.ts +14 -0
- package/types/errors.d.ts +3 -0
- package/types/request.d.ts +23 -2
- package/AGENTS.md +0 -290
- package/test/types/content-type-parser.test-d.ts +0 -72
- package/test/types/errors.test-d.ts +0 -90
- package/test/types/fastify.test-d.ts +0 -352
- package/test/types/hooks.test-d.ts +0 -550
- package/test/types/import.ts +0 -2
- package/test/types/instance.test-d.ts +0 -588
- package/test/types/plugin.test-d.ts +0 -97
- package/test/types/register.test-d.ts +0 -237
- package/test/types/reply.test-d.ts +0 -254
- package/test/types/request.test-d.ts +0 -188
- package/test/types/route.test-d.ts +0 -553
- 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
|
|
17
|
-
|
|
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
|
|
27
|
-
|
|
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
|
|
44
|
+
logger: envToLogger[environment] ?? true // defaults to true if no matching environment is found
|
|
45
45
|
})
|
|
46
46
|
```
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
61
|
-
|
|
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' //
|
|
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
|
|
107
|
-
[`requestIdHeader`](./Server.md#factory-request-id-header) and
|
|
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
|
|
112
|
-
> value
|
|
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
|
|
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
|
-
|
|
133
|
-
|
|
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,
|
|
169
|
-
> `
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
220
|
-
|
|
221
|
-
`
|
|
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
|
|
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
|
|
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
|
-
|
|
6
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
35
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
the
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
use the
|
|
43
|
-
|
|
44
|
-
[
|
|
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
|
-
|
|
43
|
+
### Restrict Middleware Execution to Certain Paths
|
|
48
44
|
<a id="restrict-usage"></a>
|
|
49
45
|
|
|
50
|
-
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
|
|
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.
|
|
7
|
-
2.
|
|
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
|
package/docs/Reference/Reply.md
CHANGED
|
@@ -219,7 +219,7 @@ reply.getHeaders() // { 'x-foo': 'foo', 'x-bar': 'bar' }
|
|
|
219
219
|
```
|
|
220
220
|
|
|
221
221
|
### .removeHeader(key)
|
|
222
|
-
<a id="
|
|
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
|
-
|
|
21
|
-
`
|
|
22
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
package/docs/Reference/Routes.md
CHANGED
|
@@ -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({
|
|
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.
|
package/docs/Reference/Server.md
CHANGED
|
@@ -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(
|
|
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="
|
|
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,
|
|
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
|
-
- [
|
|
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
|
|
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
|
-
|
|
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
|
-
>
|
|
924
|
-
>
|
|
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
|
-
- [
|
|
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
|
|
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
|
|
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
|
|
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="
|
|
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
|
]
|