fastify 5.2.0 → 5.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/PROJECT_CHARTER.md +7 -7
- package/README.md +65 -67
- package/SPONSORS.md +2 -0
- package/build/build-validation.js +1 -1
- package/docs/Guides/Benchmarking.md +4 -4
- package/docs/Guides/Database.md +1 -1
- package/docs/Guides/Delay-Accepting-Requests.md +10 -10
- package/docs/Guides/Ecosystem.md +5 -1
- package/docs/Guides/Fluent-Schema.md +1 -1
- package/docs/Guides/Getting-Started.md +9 -5
- package/docs/Guides/Index.md +1 -1
- package/docs/Guides/Migration-Guide-V4.md +1 -1
- package/docs/Guides/Migration-Guide-V5.md +12 -2
- package/docs/Guides/Plugins-Guide.md +6 -6
- package/docs/Guides/Serverless.md +14 -48
- package/docs/Guides/Style-Guide.md +2 -2
- package/docs/Guides/Testing.md +2 -2
- package/docs/Guides/Write-Plugin.md +2 -3
- package/docs/Reference/ContentTypeParser.md +58 -78
- package/docs/Reference/Decorators.md +50 -60
- package/docs/Reference/Encapsulation.md +28 -33
- package/docs/Reference/Errors.md +52 -53
- package/docs/Reference/HTTP2.md +7 -7
- package/docs/Reference/Hooks.md +31 -30
- package/docs/Reference/LTS.md +10 -15
- package/docs/Reference/Lifecycle.md +19 -24
- package/docs/Reference/Logging.md +59 -56
- package/docs/Reference/Middleware.md +19 -19
- package/docs/Reference/Plugins.md +55 -71
- package/docs/Reference/Principles.md +25 -30
- package/docs/Reference/Reply.md +11 -10
- package/docs/Reference/Request.md +89 -99
- package/docs/Reference/Routes.md +108 -128
- package/docs/Reference/Server.md +19 -17
- package/docs/Reference/Type-Providers.md +19 -21
- package/docs/Reference/TypeScript.md +1 -18
- package/docs/Reference/Validation-and-Serialization.md +134 -159
- package/docs/Reference/Warnings.md +22 -25
- package/fastify.js +1 -1
- package/lib/contentTypeParser.js +7 -8
- package/lib/error-handler.js +14 -12
- package/lib/errors.js +4 -0
- package/lib/headRoute.js +4 -2
- package/lib/pluginUtils.js +4 -2
- package/lib/reply.js +4 -0
- package/lib/request.js +13 -9
- package/lib/server.js +5 -0
- package/lib/validation.js +1 -1
- package/lib/warnings.js +9 -0
- package/lib/wrapThenable.js +8 -1
- package/package.json +28 -17
- package/test/build/error-serializer.test.js +2 -1
- package/test/bundler/esbuild/package.json +1 -1
- package/test/close.test.js +125 -108
- package/test/custom-parser-async.test.js +34 -36
- package/test/custom-parser.2.test.js +19 -20
- package/test/custom-parser.3.test.js +56 -45
- package/test/delete.test.js +79 -67
- package/test/genReqId.test.js +125 -174
- package/test/has-route.test.js +1 -3
- package/test/internals/content-type-parser.test.js +1 -1
- package/test/internals/errors.test.js +19 -7
- package/test/issue-4959.test.js +84 -0
- package/test/listen.1.test.js +37 -34
- package/test/listen.2.test.js +47 -40
- package/test/listen.3.test.js +28 -32
- package/test/listen.4.test.js +61 -45
- package/test/listen.5.test.js +23 -0
- package/test/nullable-validation.test.js +30 -27
- package/test/register.test.js +55 -50
- package/test/request-error.test.js +114 -94
- package/test/route-shorthand.test.js +36 -32
- package/test/server.test.js +0 -175
- package/test/stream.5.test.js +35 -33
- package/test/throw.test.js +87 -91
- package/test/toolkit.js +32 -0
- package/test/trust-proxy.test.js +23 -23
- package/test/types/instance.test-d.ts +1 -0
- package/test/upgrade.test.js +32 -30
- package/test/web-api.test.js +44 -0
- package/types/instance.d.ts +4 -0
- package/test/test-reporter.mjs +0 -68
|
@@ -2,18 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## Type Providers
|
|
4
4
|
|
|
5
|
-
Type Providers are a TypeScript
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
Type Providers are a TypeScript feature that enables Fastify to infer type
|
|
6
|
+
information from inline JSON Schema. They are an alternative to specifying
|
|
7
|
+
generic arguments on routes and can reduce the need to keep associated types for
|
|
8
|
+
each schema in a project.
|
|
9
9
|
|
|
10
10
|
### Providers
|
|
11
11
|
|
|
12
|
-
Type
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Provider packages follow a `@fastify/type-provider-{provider-name}` naming
|
|
16
|
-
convention, and there are several community ones available as well.
|
|
12
|
+
Official Type Provider packages follow the
|
|
13
|
+
`@fastify/type-provider-{provider-name}` naming convention.
|
|
14
|
+
Several community providers are also available.
|
|
17
15
|
|
|
18
16
|
The following inference packages are supported:
|
|
19
17
|
|
|
@@ -30,7 +28,7 @@ See also the Type Provider wrapper packages for each of the packages respectivel
|
|
|
30
28
|
|
|
31
29
|
### Json Schema to Ts
|
|
32
30
|
|
|
33
|
-
The following sets up a `json-schema-to-ts` Type Provider
|
|
31
|
+
The following sets up a `json-schema-to-ts` Type Provider:
|
|
34
32
|
|
|
35
33
|
```bash
|
|
36
34
|
$ npm i @fastify/type-provider-json-schema-to-ts
|
|
@@ -62,7 +60,7 @@ server.get('/route', {
|
|
|
62
60
|
|
|
63
61
|
### TypeBox
|
|
64
62
|
|
|
65
|
-
The following sets up a TypeBox Type Provider
|
|
63
|
+
The following sets up a TypeBox Type Provider:
|
|
66
64
|
|
|
67
65
|
```bash
|
|
68
66
|
$ npm i @fastify/type-provider-typebox
|
|
@@ -89,14 +87,14 @@ server.get('/route', {
|
|
|
89
87
|
})
|
|
90
88
|
```
|
|
91
89
|
|
|
92
|
-
See
|
|
93
|
-
documentation](https://github.com/sinclairzx81/typebox#validation)
|
|
94
|
-
up AJV to work with TypeBox.
|
|
90
|
+
See the [TypeBox
|
|
91
|
+
documentation](https://github.com/sinclairzx81/typebox#validation)
|
|
92
|
+
for setting up AJV to work with TypeBox.
|
|
95
93
|
|
|
96
94
|
### Zod
|
|
97
95
|
|
|
98
96
|
See [official documentation](https://github.com/turkerdev/fastify-type-provider-zod)
|
|
99
|
-
for Zod
|
|
97
|
+
for Zod Type Provider instructions.
|
|
100
98
|
|
|
101
99
|
|
|
102
100
|
### Scoped Type-Provider
|
|
@@ -154,9 +152,9 @@ fastify.register(pluginWithJsonSchema)
|
|
|
154
152
|
fastify.register(pluginWithTypebox)
|
|
155
153
|
```
|
|
156
154
|
|
|
157
|
-
It
|
|
158
|
-
|
|
159
|
-
|
|
155
|
+
It is important to note that since the types do not propagate globally, it is
|
|
156
|
+
currently not possible to avoid multiple registrations on routes when dealing
|
|
157
|
+
with several scopes, as shown below:
|
|
160
158
|
|
|
161
159
|
```ts
|
|
162
160
|
import Fastify from 'fastify'
|
|
@@ -178,7 +176,7 @@ function plugin1(fastify: FastifyInstance, _opts, done): void {
|
|
|
178
176
|
})
|
|
179
177
|
}
|
|
180
178
|
}, (req) => {
|
|
181
|
-
//
|
|
179
|
+
// In a new scope, call `withTypeProvider` again to ensure it works
|
|
182
180
|
const { x, y, z } = req.body
|
|
183
181
|
});
|
|
184
182
|
done()
|
|
@@ -205,8 +203,8 @@ function plugin2(fastify: FastifyInstance, _opts, done): void {
|
|
|
205
203
|
|
|
206
204
|
### Type Definition of FastifyInstance + TypeProvider
|
|
207
205
|
|
|
208
|
-
When working with modules
|
|
209
|
-
|
|
206
|
+
When working with modules, use `FastifyInstance` with Type Provider generics.
|
|
207
|
+
See the example below:
|
|
210
208
|
|
|
211
209
|
```ts
|
|
212
210
|
// index.ts
|
|
@@ -632,7 +632,7 @@ newer, automatically adds `.default` property and a named export to the exported
|
|
|
632
632
|
plugin. Be sure to `export default` and `export const myPlugin` in your typings
|
|
633
633
|
to provide the best developer experience. For a complete example you can check
|
|
634
634
|
out
|
|
635
|
-
[@fastify/swagger](https://github.com/fastify/fastify-swagger/blob/
|
|
635
|
+
[@fastify/swagger](https://github.com/fastify/fastify-swagger/blob/main/index.d.ts).
|
|
636
636
|
|
|
637
637
|
With those files completed, the plugin is now ready to be consumed by any
|
|
638
638
|
TypeScript project!
|
|
@@ -659,23 +659,6 @@ However, there are a couple of suggestions to help improve this experience:
|
|
|
659
659
|
- Make sure the `no-unused-vars` rule is enabled in
|
|
660
660
|
[ESLint](https://eslint.org/docs/rules/no-unused-vars) and any imported plugin
|
|
661
661
|
are actually being loaded.
|
|
662
|
-
- In case you've the `@typescript-eslint/no-floating-promises` enabled,
|
|
663
|
-
please double-check that your ESLint configuration includes a `allowForKnownSafePromises`
|
|
664
|
-
property as described on the [`typescript-eslint no-floating-promises allowForKnownSafePromises
|
|
665
|
-
documentation`](https://typescript-eslint.io/rules/no-floating-promises/#allowforknownsafepromises):
|
|
666
|
-
```
|
|
667
|
-
{
|
|
668
|
-
"rules": {
|
|
669
|
-
"@typescript-eslint/no-floating-promises": ["error", {
|
|
670
|
-
"allowForKnownSafePromises": [
|
|
671
|
-
{ "from": "package", "name": "FastifyInstance", "package": "fastify" },
|
|
672
|
-
{ "from": "package", "name": "FastifyReply", "package": "fastify" },
|
|
673
|
-
{ "from": "package", "name": "SafePromiseLike", "package": "fastify" },
|
|
674
|
-
]
|
|
675
|
-
}]
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
```
|
|
679
662
|
- Use a module such as [depcheck](https://www.npmjs.com/package/depcheck) or
|
|
680
663
|
[npm-check](https://www.npmjs.com/package/npm-check) to verify plugin
|
|
681
664
|
dependencies are being used somewhere in your project.
|
|
@@ -1,67 +1,56 @@
|
|
|
1
1
|
<h1 align="center">Fastify</h1>
|
|
2
2
|
|
|
3
3
|
## Validation and Serialization
|
|
4
|
-
Fastify uses a schema-based approach
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Validation will only be attempted if the content type is `application-json`, as
|
|
10
|
-
described in the documentation for the [content type
|
|
11
|
-
parser](./ContentTypeParser.md).
|
|
12
|
-
|
|
13
|
-
All the examples in this section are using the [JSON Schema Draft
|
|
14
|
-
7](https://json-schema.org/specification-links.html#draft-7) specification.
|
|
15
|
-
|
|
16
|
-
> ## ⚠ Security Notice
|
|
17
|
-
> Treat the schema definition as application code. Validation and serialization
|
|
18
|
-
> features dynamically evaluate code with `new Function()`, which is not safe to
|
|
19
|
-
> use with user-provided schemas. See [Ajv](https://npm.im/ajv) and
|
|
20
|
-
> [fast-json-stringify](https://npm.im/fast-json-stringify) for more details.
|
|
21
|
-
>
|
|
22
|
-
> Regardless the [`$async` Ajv
|
|
23
|
-
> feature](https://ajv.js.org/guide/async-validation.html) is supported
|
|
24
|
-
> by Fastify, it should not be used as
|
|
25
|
-
> part of the first validation strategy. This option is used to access Databases
|
|
26
|
-
> and reading them during the validation process may lead to Denial of Service
|
|
27
|
-
> Attacks to your application. If you need to run `async` tasks, use [Fastify's
|
|
28
|
-
> hooks](./Hooks.md) instead after validation completes, such as `preHandler`.
|
|
4
|
+
Fastify uses a schema-based approach. We recommend using
|
|
5
|
+
[JSON Schema](https://json-schema.org/) to validate routes and serialize outputs.
|
|
6
|
+
Fastify compiles the schema into a highly performant function.
|
|
7
|
+
|
|
8
|
+
Validation is only attempted if the content type is `application/json`.
|
|
29
9
|
|
|
10
|
+
All examples use the
|
|
11
|
+
[JSON Schema Draft 7](https://json-schema.org/specification-links.html#draft-7)
|
|
12
|
+
specification.
|
|
13
|
+
|
|
14
|
+
> ⚠ Warning:
|
|
15
|
+
> Treat schema definitions as application code. Validation and serialization
|
|
16
|
+
> features use `new Function()`, which is unsafe with user-provided schemas. See
|
|
17
|
+
> [Ajv](https://npm.im/ajv) and
|
|
18
|
+
> [fast-json-stringify](https://npm.im/fast-json-stringify) for details.
|
|
19
|
+
>
|
|
20
|
+
> Whilst Fastify supports the
|
|
21
|
+
> [`$async` Ajv feature](https://ajv.js.org/guide/async-validation.html),
|
|
22
|
+
> it should not be used for initial validation. Accessing databases during
|
|
23
|
+
> validation may lead to Denial of Service attacks. Use
|
|
24
|
+
> [Fastify's hooks](./Hooks.md) like `preHandler` for `async` tasks after validation.
|
|
30
25
|
|
|
31
26
|
### Core concepts
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- [Ajv v8](https://www.npmjs.com/package/ajv) for the validation of a request
|
|
27
|
+
Validation and serialization are handled by two customizable dependencies:
|
|
28
|
+
- [Ajv v8](https://www.npmjs.com/package/ajv) for request validation
|
|
35
29
|
- [fast-json-stringify](https://www.npmjs.com/package/fast-json-stringify) for
|
|
36
|
-
|
|
30
|
+
response body serialization
|
|
37
31
|
|
|
38
|
-
These
|
|
39
|
-
|
|
32
|
+
These dependencies share only the JSON schemas added to Fastify's instance via
|
|
33
|
+
`.addSchema(schema)`.
|
|
40
34
|
|
|
41
35
|
#### Adding a shared schema
|
|
42
36
|
<a id="shared-schema"></a>
|
|
43
37
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this API is encapsulated.
|
|
38
|
+
The `addSchema` API allows adding multiple schemas to the Fastify instance for
|
|
39
|
+
reuse throughout the application. This API is encapsulated.
|
|
47
40
|
|
|
48
|
-
|
|
41
|
+
Shared schemas can be reused with the JSON Schema
|
|
49
42
|
[**`$ref`**](https://tools.ietf.org/html/draft-handrews-json-schema-01#section-8)
|
|
50
|
-
keyword. Here is an overview of
|
|
43
|
+
keyword. Here is an overview of how references work:
|
|
51
44
|
|
|
52
|
-
+ `myField: { $ref: '#foo' }`
|
|
45
|
+
+ `myField: { $ref: '#foo' }` searches for `$id: '#foo'` in the current schema
|
|
46
|
+
+ `myField: { $ref: '#/definitions/foo' }` searches for `definitions.foo` in the
|
|
53
47
|
current schema
|
|
54
|
-
+ `myField: { $ref: '
|
|
55
|
-
|
|
56
|
-
+ `myField: { $ref: 'http://url.com/sh.json
|
|
57
|
-
|
|
58
|
-
+ `myField: { $ref: 'http://url.com/sh.json
|
|
59
|
-
|
|
60
|
-
field `definitions.foo`
|
|
61
|
-
+ `myField: { $ref: 'http://url.com/sh.json#foo' }` will search for a shared
|
|
62
|
-
schema added with `$id: 'http://url.com/sh.json'` and it will look inside of
|
|
63
|
-
it for object with `$id: '#foo'`
|
|
64
|
-
|
|
48
|
+
+ `myField: { $ref: 'http://url.com/sh.json#' }` searches for a shared schema
|
|
49
|
+
with `$id: 'http://url.com/sh.json'`
|
|
50
|
+
+ `myField: { $ref: 'http://url.com/sh.json#/definitions/foo' }` searches for a
|
|
51
|
+
shared schema with `$id: 'http://url.com/sh.json'` and uses `definitions.foo`
|
|
52
|
+
+ `myField: { $ref: 'http://url.com/sh.json#foo' }` searches for a shared schema
|
|
53
|
+
with `$id: 'http://url.com/sh.json'` and looks for `$id: '#foo'` within it
|
|
65
54
|
|
|
66
55
|
**Simple usage:**
|
|
67
56
|
|
|
@@ -108,9 +97,9 @@ fastify.post('/', {
|
|
|
108
97
|
#### Retrieving the shared schemas
|
|
109
98
|
<a id="get-shared-schema"></a>
|
|
110
99
|
|
|
111
|
-
If the validator and
|
|
112
|
-
|
|
113
|
-
|
|
100
|
+
If the validator and serializer are customized, `.addSchema` is not useful since
|
|
101
|
+
Fastify no longer controls them. To access schemas added to the Fastify instance,
|
|
102
|
+
use `.getSchemas()`:
|
|
114
103
|
|
|
115
104
|
```js
|
|
116
105
|
fastify.addSchema({
|
|
@@ -125,8 +114,8 @@ const mySchemas = fastify.getSchemas()
|
|
|
125
114
|
const mySchema = fastify.getSchema('schemaId')
|
|
126
115
|
```
|
|
127
116
|
|
|
128
|
-
|
|
129
|
-
|
|
117
|
+
The `getSchemas` function is encapsulated and returns shared schemas available
|
|
118
|
+
in the selected scope:
|
|
130
119
|
|
|
131
120
|
```js
|
|
132
121
|
fastify.addSchema({ $id: 'one', my: 'hello' })
|
|
@@ -150,25 +139,22 @@ fastify.register((instance, opts, done) => {
|
|
|
150
139
|
|
|
151
140
|
|
|
152
141
|
### Validation
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
- `body`: validates the body of the request if it is a POST, PUT, or PATCH
|
|
160
|
-
method.
|
|
142
|
+
Route validation relies on [Ajv v8](https://www.npmjs.com/package/ajv), a
|
|
143
|
+
high-performance JSON Schema validator. To validate input, add the required
|
|
144
|
+
fields to the route schema.
|
|
145
|
+
|
|
146
|
+
Supported validations include:
|
|
147
|
+
- `body`: validates the request body for POST, PUT, or PATCH methods.
|
|
161
148
|
- `querystring` or `query`: validates the query string.
|
|
162
|
-
- `params`: validates the route
|
|
149
|
+
- `params`: validates the route parameters.
|
|
163
150
|
- `headers`: validates the request headers.
|
|
164
151
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
parameters are listed at the top level (see the example below).
|
|
152
|
+
Validations can be a complete JSON Schema object with a `type` of `'object'` and
|
|
153
|
+
a `'properties'` object containing parameters, or a simpler variation listing
|
|
154
|
+
parameters at the top level.
|
|
169
155
|
|
|
170
|
-
> ℹ
|
|
171
|
-
>
|
|
156
|
+
> ℹ For using the latest Ajv (v8), refer to the
|
|
157
|
+
> [`schemaController`](./Server.md#schema-controller) section.
|
|
172
158
|
|
|
173
159
|
Example:
|
|
174
160
|
```js
|
|
@@ -257,9 +243,9 @@ fastify.post('/the/url', {
|
|
|
257
243
|
}, handler)
|
|
258
244
|
```
|
|
259
245
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
246
|
+
Note that Ajv will try to [coerce](https://ajv.js.org/coercion.html) values to
|
|
247
|
+
the types specified in the schema `type` keywords, both to pass validation and
|
|
248
|
+
to use the correctly typed data afterwards.
|
|
263
249
|
|
|
264
250
|
The Ajv default configuration in Fastify supports coercing array parameters in
|
|
265
251
|
`querystring`. Example:
|
|
@@ -294,11 +280,11 @@ curl -X GET "http://localhost:3000/?ids=1
|
|
|
294
280
|
{"params":{"ids":["1"]}}
|
|
295
281
|
```
|
|
296
282
|
|
|
297
|
-
|
|
283
|
+
A custom schema validator can be specified for each parameter type (body,
|
|
298
284
|
querystring, params, headers).
|
|
299
285
|
|
|
300
|
-
For example, the following code
|
|
301
|
-
parameters, changing the
|
|
286
|
+
For example, the following code disables type coercion only for the `body`
|
|
287
|
+
parameters, changing the Ajv default options:
|
|
302
288
|
|
|
303
289
|
```js
|
|
304
290
|
const schemaCompilers = {
|
|
@@ -336,16 +322,15 @@ server.setValidatorCompiler(req => {
|
|
|
336
322
|
})
|
|
337
323
|
```
|
|
338
324
|
|
|
339
|
-
For
|
|
325
|
+
For more information, see [Ajv Coercion](https://ajv.js.org/coercion.html).
|
|
340
326
|
|
|
341
327
|
#### Ajv Plugins
|
|
342
328
|
<a id="ajv-plugins"></a>
|
|
343
329
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
within Fastify**.
|
|
330
|
+
A list of plugins can be provided for use with the default `ajv` instance.
|
|
331
|
+
Ensure the plugin is **compatible with the Ajv version shipped within Fastify**.
|
|
347
332
|
|
|
348
|
-
> Refer to [`ajv options`](./Server.md#ajv) to check plugins format
|
|
333
|
+
> Refer to [`ajv options`](./Server.md#ajv) to check plugins format.
|
|
349
334
|
|
|
350
335
|
```js
|
|
351
336
|
const fastify = require('fastify')({
|
|
@@ -406,11 +391,10 @@ fastify.post('/foo', {
|
|
|
406
391
|
#### Validator Compiler
|
|
407
392
|
<a id="schema-validator"></a>
|
|
408
393
|
|
|
409
|
-
The `validatorCompiler` is a function that returns a function
|
|
410
|
-
body, URL
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
speed the validation up.
|
|
394
|
+
The `validatorCompiler` is a function that returns a function to validate the
|
|
395
|
+
body, URL parameters, headers, and query string. The default `validatorCompiler`
|
|
396
|
+
returns a function that implements the [ajv](https://ajv.js.org/) validation
|
|
397
|
+
interface. Fastify uses it internally to speed up validation.
|
|
414
398
|
|
|
415
399
|
Fastify's [baseline ajv
|
|
416
400
|
configuration](https://github.com/fastify/ajv-compiler#ajv-configuration) is:
|
|
@@ -428,11 +412,11 @@ configuration](https://github.com/fastify/ajv-compiler#ajv-configuration) is:
|
|
|
428
412
|
}
|
|
429
413
|
```
|
|
430
414
|
|
|
431
|
-
|
|
432
|
-
[`ajv.customOptions`](./Server.md#factory-ajv) to
|
|
415
|
+
Modify the baseline configuration by providing
|
|
416
|
+
[`ajv.customOptions`](./Server.md#factory-ajv) to the Fastify factory.
|
|
433
417
|
|
|
434
|
-
|
|
435
|
-
|
|
418
|
+
To change or set additional config options, create a custom instance and
|
|
419
|
+
override the existing one:
|
|
436
420
|
|
|
437
421
|
```js
|
|
438
422
|
const fastify = require('fastify')()
|
|
@@ -448,17 +432,16 @@ fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
|
|
|
448
432
|
return ajv.compile(schema)
|
|
449
433
|
})
|
|
450
434
|
```
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
validator
|
|
454
|
-
validator you are using._
|
|
435
|
+
> 🛈 Note: When using a custom validator instance, add schemas to the validator
|
|
436
|
+
> instead of Fastify. Fastify's `addSchema` method will not recognize the custom
|
|
437
|
+
> validator.
|
|
455
438
|
|
|
456
439
|
##### Using other validation libraries
|
|
457
440
|
<a id="using-other-validation-libraries"></a>
|
|
458
441
|
|
|
459
|
-
The `setValidatorCompiler` function
|
|
460
|
-
|
|
461
|
-
[yup](https://github.com/jquense/yup/),
|
|
442
|
+
The `setValidatorCompiler` function allows substituting `ajv` with other
|
|
443
|
+
JavaScript validation libraries like [joi](https://github.com/hapijs/joi/) or
|
|
444
|
+
[yup](https://github.com/jquense/yup/), or a custom one:
|
|
462
445
|
|
|
463
446
|
```js
|
|
464
447
|
const Joi = require('joi')
|
|
@@ -511,8 +494,8 @@ fastify.post('/the/url', {
|
|
|
511
494
|
|
|
512
495
|
##### .statusCode property
|
|
513
496
|
|
|
514
|
-
All validation errors
|
|
515
|
-
|
|
497
|
+
All validation errors have a `.statusCode` property set to `400`, ensuring the
|
|
498
|
+
default error handler sets the response status code to `400`.
|
|
516
499
|
|
|
517
500
|
```js
|
|
518
501
|
fastify.setErrorHandler(function (error, request, reply) {
|
|
@@ -525,30 +508,27 @@ fastify.setErrorHandler(function (error, request, reply) {
|
|
|
525
508
|
|
|
526
509
|
Fastify's validation error messages are tightly coupled to the default
|
|
527
510
|
validation engine: errors returned from `ajv` are eventually run through the
|
|
528
|
-
`schemaErrorFormatter` function which
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
511
|
+
`schemaErrorFormatter` function which builds human-friendly error messages.
|
|
512
|
+
However, the `schemaErrorFormatter` function is written with `ajv` in mind.
|
|
513
|
+
This may result in odd or incomplete error messages when using other validation
|
|
514
|
+
libraries.
|
|
532
515
|
|
|
533
|
-
To circumvent this issue,
|
|
516
|
+
To circumvent this issue, there are two main options:
|
|
534
517
|
|
|
535
|
-
1.
|
|
536
|
-
returns errors in the same structure and format as `ajv
|
|
537
|
-
|
|
538
|
-
engines)
|
|
539
|
-
2. or use a custom `errorHandler` to intercept and format your 'custom'
|
|
540
|
-
validation errors
|
|
518
|
+
1. Ensure the validation function (returned by the custom `schemaCompiler`)
|
|
519
|
+
returns errors in the same structure and format as `ajv`.
|
|
520
|
+
2. Use a custom `errorHandler` to intercept and format custom validation errors.
|
|
541
521
|
|
|
542
|
-
|
|
543
|
-
|
|
522
|
+
Fastify adds two properties to all validation errors to help write a custom
|
|
523
|
+
`errorHandler`:
|
|
544
524
|
|
|
545
525
|
* `validation`: the content of the `error` property of the object returned by
|
|
546
|
-
the validation function (returned by
|
|
547
|
-
* `validationContext`: the
|
|
526
|
+
the validation function (returned by the custom `schemaCompiler`)
|
|
527
|
+
* `validationContext`: the context (body, params, query, headers) where the
|
|
548
528
|
validation error occurred
|
|
549
529
|
|
|
550
|
-
A
|
|
551
|
-
|
|
530
|
+
A contrived example of such a custom `errorHandler` handling validation errors
|
|
531
|
+
is shown below:
|
|
552
532
|
|
|
553
533
|
```js
|
|
554
534
|
const errorHandler = (error, request, reply) => {
|
|
@@ -560,9 +540,9 @@ const errorHandler = (error, request, reply) => {
|
|
|
560
540
|
// check if we have a validation error
|
|
561
541
|
if (validation) {
|
|
562
542
|
response = {
|
|
563
|
-
// validationContext will be 'body'
|
|
543
|
+
// validationContext will be 'body', 'params', 'headers', or 'query'
|
|
564
544
|
message: `A validation error occurred when validating the ${validationContext}...`,
|
|
565
|
-
// this is the result of
|
|
545
|
+
// this is the result of the validation library...
|
|
566
546
|
errors: validation
|
|
567
547
|
}
|
|
568
548
|
} else {
|
|
@@ -581,12 +561,10 @@ const errorHandler = (error, request, reply) => {
|
|
|
581
561
|
### Serialization
|
|
582
562
|
<a id="serialization"></a>
|
|
583
563
|
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
you to use an output schema, as it can drastically increase throughput and help
|
|
589
|
-
prevent accidental disclosure of sensitive information.
|
|
564
|
+
Fastify uses [fast-json-stringify](https://www.npmjs.com/package/fast-json-stringify)
|
|
565
|
+
to send data as JSON if an output schema is provided in the route options. Using
|
|
566
|
+
an output schema can drastically increase throughput and help prevent accidental
|
|
567
|
+
disclosure of sensitive information.
|
|
590
568
|
|
|
591
569
|
Example:
|
|
592
570
|
```js
|
|
@@ -605,9 +583,8 @@ const schema = {
|
|
|
605
583
|
fastify.post('/the/url', { schema }, handler)
|
|
606
584
|
```
|
|
607
585
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
for example:
|
|
586
|
+
The response schema is based on the status code. To use the same schema for
|
|
587
|
+
multiple status codes, use `'2xx'` or `default`, for example:
|
|
611
588
|
```js
|
|
612
589
|
const schema = {
|
|
613
590
|
response: {
|
|
@@ -636,7 +613,7 @@ const schema = {
|
|
|
636
613
|
|
|
637
614
|
fastify.post('/the/url', { schema }, handler)
|
|
638
615
|
```
|
|
639
|
-
|
|
616
|
+
A specific response schema can be defined for different content types.
|
|
640
617
|
For example:
|
|
641
618
|
```js
|
|
642
619
|
const schema = {
|
|
@@ -688,10 +665,9 @@ fastify.post('/url', { schema }, handler)
|
|
|
688
665
|
#### Serializer Compiler
|
|
689
666
|
<a id="schema-serializer"></a>
|
|
690
667
|
|
|
691
|
-
The `serializerCompiler`
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
every route where you do.
|
|
668
|
+
The `serializerCompiler` returns a function that must return a string from an
|
|
669
|
+
input object. When defining a response JSON Schema, change the default
|
|
670
|
+
serialization method by providing a function to serialize each route.
|
|
695
671
|
|
|
696
672
|
```js
|
|
697
673
|
fastify.setSerializerCompiler(({ schema, method, url, httpStatus, contentType }) => {
|
|
@@ -716,13 +692,13 @@ fastify.get('/user', {
|
|
|
716
692
|
})
|
|
717
693
|
```
|
|
718
694
|
|
|
719
|
-
*
|
|
720
|
-
|
|
695
|
+
*To set a custom serializer in a specific part of the code, use
|
|
696
|
+
[`reply.serializer(...)`](./Reply.md#serializerfunc).*
|
|
721
697
|
|
|
722
698
|
### Error Handling
|
|
723
699
|
When schema validation fails for a request, Fastify will automatically return a
|
|
724
|
-
status 400 response including the result from the validator in the payload.
|
|
725
|
-
|
|
700
|
+
status 400 response including the result from the validator in the payload. For
|
|
701
|
+
example, if the following schema is used for a route:
|
|
726
702
|
|
|
727
703
|
```js
|
|
728
704
|
const schema = {
|
|
@@ -736,8 +712,8 @@ const schema = {
|
|
|
736
712
|
}
|
|
737
713
|
```
|
|
738
714
|
|
|
739
|
-
|
|
740
|
-
following payload
|
|
715
|
+
If the request fails to satisfy the schema, the route will return a response
|
|
716
|
+
with the following payload:
|
|
741
717
|
|
|
742
718
|
```js
|
|
743
719
|
{
|
|
@@ -747,10 +723,9 @@ following payload
|
|
|
747
723
|
}
|
|
748
724
|
```
|
|
749
725
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
`
|
|
753
|
-
the raw `validation` result as shown below
|
|
726
|
+
To handle errors inside the route, specify the `attachValidation` option. If
|
|
727
|
+
there is a validation error, the `validationError` property of the request will
|
|
728
|
+
contain the `Error` object with the raw validation result as shown below:
|
|
754
729
|
|
|
755
730
|
```js
|
|
756
731
|
const fastify = Fastify()
|
|
@@ -765,13 +740,13 @@ fastify.post('/', { schema, attachValidation: true }, function (req, reply) {
|
|
|
765
740
|
|
|
766
741
|
#### `schemaErrorFormatter`
|
|
767
742
|
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
743
|
+
To format errors, provide a sync function that returns an error as the
|
|
744
|
+
`schemaErrorFormatter` option when instantiating Fastify. The context function
|
|
745
|
+
will be the Fastify server instance.
|
|
771
746
|
|
|
772
747
|
`errors` is an array of Fastify schema errors `FastifySchemaValidationError`.
|
|
773
|
-
`dataVar` is the currently validated part of the schema
|
|
774
|
-
querystring
|
|
748
|
+
`dataVar` is the currently validated part of the schema (params, body,
|
|
749
|
+
querystring, headers).
|
|
775
750
|
|
|
776
751
|
```js
|
|
777
752
|
const fastify = Fastify({
|
|
@@ -789,8 +764,8 @@ fastify.setSchemaErrorFormatter(function (errors, dataVar) {
|
|
|
789
764
|
})
|
|
790
765
|
```
|
|
791
766
|
|
|
792
|
-
|
|
793
|
-
|
|
767
|
+
Use [setErrorHandler](./Server.md#seterrorhandler) to define a custom response
|
|
768
|
+
for validation errors such as:
|
|
794
769
|
|
|
795
770
|
```js
|
|
796
771
|
fastify.setErrorHandler(function (error, request, reply) {
|
|
@@ -800,25 +775,25 @@ fastify.setErrorHandler(function (error, request, reply) {
|
|
|
800
775
|
})
|
|
801
776
|
```
|
|
802
777
|
|
|
803
|
-
|
|
804
|
-
quickly, take a look at
|
|
778
|
+
For custom error responses in the schema, see
|
|
805
779
|
[`ajv-errors`](https://github.com/epoberezkin/ajv-errors). Check out the
|
|
806
780
|
[example](https://github.com/fastify/example/blob/HEAD/validation-messages/custom-errors-messages.js)
|
|
807
781
|
usage.
|
|
808
|
-
|
|
809
|
-
>
|
|
782
|
+
|
|
783
|
+
> Install version 1.0.1 of `ajv-errors`, as later versions are not compatible
|
|
784
|
+
> with AJV v6 (the version shipped by Fastify v3).
|
|
810
785
|
|
|
811
786
|
Below is an example showing how to add **custom error messages for each
|
|
812
787
|
property** of a schema by supplying custom AJV options. Inline comments in the
|
|
813
|
-
schema
|
|
814
|
-
|
|
788
|
+
schema describe how to configure it to show a different error message for each
|
|
789
|
+
case:
|
|
815
790
|
|
|
816
791
|
```js
|
|
817
792
|
const fastify = Fastify({
|
|
818
793
|
ajv: {
|
|
819
794
|
customOptions: {
|
|
820
795
|
jsonPointers: true,
|
|
821
|
-
// Warning: Enabling this option may lead to this security issue https://www.cvedetails.com/cve/CVE-2020-8192/
|
|
796
|
+
// ⚠ Warning: Enabling this option may lead to this security issue https://www.cvedetails.com/cve/CVE-2020-8192/
|
|
822
797
|
allErrors: true
|
|
823
798
|
},
|
|
824
799
|
plugins: [
|
|
@@ -862,8 +837,8 @@ fastify.post('/', { schema, }, (request, reply) => {
|
|
|
862
837
|
})
|
|
863
838
|
```
|
|
864
839
|
|
|
865
|
-
|
|
866
|
-
[ajv-i18n](https://github.com/epoberezkin/ajv-i18n)
|
|
840
|
+
To return localized error messages, see
|
|
841
|
+
[ajv-i18n](https://github.com/epoberezkin/ajv-i18n).
|
|
867
842
|
|
|
868
843
|
```js
|
|
869
844
|
const localize = require('ajv-i18n')
|
|
@@ -897,8 +872,8 @@ fastify.setErrorHandler(function (error, request, reply) {
|
|
|
897
872
|
|
|
898
873
|
### JSON Schema support
|
|
899
874
|
|
|
900
|
-
JSON Schema provides utilities to optimize
|
|
901
|
-
|
|
875
|
+
JSON Schema provides utilities to optimize schemas. Combined with Fastify's
|
|
876
|
+
shared schema, all schemas can be easily reused.
|
|
902
877
|
|
|
903
878
|
| Use Case | Validator | Serializer |
|
|
904
879
|
|-----------------------------------|-----------|------------|
|
|
@@ -1012,4 +987,4 @@ const refToSharedSchemaDefinitions = {
|
|
|
1012
987
|
- [Ajv i18n](https://github.com/epoberezkin/ajv-i18n)
|
|
1013
988
|
- [Ajv custom errors](https://github.com/epoberezkin/ajv-errors)
|
|
1014
989
|
- Custom error handling with core methods with error file dumping
|
|
1015
|
-
[example](https://github.com/fastify/example/tree/
|
|
990
|
+
[example](https://github.com/fastify/example/tree/main/validation-messages)
|