fastify 3.26.0 → 4.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/README.md +5 -4
  2. package/build/build-error-serializer.js +27 -0
  3. package/build/build-validation.js +49 -35
  4. package/docs/Guides/Ecosystem.md +2 -1
  5. package/docs/Guides/Prototype-Poisoning.md +3 -3
  6. package/docs/Migration-Guide-V4.md +12 -0
  7. package/docs/Reference/ContentTypeParser.md +8 -1
  8. package/docs/Reference/Errors.md +51 -6
  9. package/docs/Reference/Hooks.md +4 -7
  10. package/docs/Reference/LTS.md +5 -4
  11. package/docs/Reference/Reply.md +23 -22
  12. package/docs/Reference/Request.md +1 -3
  13. package/docs/Reference/Routes.md +17 -10
  14. package/docs/Reference/Server.md +98 -63
  15. package/docs/Reference/TypeScript.md +11 -13
  16. package/docs/Reference/Validation-and-Serialization.md +32 -54
  17. package/docs/Type-Providers.md +257 -0
  18. package/examples/hooks.js +1 -1
  19. package/examples/simple-stream.js +18 -0
  20. package/fastify.d.ts +36 -22
  21. package/fastify.js +72 -53
  22. package/lib/configValidator.js +902 -1023
  23. package/lib/contentTypeParser.js +6 -16
  24. package/lib/context.js +36 -10
  25. package/lib/decorate.js +5 -3
  26. package/lib/error-handler.js +158 -0
  27. package/lib/error-serializer.js +257 -0
  28. package/lib/errors.js +49 -10
  29. package/lib/fourOhFour.js +31 -20
  30. package/lib/handleRequest.js +10 -13
  31. package/lib/hooks.js +14 -9
  32. package/lib/noop-set.js +10 -0
  33. package/lib/pluginOverride.js +0 -3
  34. package/lib/pluginUtils.js +3 -2
  35. package/lib/reply.js +44 -163
  36. package/lib/request.js +13 -10
  37. package/lib/route.js +158 -139
  38. package/lib/schema-controller.js +3 -3
  39. package/lib/schemas.js +27 -1
  40. package/lib/server.js +219 -116
  41. package/lib/symbols.js +6 -4
  42. package/lib/validation.js +2 -1
  43. package/lib/warnings.js +2 -12
  44. package/lib/wrapThenable.js +4 -11
  45. package/package.json +40 -45
  46. package/test/404s.test.js +265 -108
  47. package/test/500s.test.js +2 -2
  48. package/test/async-await.test.js +15 -71
  49. package/test/close.test.js +39 -1
  50. package/test/content-parser.test.js +32 -0
  51. package/test/context-config.test.js +56 -4
  52. package/test/custom-http-server.test.js +14 -7
  53. package/test/custom-parser-async.test.js +0 -65
  54. package/test/custom-parser.test.js +54 -121
  55. package/test/decorator.test.js +1 -3
  56. package/test/delete.test.js +5 -5
  57. package/test/encapsulated-error-handler.test.js +50 -0
  58. package/test/esm/index.test.js +0 -14
  59. package/test/fastify-instance.test.js +4 -4
  60. package/test/fluent-schema.test.js +4 -4
  61. package/test/get.test.js +3 -3
  62. package/test/helper.js +18 -3
  63. package/test/hooks-async.test.js +14 -47
  64. package/test/hooks.on-ready.test.js +9 -4
  65. package/test/hooks.test.js +58 -99
  66. package/test/http2/closing.test.js +5 -11
  67. package/test/http2/unknown-http-method.test.js +3 -9
  68. package/test/https/custom-https-server.test.js +12 -6
  69. package/test/inject.test.js +1 -1
  70. package/test/input-validation.js +2 -2
  71. package/test/internals/all.test.js +2 -2
  72. package/test/internals/contentTypeParser.test.js +4 -4
  73. package/test/internals/handleRequest.test.js +9 -46
  74. package/test/internals/initialConfig.test.js +33 -12
  75. package/test/internals/logger.test.js +1 -1
  76. package/test/internals/reply.test.js +245 -3
  77. package/test/internals/request.test.js +13 -7
  78. package/test/internals/server.test.js +88 -0
  79. package/test/listen.test.js +84 -1
  80. package/test/logger.test.js +98 -58
  81. package/test/maxRequestsPerSocket.test.js +8 -6
  82. package/test/middleware.test.js +2 -25
  83. package/test/noop-set.test.js +19 -0
  84. package/test/nullable-validation.test.js +51 -14
  85. package/test/plugin.test.js +31 -5
  86. package/test/pretty-print.test.js +22 -10
  87. package/test/reply-error.test.js +123 -12
  88. package/test/request-error.test.js +2 -5
  89. package/test/route-hooks.test.js +17 -17
  90. package/test/route-prefix.test.js +2 -1
  91. package/test/route.test.js +216 -20
  92. package/test/router-options.test.js +1 -1
  93. package/test/schema-examples.test.js +11 -5
  94. package/test/schema-feature.test.js +24 -19
  95. package/test/schema-serialization.test.js +50 -9
  96. package/test/schema-special-usage.test.js +14 -81
  97. package/test/schema-validation.test.js +9 -9
  98. package/test/skip-reply-send.test.js +8 -8
  99. package/test/stream.test.js +23 -12
  100. package/test/throw.test.js +8 -5
  101. package/test/trust-proxy.test.js +1 -1
  102. package/test/type-provider.test.js +20 -0
  103. package/test/types/fastify.test-d.ts +12 -18
  104. package/test/types/hooks.test-d.ts +7 -3
  105. package/test/types/import.js +2 -0
  106. package/test/types/import.ts +1 -0
  107. package/test/types/instance.test-d.ts +61 -15
  108. package/test/types/logger.test-d.ts +44 -15
  109. package/test/types/route.test-d.ts +8 -2
  110. package/test/types/schema.test-d.ts +2 -39
  111. package/test/types/type-provider.test-d.ts +417 -0
  112. package/test/validation-error-handling.test.js +9 -9
  113. package/test/versioned-routes.test.js +29 -17
  114. package/test/wrapThenable.test.js +7 -6
  115. package/types/.eslintrc.json +1 -1
  116. package/types/content-type-parser.d.ts +17 -8
  117. package/types/hooks.d.ts +107 -60
  118. package/types/instance.d.ts +137 -105
  119. package/types/logger.d.ts +18 -104
  120. package/types/plugin.d.ts +10 -4
  121. package/types/register.d.ts +1 -1
  122. package/types/reply.d.ts +16 -11
  123. package/types/request.d.ts +10 -5
  124. package/types/route.d.ts +42 -31
  125. package/types/schema.d.ts +15 -1
  126. package/types/type-provider.d.ts +99 -0
  127. package/types/utils.d.ts +1 -1
  128. package/lib/schema-compilers.js +0 -12
  129. package/test/emit-warning.test.js +0 -166
@@ -13,6 +13,7 @@ describes the properties available in that options object.
13
13
  - [`https`](#https)
14
14
  - [`connectionTimeout`](#connectiontimeout)
15
15
  - [`keepAliveTimeout`](#keepalivetimeout)
16
+ - [`forceCloseConnections`](#forcecloseconnections)
16
17
  - [`maxRequestsPerSocket`](#maxrequestspersocket)
17
18
  - [`requestTimeout`](#requesttimeout)
18
19
  - [`ignoreTrailingSlash`](#ignoretrailingslash)
@@ -46,6 +47,7 @@ describes the properties available in that options object.
46
47
  - [after](#after)
47
48
  - [ready](#ready)
48
49
  - [listen](#listen)
50
+ - [addresses](#addresses)
49
51
  - [getDefaultRoute](#getdefaultroute)
50
52
  - [setDefaultRoute](#setdefaultroute)
51
53
  - [routing](#routing)
@@ -76,6 +78,9 @@ describes the properties available in that options object.
76
78
  - [printRoutes](#printroutes)
77
79
  - [printPlugins](#printplugins)
78
80
  - [addContentTypeParser](#addcontenttypeparser)
81
+ - [hasContentTypeParser](#hasContentTypeParser)
82
+ - [removeContentTypeParser](#removeContentTypeParser)
83
+ - [removeAllContentTypeParsers](#removeAllContentTypeParsers)
79
84
  - [getDefaultJsonParser](#getdefaultjsonparser)
80
85
  - [defaultTextParser](#defaulttextparser)
81
86
  - [errorHandler](#errorhandler)
@@ -122,7 +127,20 @@ property](https://nodejs.org/api/http.html#http_server_keepalivetimeout) to
122
127
  understand the effect of this option. This option only applies when HTTP/1 is in
123
128
  use. Also, when `serverFactory` option is specified, this option is ignored.
124
129
 
125
- + Default: `5000` (5 seconds)
130
+ + Default: `72000` (72 seconds)
131
+
132
+ ### `forceCloseConnections`
133
+ <a id="forcecloseconnections"></a>
134
+
135
+ When set to `true` requests with the header `connection: keep-alive` will be
136
+ tracked by the server. Upon [`close`](#close), the server will iterate the
137
+ current persistent connections and [destroy their
138
+ sockets](https://nodejs.org/dist/latest-v16.x/docs/api/net.html#socketdestroyerror).
139
+ This means the server will shutdown immediately instead of waiting for existing
140
+ persistent connections to timeout first. Important: connections are not
141
+ inspected to determine if requests have been completed.
142
+
143
+ + Default: `false`
126
144
 
127
145
  ### `maxRequestsPerSocket`
128
146
  <a id="factory-max-requests-per-socket"></a>
@@ -536,7 +554,7 @@ Automatically creates a sibling `HEAD` route for each `GET` route defined. If
536
554
  you want a custom `HEAD` handler without disabling this option, make sure to
537
555
  define it before the `GET` route.
538
556
 
539
- + Default: `false`
557
+ + Default: `true`
540
558
 
541
559
  ### `constraints`
542
560
  <a id="constraints"></a>
@@ -582,28 +600,14 @@ the incoming request as usual.
582
600
  ### `ajv`
583
601
  <a id="factory-ajv"></a>
584
602
 
585
- Configure the Ajv v6 instance used by Fastify without providing a custom one.
586
-
587
- + Default:
588
-
589
- ```js
590
- {
591
- customOptions: {
592
- removeAdditional: true,
593
- useDefaults: true,
594
- coerceTypes: true,
595
- allErrors: false,
596
- nullable: true
597
- },
598
- plugins: []
599
- }
600
- ```
603
+ Configure the Ajv v8 instance used by Fastify without providing a custom one.
604
+ The default configuration is explained in the [#schema-validator](Validation-and-Serialization.md#schema-validator) section.
601
605
 
602
606
  ```js
603
607
  const fastify = require('fastify')({
604
608
  ajv: {
605
609
  customOptions: {
606
- nullable: false // Refer to [ajv options](https://github.com/ajv-validator/ajv/tree/v6#options)
610
+ removeAdditional: 'all' // Refer to [ajv options](https://ajv.js.org/#options)
607
611
  },
608
612
  plugins: [
609
613
  require('ajv-merge-patch'),
@@ -636,7 +640,7 @@ const fastify = require('fastify')({
636
640
  Set a default
637
641
  [timeout](https://nodejs.org/api/http2.html#http2_http2session_settimeout_msecs_callback)
638
642
  to every incoming HTTP/2 session. The session will be closed on the timeout.
639
- Default: `5000` ms.
643
+ Default: `72000` ms.
640
644
 
641
645
  Note that this is needed to offer the graceful "close" experience when using
642
646
  HTTP/2. The low default has been chosen to mitigate denial of service attacks.
@@ -817,14 +821,25 @@ fastify.ready().then(() => {
817
821
  <a id="listen"></a>
818
822
 
819
823
  Starts the server on the given port after all the plugins are loaded, internally
820
- waits for the `.ready()` event. The callback is the same as the Node core. By
821
- default, the server will listen on the address resolved by `localhost` when no
822
- specific address is provided (`127.0.0.1` or `::1` depending on the operating
823
- system). If listening on any available interface is desired, then specifying
824
- `0.0.0.0` for the address will listen on all IPv4 addresses. Using `::` for the
825
- address will listen on all IPv6 addresses and, depending on OS, may also listen
826
- on all IPv4 addresses. Be careful when deciding to listen on all interfaces; it
827
- comes with inherent [security
824
+ waits for the `.ready()` event. The callback is the same as the Node core.
825
+
826
+ By default, the server will listen on the address(es) resolved by `localhost` when no
827
+ specific address is provided. If listening on any available interface is desired,
828
+ then specifying `0.0.0.0` for the address will listen on all IPv4 addresses.
829
+
830
+ Host | IPv4 | IPv6
831
+ --------------|------|-------
832
+ `::` | ✅<sup>*</sup> | ✅
833
+ `::` + [`ipv6Only`](https://nodejs.org/api/net.html#serverlistenoptions-callback) | 🚫 | ✅
834
+ `0.0.0.0` | ✅ | 🚫
835
+ `localhost` | ✅ | ✅
836
+ `127.0.0.1` | ✅ | 🚫
837
+ `::1` | 🚫 | ✅
838
+
839
+ <sup>*</sup> Using `::` for the address will listen on all IPv6 addresses and, depending on OS,
840
+ may also listen on [all IPv4 addresses](https://nodejs.org/api/net.html#serverlistenport-host-backlog-callback).
841
+
842
+ Be careful when deciding to listen on all interfaces; it comes with inherent [security
828
843
  risks](https://web.archive.org/web/20170831174611/https://snyk.io/blog/mongodb-hack-and-secure-defaults/).
829
844
 
830
845
  ```js
@@ -933,6 +948,24 @@ fastify.listen({
933
948
  }, (err) => {})
934
949
  ```
935
950
 
951
+ #### addresses
952
+ <a id="addresses"></a>
953
+
954
+ This method returns an array of addresses that the server is listening on.
955
+ If you call it before `listen()` is called or after the `close()` function,
956
+ it will return an empty array.
957
+
958
+ ```js
959
+ await fastify.listen(8080)
960
+ const addresses = fastify.addresses()
961
+ // [
962
+ // { port: 8080, family: 'IPv6', address: '::1' },
963
+ // { port: 8080, family: 'IPv4', address: '127.0.0.1' }
964
+ // ]
965
+ ```
966
+
967
+ Note that the array contains the `fastify.server.address()` too.
968
+
936
969
  #### getDefaultRoute
937
970
  <a id="getDefaultRoute"></a>
938
971
 
@@ -1171,8 +1204,10 @@ unknown to Fastify. See [issue
1171
1204
  #2446](https://github.com/fastify/fastify/issues/2446) for an example of what
1172
1205
  this property helps to resolve.
1173
1206
 
1174
- Another use case is to tweak all the schemas processing. Doing so it is possible
1175
- to use Ajv v8, instead of the default v6! We will see an example of this later.
1207
+ Another use case is to tweak all the schemas processing.
1208
+ Doing so it is possible to use Ajv v8 JTD or Standalone feature. To use such
1209
+ as JTD or the Standalone mode, refers to the
1210
+ [`@fastify/ajv-compiler` documentation](https://github.com/fastify/ajv-compiler#usage).
1176
1211
 
1177
1212
  ```js
1178
1213
  const fastify = Fastify({
@@ -1247,39 +1282,6 @@ const fastify = Fastify({
1247
1282
  });
1248
1283
  ```
1249
1284
 
1250
- ##### Ajv 8 as default schema validator
1251
-
1252
- Ajv 8 is the evolution of Ajv 6, and it has a lot of improvements and new
1253
- features. To use the new Ajv 8 features such as JTD or the Standalone mode,
1254
- refer to the [`@fastify/ajv-compiler`
1255
- documentation](https://github.com/fastify/ajv-compiler#usage).
1256
-
1257
- To use Ajv 8 as default schema validator, you can use the following code:
1258
-
1259
- ```js
1260
- const AjvCompiler = require('@fastify/ajv-compiler') // It must be the v2.x.x version
1261
-
1262
- // Note that the `format` schema's keyword is no longer supported on Ajv 8 by default.
1263
- // So you need to add it manually.
1264
- const ajvFormats = require('ajv-formats')
1265
-
1266
- const app = fastify({
1267
- ajv: {
1268
- customOptions: {
1269
- validateFormats: true
1270
- },
1271
- plugins: [ajvFormats]
1272
- },
1273
- schemaController: {
1274
- compilersFactory: {
1275
- buildValidator: AjvCompiler()
1276
- }
1277
- }
1278
- })
1279
-
1280
- // Done! You can now use Ajv 8 options and keywords in your schemas!
1281
- ```
1282
-
1283
1285
  #### setNotFoundHandler
1284
1286
  <a id="set-not-found-handler"></a>
1285
1287
 
@@ -1465,6 +1467,39 @@ content types, e.g. `text/json, application/vnd.oasis.opendocument.text`.
1465
1467
  fastify.addContentTypeParser('text/json', { asString: true }, fastify.getDefaultJsonParser('ignore', 'ignore'))
1466
1468
  ```
1467
1469
 
1470
+ #### hasContentTypeParser
1471
+ <a id="hasContentTypeParser"></a>
1472
+
1473
+ `fastify.hasContentTypeParser(contentType)` is used to check whether there is a content type parser in the current
1474
+ context for the specified content type.
1475
+
1476
+ ```js
1477
+ fastify.hasContentTypeParser('text/json')
1478
+
1479
+ fastify.hasContentTypeParser(/^.+\/json$/)
1480
+ ```
1481
+
1482
+ #### removeContentTypeParser
1483
+ <a id="removeContentTypeParser"></a>
1484
+
1485
+ `fastify.removeContentTypeParser(contentType)` is used to remove content type parsers in the current context. This
1486
+ method allows for example to remove the both built-in parsers for `application/json` and `text/plain`.
1487
+
1488
+ ```js
1489
+ fastify.removeContentTypeParser('application/json')
1490
+
1491
+ fastify.removeContentTypeParser(['application/json', 'text/plain'])
1492
+ ```
1493
+
1494
+ #### removeAllContentTypeParsers
1495
+ <a id="removeAllContentTypeParsers"></a>
1496
+
1497
+ The `fastify.removeAllContentTypeParsers()` method allows all content type parsers in the current context to be removed.
1498
+ A use case of this method is the implementation of catch-all content type parser. Before adding this parser with
1499
+ `fastify.addContentTypeParser()` one could call the `removeAllContentTypeParsers` method.
1500
+
1501
+ For more details about the usage of the different content type parser APIs see [here](./ContentTypeParser.md#usage).
1502
+
1468
1503
  #### getDefaultJsonParser
1469
1504
  <a id="getDefaultJsonParser"></a>
1470
1505
 
@@ -399,7 +399,7 @@ const todo = {
399
399
  done: { type: 'boolean' },
400
400
  },
401
401
  required: ['name'],
402
- } as const;
402
+ } as const; // don't forget to use const !
403
403
  ```
404
404
 
405
405
  With the provided type `FromSchema` you can build a type from your schema and
@@ -487,6 +487,7 @@ Fastify Plugin in a TypeScript Project.
487
487
  import fp from 'fastify-plugin'
488
488
 
489
489
  // using declaration merging, add your plugin props to the appropriate fastify interfaces
490
+ // if prop type is defined here, the value will be typechecked when you call decorate{,Request,Reply}
490
491
  declare module 'fastify' {
491
492
  interface FastifyRequest {
492
493
  myPluginProp: string
@@ -877,26 +878,23 @@ server.get('/', async (request, reply) => {
877
878
 
878
879
  ###### Example 5: Specifying logger types
879
880
 
880
- Fastify uses [Pino](https://getpino.io/#/) logging library under the hood. Some
881
- of it's properties can be configured via `logger` field when constructing
882
- Fastify's instance. If properties you need aren't exposed, it's also possible to
883
- pass a preconfigured external instance of Pino (or any other compatible logger)
884
- to Fastify via the same field. This allows creating custom serializers as well,
885
- see the [Logging](./Logging.md) documentation for more info.
886
-
887
- To use an external instance of Pino, add `@types/pino` to devDependencies and
888
- pass the instance to `logger` field:
881
+ Fastify uses [Pino](https://getpino.io/#/) logging library under the hood. Since
882
+ `pino@7`, all of it's properties can be configured via `logger` field when
883
+ constructing Fastify's instance. If properties you need aren't exposed, please
884
+ open an Issue to [`Pino`](https://github.com/pinojs/pino/issues) or pass a
885
+ preconfigured external instance of Pino (or any other compatible logger) as
886
+ temporary fix to Fastify via the same field. This allows creating custom
887
+ serializers as well, see the [Logging](Logging.md) documentation for more info.
889
888
 
890
889
  ```typescript
891
890
  import fastify from 'fastify'
892
- import pino from 'pino'
893
891
 
894
892
  const server = fastify({
895
- logger: pino({
893
+ logger: {
896
894
  level: 'info',
897
895
  redact: ['x-userinfo'],
898
896
  messageKey: 'message'
899
- })
897
+ }
900
898
  })
901
899
 
902
900
  server.get('/', async (request, reply) => {
@@ -4,7 +4,12 @@
4
4
  Fastify uses a schema-based approach, and even if it is not mandatory we
5
5
  recommend using [JSON Schema](https://json-schema.org/) to validate your routes
6
6
  and serialize your outputs. Internally, Fastify compiles the schema into a
7
- highly performant function.
7
+ highly performant function.
8
+
9
+ Validation will only be attempted if the content type is `application-json`,
10
+ as described in the documentation for the [content type parser](./ContentTypeParser.md).
11
+
12
+ All the examples in this section are using the [JSON Schema Draft 7](https://json-schema.org/specification-links.html#draft-7) specification.
8
13
 
9
14
  > ## ⚠ Security Notice
10
15
  > Treat the schema definition as application code. Validation and serialization
@@ -23,8 +28,7 @@ highly performant function.
23
28
  ### Core concepts
24
29
  The validation and the serialization tasks are processed by two different, and
25
30
  customizable, actors:
26
- - [Ajv v6](https://www.npmjs.com/package/ajv/v/6.12.6) for the validation of a
27
- request
31
+ - [Ajv v8](https://www.npmjs.com/package/ajv) for the validation of a request
28
32
  - [fast-json-stringify](https://www.npmjs.com/package/fast-json-stringify) for
29
33
  the serialization of a response's body
30
34
 
@@ -143,10 +147,11 @@ fastify.register((instance, opts, done) => {
143
147
 
144
148
 
145
149
  ### Validation
146
- The route validation internally relies upon [Ajv
147
- v6](https://www.npmjs.com/package/ajv/v/6.12.6) which is a high-performance JSON
148
- Schema validator. Validating the input is very easy: just add the fields that
149
- you need inside the route schema, and you are done!
150
+ The route validation internally relies upon
151
+ [Ajv v8](https://www.npmjs.com/package/ajv) which is a high-performance
152
+ JSON Schema validator.
153
+ Validating the input is very easy: just add the fields that you need
154
+ inside the route schema, and you are done!
150
155
 
151
156
  The supported validations are:
152
157
  - `body`: validates the body of the request if it is a POST, PUT, or PATCH
@@ -229,15 +234,13 @@ const schema = {
229
234
  fastify.post('/the/url', { schema }, handler)
230
235
  ```
231
236
 
232
- *Note that Ajv will try to
233
- [coerce](https://github.com/epoberezkin/ajv#coercing-data-types) the values to
237
+ *Note that Ajv will try to [coerce](https://ajv.js.org/coercion.html) the values to
234
238
  the types specified in your schema `type` keywords, both to pass the validation
235
239
  and to use the correctly typed data afterwards.*
236
240
 
237
- The Ajv default configuration in Fastify doesn't support coercing array
238
- parameters in querystring. However, Fastify allows
239
- [`customOptions`](./Server.md#ajv) in Ajv instance. The `coerceTypes: 'array'`
240
- will coerce one parameter to a single element in array. Example:
241
+ The Ajv default configuration in Fastify supports coercing array
242
+ parameters in `querystring`.
243
+ Example:
241
244
 
242
245
  ```js
243
246
  const opts = {
@@ -255,7 +258,7 @@ const opts = {
255
258
  }
256
259
 
257
260
  fastify.get('/', opts, (request, reply) => {
258
- reply.send({ params: request.query })
261
+ reply.send({ params: request.query }) // echo the querystring
259
262
  })
260
263
 
261
264
  fastify.listen(3000, (err) => {
@@ -263,29 +266,6 @@ fastify.listen(3000, (err) => {
263
266
  })
264
267
  ```
265
268
 
266
- Using Fastify defaults the following request will result in `400` status code:
267
-
268
- ```sh
269
- curl -X GET "http://localhost:3000/?ids=1
270
-
271
- {"statusCode":400,"error":"Bad Request","message":"querystring/hello should be array"}
272
- ```
273
-
274
- Using `coerceTypes` as 'array' will fix it:
275
-
276
- ```js
277
- const ajv = new Ajv({
278
- removeAdditional: true,
279
- useDefaults: true,
280
- coerceTypes: 'array', // This line
281
- allErrors: true
282
- })
283
-
284
- fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
285
- return ajv.compile(schema)
286
- })
287
- ```
288
-
289
269
  ```sh
290
270
  curl -X GET "http://localhost:3000/?ids=1
291
271
 
@@ -339,8 +319,8 @@ For further information see [here](https://ajv.js.org/coercion.html)
339
319
  #### Ajv Plugins
340
320
  <a id="ajv-plugins"></a>
341
321
 
342
- You can provide a list of plugins you want to use with the default `ajv`
343
- instance. Note that the plugin must be **compatible with Ajv v6**.
322
+ You can provide a list of plugins you want to use with the default `ajv` instance.
323
+ Note that the plugin must be **compatible with the Ajv version shipped within Fastify**.
344
324
 
345
325
  > Refer to [`ajv options`](./Server.md#ajv) to check plugins format
346
326
 
@@ -409,16 +389,16 @@ body, URL parameters, headers, and query string. The default
409
389
  [ajv](https://ajv.js.org/) validation interface. Fastify uses it internally to
410
390
  speed the validation up.
411
391
 
412
- Fastify's [baseline ajv
413
- configuration](https://github.com/epoberezkin/ajv#options-to-modify-validated-data)
414
- is:
392
+ Fastify's [baseline ajv configuration](https://github.com/fastify/ajv-compiler#ajv-configuration) is:
415
393
 
416
394
  ```js
417
395
  {
418
- removeAdditional: true, // remove additional properties
419
- useDefaults: true, // replace missing properties and items with the values from corresponding default keyword
420
396
  coerceTypes: true, // change data type of data to match type keyword
421
- nullable: true // support keyword "nullable" from Open API 3 specification.
397
+ useDefaults: true, // replace missing properties and items with the values from corresponding default keyword
398
+ removeAdditional: true, // remove additional properties
399
+ // Explicitly set allErrors to `false`.
400
+ // When set to `true`, a DoS attack is possible.
401
+ allErrors: false
422
402
  }
423
403
  ```
424
404
 
@@ -432,11 +412,9 @@ your own instance and override the existing one like:
432
412
  const fastify = require('fastify')()
433
413
  const Ajv = require('ajv')
434
414
  const ajv = new Ajv({
435
- // the fastify defaults (if needed)
436
- removeAdditional: true,
415
+ removeAdditional: 'all',
437
416
  useDefaults: true,
438
- coerceTypes: true,
439
- nullable: true,
417
+ coerceTypes: 'array',
440
418
  // any other options
441
419
  // ...
442
420
  })
@@ -457,7 +435,7 @@ almost any Javascript validation library ([joi](https://github.com/hapijs/joi/),
457
435
  [yup](https://github.com/jquense/yup/), ...) or a custom one:
458
436
 
459
437
  ```js
460
- const Joi = require('@hapi/joi')
438
+ const Joi = require('joi')
461
439
 
462
440
  fastify.post('/the/url', {
463
441
  schema: {
@@ -509,8 +487,8 @@ fastify.post('/the/url', {
509
487
 
510
488
  Fastify's validation error messages are tightly coupled to the default
511
489
  validation engine: errors returned from `ajv` are eventually run through the
512
- `schemaErrorsText` function which is responsible for building human-friendly
513
- error messages. However, the `schemaErrorsText` function is written with `ajv`
490
+ `schemaErrorFormatter` function which is responsible for building human-friendly
491
+ error messages. However, the `schemaErrorFormatter` function is written with `ajv`
514
492
  in mind : as a result, you may run into odd or incomplete error messages when
515
493
  using other validation libraries.
516
494
 
@@ -526,9 +504,9 @@ To circumvent this issue, you have 2 main options :
526
504
  To help you in writing a custom `errorHandler`, Fastify adds 2 properties to all
527
505
  validation errors:
528
506
 
529
- * validation: the content of the `error` property of the object returned by the
507
+ * `validation`: the content of the `error` property of the object returned by the
530
508
  validation function (returned by your custom `schemaCompiler`)
531
- * validationContext: the 'context' (body, params, query, headers) where the
509
+ * `validationContext`: the 'context' (body, params, query, headers) where the
532
510
  validation error occurred
533
511
 
534
512
  A very contrived example of such a custom `errorHandler` handling validation