fastify 3.24.0 → 3.25.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.
Files changed (67) hide show
  1. package/README.md +30 -29
  2. package/docs/{Benchmarking.md → Guides/Benchmarking.md} +14 -5
  3. package/docs/Guides/Ecosystem.md +513 -0
  4. package/docs/{Fluent-Schema.md → Guides/Fluent-Schema.md} +16 -7
  5. package/docs/{Getting-Started.md → Guides/Getting-Started.md} +180 -60
  6. package/docs/Guides/Index.md +30 -4
  7. package/docs/{Migration-Guide-V3.md → Guides/Migration-Guide-V3.md} +43 -37
  8. package/docs/{Plugins-Guide.md → Guides/Plugins-Guide.md} +196 -82
  9. package/docs/{Recommendations.md → Guides/Recommendations.md} +17 -10
  10. package/docs/{Serverless.md → Guides/Serverless.md} +200 -42
  11. package/docs/Guides/Style-Guide.md +246 -0
  12. package/docs/{Testing.md → Guides/Testing.md} +26 -12
  13. package/docs/Guides/Write-Plugin.md +102 -0
  14. package/docs/{ContentTypeParser.md → Reference/ContentTypeParser.md} +68 -30
  15. package/docs/{Decorators.md → Reference/Decorators.md} +52 -47
  16. package/docs/{Encapsulation.md → Reference/Encapsulation.md} +3 -3
  17. package/docs/{Errors.md → Reference/Errors.md} +77 -47
  18. package/docs/{HTTP2.md → Reference/HTTP2.md} +13 -13
  19. package/docs/{Hooks.md → Reference/Hooks.md} +157 -70
  20. package/docs/Reference/Index.md +71 -0
  21. package/docs/{LTS.md → Reference/LTS.md} +31 -32
  22. package/docs/{Lifecycle.md → Reference/Lifecycle.md} +15 -7
  23. package/docs/{Logging.md → Reference/Logging.md} +68 -28
  24. package/docs/Reference/Middleware.md +78 -0
  25. package/docs/{Plugins.md → Reference/Plugins.md} +91 -34
  26. package/docs/{Reply.md → Reference/Reply.md} +205 -94
  27. package/docs/{Request.md → Reference/Request.md} +32 -16
  28. package/docs/{Routes.md → Reference/Routes.md} +243 -113
  29. package/docs/{Server.md → Reference/Server.md} +516 -267
  30. package/docs/{TypeScript.md → Reference/TypeScript.md} +451 -191
  31. package/docs/{Validation-and-Serialization.md → Reference/Validation-and-Serialization.md} +178 -86
  32. package/docs/index.md +24 -0
  33. package/examples/typescript-server.ts +1 -1
  34. package/fastify.js +2 -3
  35. package/lib/contentTypeParser.js +11 -6
  36. package/lib/decorate.js +6 -3
  37. package/lib/logger.js +1 -1
  38. package/lib/route.js +1 -1
  39. package/lib/server.js +9 -8
  40. package/package.json +9 -4
  41. package/test/als.test.js +74 -0
  42. package/test/constrained-routes.test.js +220 -0
  43. package/test/custom-parser.test.js +11 -2
  44. package/test/decorator.test.js +38 -0
  45. package/test/handler-context.test.js +11 -4
  46. package/test/http2/closing.test.js +14 -5
  47. package/test/http2/constraint.test.js +91 -0
  48. package/test/listen.test.js +36 -22
  49. package/test/logger.test.js +16 -0
  50. package/test/maxRequestsPerSocket.test.js +10 -0
  51. package/test/request-error.test.js +2 -8
  52. package/test/requestTimeout.test.js +4 -1
  53. package/test/router-options.test.js +10 -1
  54. package/test/schema-feature.test.js +146 -0
  55. package/test/stream.test.js +14 -3
  56. package/test/trust-proxy.test.js +15 -7
  57. package/test/types/instance.test-d.ts +52 -1
  58. package/test/types/request.test-d.ts +7 -1
  59. package/test/types/route.test-d.ts +21 -0
  60. package/types/hooks.d.ts +12 -1
  61. package/types/instance.d.ts +16 -6
  62. package/types/request.d.ts +4 -1
  63. package/types/route.d.ts +1 -1
  64. package/docs/Ecosystem.md +0 -211
  65. package/docs/Middleware.md +0 -53
  66. package/docs/Style-Guide.md +0 -185
  67. package/docs/Write-Plugin.md +0 -58
@@ -1,41 +1,59 @@
1
1
  <h1 align="center">Fastify</h1>
2
2
 
3
3
  ## Validation and Serialization
4
- Fastify uses a schema-based approach, and even if it is not mandatory we recommend using [JSON Schema](https://json-schema.org/) to validate your routes and serialize your outputs. Internally, Fastify compiles the schema into a highly performant function.
4
+ Fastify uses a schema-based approach, and even if it is not mandatory we
5
+ recommend using [JSON Schema](https://json-schema.org/) to validate your routes
6
+ and serialize your outputs. Internally, Fastify compiles the schema into a
7
+ highly performant function.
5
8
 
6
9
  > ## ⚠ Security Notice
7
- > Treat the schema definition as application code.
8
- > Validation and serialization features dynamically evaluate
9
- > code with `new Function()`, which is not safe to use with
10
- > user-provided schemas. See [Ajv](https://npm.im/ajv) and
11
- > [fast-json-stringify](https://npm.im/fast-json-stringify) for more
12
- > details.
13
- >
14
- > Moreover, the [`$async` Ajv feature](https://ajv.js.org/guide/async-validation.html) should not be used as part of the first validation strategy.
15
- > This option is used to access Databases and reading them during the validation process may lead to Denial of Service Attacks to your
16
- > application. If you need to run `async` tasks, use [Fastify's hooks](./Hooks.md) instead after validation completes, such as `preHandler`.
10
+ > Treat the schema definition as application code. Validation and serialization
11
+ > features dynamically evaluate code with `new Function()`, which is not safe to
12
+ > use with user-provided schemas. See [Ajv](https://npm.im/ajv) and
13
+ > [fast-json-stringify](https://npm.im/fast-json-stringify) for more details.
14
+ >
15
+ > Moreover, the [`$async` Ajv
16
+ > feature](https://ajv.js.org/guide/async-validation.html) should not be used as
17
+ > part of the first validation strategy. This option is used to access Databases
18
+ > and reading them during the validation process may lead to Denial of Service
19
+ > Attacks to your application. If you need to run `async` tasks, use [Fastify's
20
+ > hooks](./Hooks.md) instead after validation completes, such as `preHandler`.
17
21
 
18
22
 
19
23
  ### Core concepts
20
- The validation and the serialization tasks are processed by two different, and customizable, actors:
21
- - [Ajv v6](https://www.npmjs.com/package/ajv/v/6.12.6) for the validation of a request
22
- - [fast-json-stringify](https://www.npmjs.com/package/fast-json-stringify) for the serialization of a response's body
24
+ The validation and the serialization tasks are processed by two different, and
25
+ customizable, actors:
26
+ - [Ajv v6](https://www.npmjs.com/package/ajv/v/6.12.6) for the validation of a
27
+ request
28
+ - [fast-json-stringify](https://www.npmjs.com/package/fast-json-stringify) for
29
+ the serialization of a response's body
23
30
 
24
- These two separate entities share only the JSON schemas added to Fastify's instance through `.addSchema(schema)`.
31
+ These two separate entities share only the JSON schemas added to Fastify's
32
+ instance through `.addSchema(schema)`.
25
33
 
26
- <a name="shared-schema"></a>
27
34
  #### Adding a shared schema
28
- Thanks to the `addSchema` API, you can add multiple schemas to the Fastify instance and then reuse them in multiple parts of your application.
29
- As usual, this API is encapsulated.
30
-
31
- The shared schemas can be reused through the JSON Schema [**`$ref`**](https://tools.ietf.org/html/draft-handrews-json-schema-01#section-8) keyword.
32
- Here an overview of _how_ references work:
33
-
34
- + `myField: { $ref: '#foo'}` will search for field with `$id: '#foo'` inside the current schema
35
- + `myField: { $ref: '#/definitions/foo'}` will search for field `definitions.foo` inside the current schema
36
- + `myField: { $ref: 'http://url.com/sh.json#'}` will search for a shared schema added with `$id: 'http://url.com/sh.json'`
37
- + `myField: { $ref: 'http://url.com/sh.json#/definitions/foo'}` will search for a shared schema added with `$id: 'http://url.com/sh.json'` and will use the field `definitions.foo`
38
- + `myField: { $ref: 'http://url.com/sh.json#foo'}` will search for a shared schema added with `$id: 'http://url.com/sh.json'` and it will look inside of it for object with `$id: '#foo'`
35
+ <a id="shared-schema"></a>
36
+
37
+ Thanks to the `addSchema` API, you can add multiple schemas to the Fastify
38
+ instance and then reuse them in multiple parts of your application. As usual,
39
+ this API is encapsulated.
40
+
41
+ The shared schemas can be reused through the JSON Schema
42
+ [**`$ref`**](https://tools.ietf.org/html/draft-handrews-json-schema-01#section-8)
43
+ keyword. Here an overview of _how_ references work:
44
+
45
+ + `myField: { $ref: '#foo'}` will search for field with `$id: '#foo'` inside the
46
+ current schema
47
+ + `myField: { $ref: '#/definitions/foo'}` will search for field
48
+ `definitions.foo` inside the current schema
49
+ + `myField: { $ref: 'http://url.com/sh.json#'}` will search for a shared schema
50
+ added with `$id: 'http://url.com/sh.json'`
51
+ + `myField: { $ref: 'http://url.com/sh.json#/definitions/foo'}` will search for
52
+ a shared schema added with `$id: 'http://url.com/sh.json'` and will use the
53
+ field `definitions.foo`
54
+ + `myField: { $ref: 'http://url.com/sh.json#foo'}` will search for a shared
55
+ schema added with `$id: 'http://url.com/sh.json'` and it will look inside of
56
+ it for object with `$id: '#foo'`
39
57
 
40
58
 
41
59
  **Simple usage:**
@@ -80,12 +98,12 @@ fastify.post('/', {
80
98
  })
81
99
  ```
82
100
 
83
- <a name="get-shared-schema"></a>
84
101
  #### Retrieving the shared schemas
102
+ <a id="get-shared-schema"></a>
85
103
 
86
- If the validator and the serializer are customized, the `.addSchema` method will not be useful since the actors are no longer
87
- controlled by Fastify.
88
- To access the schemas added to the Fastify instance, you can simply use `.getSchemas()`:
104
+ If the validator and the serializer are customized, the `.addSchema` method will
105
+ not be useful since the actors are no longer controlled by Fastify. To access
106
+ the schemas added to the Fastify instance, you can simply use `.getSchemas()`:
89
107
 
90
108
  ```js
91
109
  fastify.addSchema({
@@ -100,7 +118,8 @@ const mySchemas = fastify.getSchemas()
100
118
  const mySchema = fastify.getSchema('schemaId')
101
119
  ```
102
120
 
103
- As usual, the function `getSchemas` is encapsulated and returns the shared schemas available in the selected scope:
121
+ As usual, the function `getSchemas` is encapsulated and returns the shared
122
+ schemas available in the selected scope:
104
123
 
105
124
  ```js
106
125
  fastify.addSchema({ $id: 'one', my: 'hello' })
@@ -124,18 +143,26 @@ fastify.register((instance, opts, done) => {
124
143
 
125
144
 
126
145
  ### Validation
127
- The route validation internally relies upon [Ajv v6](https://www.npmjs.com/package/ajv/v/6.12.6) which is a high-performance JSON Schema validator.
128
- Validating the input is very easy: just add the fields that you need inside the route schema, and you are done!
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!
129
150
 
130
151
  The supported validations are:
131
- - `body`: validates the body of the request if it is a POST, PUT, or PATCH method.
152
+ - `body`: validates the body of the request if it is a POST, PUT, or PATCH
153
+ method.
132
154
  - `querystring` or `query`: validates the query string.
133
155
  - `params`: validates the route params.
134
156
  - `headers`: validates the request headers.
135
157
 
136
- All the validations can be a complete JSON Schema object (with a `type` property of `'object'` and a `'properties'` object containing parameters) or a simpler variation in which the `type` and `properties` attributes are forgone and the parameters are listed at the top level (see the example below).
158
+ All the validations can be a complete JSON Schema object (with a `type` property
159
+ of `'object'` and a `'properties'` object containing parameters) or a simpler
160
+ variation in which the `type` and `properties` attributes are forgone and the
161
+ parameters are listed at the top level (see the example below).
137
162
 
138
- > ℹ If you need to use the lastest version of Ajv (v8) you should read how to do it in the [`schemaController`](Server.md#schema-controller) section. It is explained the easier way to avoid to implement a custom validator.
163
+ > ℹ If you need to use the lastest version of Ajv (v8) you should read how to do
164
+ > it in the [`schemaController`](./Server.md#schema-controller) section. It is
165
+ > explained the easier way to avoid to implement a custom validator.
139
166
 
140
167
  Example:
141
168
  ```js
@@ -202,9 +229,15 @@ const schema = {
202
229
  fastify.post('/the/url', { schema }, handler)
203
230
  ```
204
231
 
205
- *Note that Ajv will try to [coerce](https://github.com/epoberezkin/ajv#coercing-data-types) the values to the types specified in your schema `type` keywords, both to pass the validation and to use the correctly typed data afterwards.*
232
+ *Note that Ajv will try to
233
+ [coerce](https://github.com/epoberezkin/ajv#coercing-data-types) the values to
234
+ the types specified in your schema `type` keywords, both to pass the validation
235
+ and to use the correctly typed data afterwards.*
206
236
 
207
- The Ajv default configuration in Fastify doesn't support coercing array parameters in querystring. However, Fastify allows [`customOptions`](Server.md#ajv) in Ajv instance. The `coerceTypes: 'array'` will coerce one parameter to a single element in array. Example:
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:
208
241
 
209
242
  ```js
210
243
  const opts = {
@@ -259,9 +292,11 @@ curl -X GET "http://localhost:3000/?ids=1
259
292
  {"params":{"hello":["1"]}}
260
293
  ```
261
294
 
262
- You can also specify a custom schema validator for each parameter type (body, querystring, params, headers).
295
+ You can also specify a custom schema validator for each parameter type (body,
296
+ querystring, params, headers).
263
297
 
264
- For example, the following code disable type coercion only for the `body` parameters, changing the ajv default options:
298
+ For example, the following code disable type coercion only for the `body`
299
+ parameters, changing the ajv default options:
265
300
 
266
301
  ```js
267
302
  const schemaCompilers = {
@@ -301,13 +336,13 @@ server.setValidatorCompiler(req => {
301
336
 
302
337
  For further information see [here](https://ajv.js.org/coercion.html)
303
338
 
304
- <a name="ajv-plugins"></a>
305
339
  #### Ajv Plugins
340
+ <a id="ajv-plugins"></a>
306
341
 
307
- You can provide a list of plugins you want to use with the default `ajv` instance.
308
- Note that the plugin must be **compatible with Ajv v6**.
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**.
309
344
 
310
- > Refer to [`ajv options`](Server.md#ajv) to check plugins format
345
+ > Refer to [`ajv options`](./Server.md#ajv) to check plugins format
311
346
 
312
347
  ```js
313
348
  const fastify = require('fastify')({
@@ -365,14 +400,18 @@ fastify.post('/foo', {
365
400
  })
366
401
  ```
367
402
 
368
- <a name="schema-validator"></a>
369
403
  #### Validator Compiler
404
+ <a id="schema-validator"></a>
370
405
 
371
- The `validatorCompiler` is a function that returns a function that validates the body, URL parameters, headers, and query string.
372
- The default `validatorCompiler` returns a function that implements the [ajv](https://ajv.js.org/) validation interface.
373
- Fastify uses it internally to speed the validation up.
406
+ The `validatorCompiler` is a function that returns a function that validates the
407
+ body, URL parameters, headers, and query string. The default
408
+ `validatorCompiler` returns a function that implements the
409
+ [ajv](https://ajv.js.org/) validation interface. Fastify uses it internally to
410
+ speed the validation up.
374
411
 
375
- Fastify's [baseline ajv configuration](https://github.com/epoberezkin/ajv#options-to-modify-validated-data) is:
412
+ Fastify's [baseline ajv
413
+ configuration](https://github.com/epoberezkin/ajv#options-to-modify-validated-data)
414
+ is:
376
415
 
377
416
  ```js
378
417
  {
@@ -383,9 +422,11 @@ Fastify's [baseline ajv configuration](https://github.com/epoberezkin/ajv#option
383
422
  }
384
423
  ```
385
424
 
386
- This baseline configuration can be modified by providing [`ajv.customOptions`](Server.md#factory-ajv) to your Fastify factory.
425
+ This baseline configuration can be modified by providing
426
+ [`ajv.customOptions`](./Server.md#factory-ajv) to your Fastify factory.
387
427
 
388
- If you want to change or set additional config options, you will need to create your own instance and override the existing one like:
428
+ If you want to change or set additional config options, you will need to create
429
+ your own instance and override the existing one like:
389
430
 
390
431
  ```js
391
432
  const fastify = require('fastify')()
@@ -403,12 +444,17 @@ fastify.setValidatorCompiler(({ schema, method, url, httpPart }) => {
403
444
  return ajv.compile(schema)
404
445
  })
405
446
  ```
406
- _**Note:** If you use a custom instance of any validator (even Ajv), you have to add schemas to the validator instead of Fastify, since Fastify's default validator is no longer used, and Fastify's `addSchema` method has no idea what validator you are using._
447
+ _**Note:** If you use a custom instance of any validator (even Ajv), you have to
448
+ add schemas to the validator instead of Fastify, since Fastify's default
449
+ validator is no longer used, and Fastify's `addSchema` method has no idea what
450
+ validator you are using._
407
451
 
408
- <a name="using-other-validation-libraries"></a>
409
452
  ##### Using other validation libraries
453
+ <a id="using-other-validation-libraries"></a>
410
454
 
411
- The `setValidatorCompiler` function makes it easy to substitute `ajv` with almost any Javascript validation library ([joi](https://github.com/hapijs/joi/), [yup](https://github.com/jquense/yup/), ...) or a custom one:
455
+ The `setValidatorCompiler` function makes it easy to substitute `ajv` with
456
+ almost any Javascript validation library ([joi](https://github.com/hapijs/joi/),
457
+ [yup](https://github.com/jquense/yup/), ...) or a custom one:
412
458
 
413
459
  ```js
414
460
  const Joi = require('@hapi/joi')
@@ -461,19 +507,32 @@ fastify.post('/the/url', {
461
507
 
462
508
  ##### Validation messages with other validation libraries
463
509
 
464
- Fastify's validation error messages are tightly coupled to the default validation engine: errors returned from `ajv` are eventually run through the `schemaErrorsText` function which is responsible for building human-friendly error messages. However, the `schemaErrorsText` function is written with `ajv` in mind : as a result, you may run into odd or incomplete error messages when using other validation libraries.
510
+ Fastify's validation error messages are tightly coupled to the default
511
+ 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`
514
+ in mind : as a result, you may run into odd or incomplete error messages when
515
+ using other validation libraries.
465
516
 
466
517
  To circumvent this issue, you have 2 main options :
467
518
 
468
- 1. make sure your validation function (returned by your custom `schemaCompiler`) returns errors in the exact same structure and format as `ajv` (although this could prove to be difficult and tricky due to differences between validation engines)
469
- 2. or use a custom `errorHandler` to intercept and format your 'custom' validation errors
519
+ 1. make sure your validation function (returned by your custom `schemaCompiler`)
520
+ returns errors in the exact same structure and format as `ajv` (although this
521
+ could prove to be difficult and tricky due to differences between validation
522
+ engines)
523
+ 2. or use a custom `errorHandler` to intercept and format your 'custom'
524
+ validation errors
470
525
 
471
- To help you in writing a custom `errorHandler`, Fastify adds 2 properties to all validation errors:
526
+ To help you in writing a custom `errorHandler`, Fastify adds 2 properties to all
527
+ validation errors:
472
528
 
473
- * validation: the content of the `error` property of the object returned by the validation function (returned by your custom `schemaCompiler`)
474
- * validationContext: the 'context' (body, params, query, headers) where the validation error occurred
529
+ * validation: the content of the `error` property of the object returned by the
530
+ validation function (returned by your custom `schemaCompiler`)
531
+ * validationContext: the 'context' (body, params, query, headers) where the
532
+ validation error occurred
475
533
 
476
- A very contrived example of such a custom `errorHandler` handling validation errors is shown below:
534
+ A very contrived example of such a custom `errorHandler` handling validation
535
+ errors is shown below:
477
536
 
478
537
  ```js
479
538
  const errorHandler = (error, request, reply) => {
@@ -503,10 +562,15 @@ const errorHandler = (error, request, reply) => {
503
562
  }
504
563
  ```
505
564
 
506
- <a name="serialization"></a>
507
565
  ### Serialization
508
- Usually, you will send your data to the clients as JSON, and Fastify has a powerful tool to help you, [fast-json-stringify](https://www.npmjs.com/package/fast-json-stringify), which is used if you have provided an output schema in the route options.
509
- We encourage you to use an output schema, as it can drastically increase throughput and help prevent accidental disclosure of sensitive information.
566
+ <a id="serialization"></a>
567
+
568
+ Usually, you will send your data to the clients as JSON, and Fastify has a
569
+ powerful tool to help you,
570
+ [fast-json-stringify](https://www.npmjs.com/package/fast-json-stringify), which
571
+ is used if you have provided an output schema in the route options. We encourage
572
+ you to use an output schema, as it can drastically increase throughput and help
573
+ prevent accidental disclosure of sensitive information.
510
574
 
511
575
  Example:
512
576
  ```js
@@ -525,7 +589,8 @@ const schema = {
525
589
  fastify.post('/the/url', { schema }, handler)
526
590
  ```
527
591
 
528
- As you can see, the response schema is based on the status code. If you want to use the same schema for multiple status codes, you can use `'2xx'`, for example:
592
+ As you can see, the response schema is based on the status code. If you want to
593
+ use the same schema for multiple status codes, you can use `'2xx'`, for example:
529
594
  ```js
530
595
  const schema = {
531
596
  response: {
@@ -546,10 +611,13 @@ const schema = {
546
611
  fastify.post('/the/url', { schema }, handler)
547
612
  ```
548
613
 
549
- <a name="schema-serializer"></a>
550
614
  #### Serializer Compiler
615
+ <a id="schema-serializer"></a>
551
616
 
552
- The `serializerCompiler` is a function that returns a function that must return a string from an input object. You must provide a function to serialize every route where you have defined a `response` JSON Schema.
617
+ The `serializerCompiler` is a function that returns a function that must return
618
+ a string from an input object. When you define a response JSON Schema, you can
619
+ change the default serialization method by providing a function to serialize
620
+ every route where you do.
553
621
 
554
622
  ```js
555
623
  fastify.setSerializerCompiler(({ schema, method, url, httpStatus }) => {
@@ -571,10 +639,13 @@ fastify.get('/user', {
571
639
  })
572
640
  ```
573
641
 
574
- *If you need a custom serializer in a very specific part of your code, you can set one with [`reply.serializer(...)`](Reply.md#serializerfunc).*
642
+ *If you need a custom serializer in a very specific part of your code, you can
643
+ set one with [`reply.serializer(...)`](./Reply.md#serializerfunc).*
575
644
 
576
645
  ### Error Handling
577
- When schema validation fails for a request, Fastify will automatically return a status 400 response including the result from the validator in the payload. As an example, if you have the following schema for your route
646
+ When schema validation fails for a request, Fastify will automatically return a
647
+ status 400 response including the result from the validator in the payload. As
648
+ an example, if you have the following schema for your route
578
649
 
579
650
  ```js
580
651
  const schema = {
@@ -588,7 +659,8 @@ const schema = {
588
659
  }
589
660
  ```
590
661
 
591
- and fail to satisfy it, the route will immediately return a response with the following payload
662
+ and fail to satisfy it, the route will immediately return a response with the
663
+ following payload
592
664
 
593
665
  ```js
594
666
  {
@@ -598,7 +670,10 @@ and fail to satisfy it, the route will immediately return a response with the fo
598
670
  }
599
671
  ```
600
672
 
601
- If you want to handle errors inside the route, you can specify the `attachValidation` option for your route. If there is a _validation error_, the `validationError` property of the request will contain the `Error` object with the raw `validation` result as shown below
673
+ If you want to handle errors inside the route, you can specify the
674
+ `attachValidation` option for your route. If there is a _validation error_, the
675
+ `validationError` property of the request will contain the `Error` object with
676
+ the raw `validation` result as shown below
602
677
 
603
678
  ```js
604
679
  const fastify = Fastify()
@@ -613,11 +688,13 @@ fastify.post('/', { schema, attachValidation: true }, function (req, reply) {
613
688
 
614
689
  #### `schemaErrorFormatter`
615
690
 
616
- If you want to format errors yourself, you can provide a sync function that must return an error as the `schemaErrorFormatter` option to Fastify when instantiating.
617
- The context function will be the Fastify server instance.
691
+ If you want to format errors yourself, you can provide a sync function that must
692
+ return an error as the `schemaErrorFormatter` option to Fastify when
693
+ instantiating. The context function will be the Fastify server instance.
618
694
 
619
695
  `errors` is an array of Fastify schema errors `FastifySchemaValidationError`.
620
- `dataVar` is the currently validated part of the schema. (params | body | querystring | headers).
696
+ `dataVar` is the currently validated part of the schema. (params | body |
697
+ querystring | headers).
621
698
 
622
699
  ```js
623
700
  const fastify = Fastify({
@@ -635,7 +712,9 @@ fastify.setSchemaErrorFormatter(function (errors, dataVar) {
635
712
  })
636
713
  ```
637
714
 
638
- You can also use [setErrorHandler](https://www.fastify.io/docs/latest/Server/#seterrorhandler) to define a custom response for validation errors such as
715
+ You can also use
716
+ [setErrorHandler](./Server.md#seterrorhandler) to
717
+ define a custom response for validation errors such as
639
718
 
640
719
  ```js
641
720
  fastify.setErrorHandler(function (error, request, reply) {
@@ -645,11 +724,18 @@ fastify.setErrorHandler(function (error, request, reply) {
645
724
  })
646
725
  ```
647
726
 
648
- If you want custom error response in schema without headaches and quickly, you can take a look at [`ajv-errors`](https://github.com/epoberezkin/ajv-errors). Check out the [example](https://github.com/fastify/example/blob/HEAD/validation-messages/custom-errors-messages.js) usage.
649
- > Make sure to install version 1.0.1 of `ajv-errors`, because later versions of it are not compatible with AJV v6 (the version shipped by Fastify v3).
727
+ If you want custom error response in schema without headaches and quickly, you
728
+ can take a look at [`ajv-errors`](https://github.com/epoberezkin/ajv-errors).
729
+ Check out the
730
+ [example](https://github.com/fastify/example/blob/HEAD/validation-messages/custom-errors-messages.js)
731
+ usage.
732
+ > Make sure to install version 1.0.1 of `ajv-errors`, because later versions of
733
+ > it are not compatible with AJV v6 (the version shipped by Fastify v3).
650
734
 
651
- Below is an example showing how to add **custom error messages for each property** of a schema by supplying custom AJV options.
652
- Inline comments in the schema below describe how to configure it to show a different error message for each case:
735
+ Below is an example showing how to add **custom error messages for each
736
+ property** of a schema by supplying custom AJV options. Inline comments in the
737
+ schema below describe how to configure it to show a different error message for
738
+ each case:
653
739
 
654
740
  ```js
655
741
  const fastify = Fastify({
@@ -699,7 +785,8 @@ fastify.post('/', { schema, }, (request, reply) => {
699
785
  })
700
786
  ```
701
787
 
702
- If you want to return localized error messages, take a look at [ajv-i18n](https://github.com/epoberezkin/ajv-i18n)
788
+ If you want to return localized error messages, take a look at
789
+ [ajv-i18n](https://github.com/epoberezkin/ajv-i18n)
703
790
 
704
791
  ```js
705
792
  const localize = require('ajv-i18n')
@@ -734,7 +821,8 @@ fastify.setErrorHandler(function (error, request, reply) {
734
821
  ### JSON Schema support
735
822
 
736
823
  JSON Schema has some type of utilities in order to optimize your schemas that,
737
- in conjunction with Fastify's shared schema, let you reuse all your schemas easily.
824
+ in conjunction with Fastify's shared schema, let you reuse all your schemas
825
+ easily.
738
826
 
739
827
  | Use Case | Validator | Serializer |
740
828
  |-----------------------------------|-----------|------------|
@@ -836,12 +924,16 @@ const refToSharedSchemaDefinitions = {
836
924
  }
837
925
  ```
838
926
 
839
- <a name="resources"></a>
840
927
  ### Resources
928
+ <a id="resources"></a>
929
+
841
930
  - [JSON Schema](https://json-schema.org/)
842
- - [Understanding JSON Schema](https://spacetelescope.github.io/understanding-json-schema/)
843
- - [fast-json-stringify documentation](https://github.com/fastify/fast-json-stringify)
931
+ - [Understanding JSON
932
+ Schema](https://spacetelescope.github.io/understanding-json-schema/)
933
+ - [fast-json-stringify
934
+ documentation](https://github.com/fastify/fast-json-stringify)
844
935
  - [Ajv documentation](https://github.com/epoberezkin/ajv/blob/master/README.md)
845
936
  - [Ajv i18n](https://github.com/epoberezkin/ajv-i18n)
846
937
  - [Ajv custom errors](https://github.com/epoberezkin/ajv-errors)
847
- - Custom error handling with core methods with error file dumping [example](https://github.com/fastify/example/tree/master/validation-messages)
938
+ - Custom error handling with core methods with error file dumping
939
+ [example](https://github.com/fastify/example/tree/master/validation-messages)
package/docs/index.md ADDED
@@ -0,0 +1,24 @@
1
+ <h1 align="center">Fastify</h1>
2
+
3
+ The documentation for Fastify is split into two categories:
4
+
5
+ - [Reference documentation](./Reference/Index.md)
6
+ - [Guides](./Guides/Index.md)
7
+
8
+ The reference documentation utilizes a very formal style in an effort to document
9
+ Fastify's API and implementation details thoroughly for the developer who needs
10
+ such. The guides category utilizes an informal, educational, style as a means to
11
+ introduce newcomers to core, and advanced, Fastify concepts.
12
+
13
+ ## Where To Start
14
+
15
+ Complete newcomers to Fastify should first read our [Getting
16
+ Started](./Guides/Getting-Started.md) guide.
17
+
18
+ Developers experienced with Fastify should consult the [reference
19
+ documentation](./Reference/index.md) directly to find the topic they are seeking
20
+ more information about.
21
+
22
+ ## Additional Documentation
23
+
24
+ - Fastify's [Long Term Support (LTS)](./Reference/LTS.md) policy
@@ -73,6 +73,6 @@ server.get<{
73
73
  server.listen(8080, (err, address) => {
74
74
  if (err) {
75
75
  console.error(err);
76
- process.exit(0);
76
+ process.exit(1);
77
77
  }
78
78
  });
package/fastify.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const VERSION = '3.24.0'
3
+ const VERSION = '3.25.2'
4
4
 
5
5
  const Avvio = require('avvio')
6
6
  const http = require('http')
@@ -631,8 +631,7 @@ function fastify (options) {
631
631
  function setSchemaController (schemaControllerOpts) {
632
632
  throwIfAlreadyStarted('Cannot call "setSchemaController" when fastify instance is already started!')
633
633
  const old = this[kSchemaController]
634
- const parent = old.parent || old
635
- const schemaController = SchemaController.buildSchemaController(parent, Object.assign({}, old.opts, schemaControllerOpts))
634
+ const schemaController = SchemaController.buildSchemaController(old, Object.assign({}, old.opts, schemaControllerOpts))
636
635
  this[kSchemaController] = schemaController
637
636
  this.getSchema = schemaController.getSchema.bind(schemaController)
638
637
  this.getSchemas = schemaController.getSchemas.bind(schemaController)
@@ -1,5 +1,6 @@
1
1
  'use strict'
2
2
 
3
+ const { AsyncResource } = require('async_hooks')
3
4
  let lru = require('tiny-lru')
4
5
  // Needed to handle Webpack and faux modules
5
6
  // See https://github.com/fastify/fastify/issues/2356
@@ -137,6 +138,7 @@ ContentTypeParser.prototype.remove = function (contentType) {
137
138
 
138
139
  ContentTypeParser.prototype.run = function (contentType, handler, request, reply) {
139
140
  const parser = this.cache.get(contentType) || this.getParser(contentType)
141
+ const resource = new AsyncResource('content-type-parser:run', request)
140
142
 
141
143
  if (parser === undefined) {
142
144
  reply.send(new FST_ERR_CTP_INVALID_MEDIA_TYPE(contentType))
@@ -163,12 +165,15 @@ ContentTypeParser.prototype.run = function (contentType, handler, request, reply
163
165
  }
164
166
 
165
167
  function done (error, body) {
166
- if (error) {
167
- reply.send(error)
168
- } else {
169
- request.body = body
170
- handler(request, reply)
171
- }
168
+ // We cannot use resource.bind() because it is broken in node v12.
169
+ resource.runInAsyncScope(() => {
170
+ if (error) {
171
+ reply.send(error)
172
+ } else {
173
+ request.body = body
174
+ handler(request, reply)
175
+ }
176
+ })
172
177
  }
173
178
  }
174
179
 
package/lib/decorate.js CHANGED
@@ -40,7 +40,7 @@ function decorateConstructor (konstructor, name, fn, dependencies) {
40
40
  throw new FST_ERR_DEC_ALREADY_PRESENT(name)
41
41
  }
42
42
 
43
- checkDependencies(instance, name, dependencies)
43
+ checkDependencies(konstructor, name, dependencies)
44
44
 
45
45
  if (fn && (typeof fn.getter === 'function' || typeof fn.setter === 'function')) {
46
46
  Object.defineProperty(instance, name, {
@@ -68,14 +68,17 @@ function decorateFastify (name, fn, dependencies) {
68
68
 
69
69
  function checkExistence (instance, name) {
70
70
  if (name) {
71
- return name in instance
71
+ return name in instance || (instance.prototype && name in instance.prototype) || hasKey(instance, name)
72
72
  }
73
73
 
74
74
  return instance in this
75
75
  }
76
76
 
77
77
  function hasKey (fn, name) {
78
- return fn.props.find(({ key }) => key === name)
78
+ if (fn.props) {
79
+ return fn.props.find(({ key }) => key === name)
80
+ }
81
+ return false
79
82
  }
80
83
 
81
84
  function checkRequestExistence (name) {
package/lib/logger.js CHANGED
@@ -50,7 +50,7 @@ const serializers = {
50
50
  return {
51
51
  method: req.method,
52
52
  url: req.url,
53
- version: req.headers['accept-version'],
53
+ version: req.headers && req.headers['accept-version'],
54
54
  hostname: req.hostname,
55
55
  remoteAddress: req.ip,
56
56
  remotePort: req.socket ? req.socket.remotePort : undefined
package/lib/route.js CHANGED
@@ -248,7 +248,7 @@ function buildRouting (options) {
248
248
  opts.schemaErrorFormatter || this[kSchemaErrorFormatter]
249
249
  )
250
250
 
251
- const headRouteExists = router.find('HEAD', url) != null
251
+ const headRouteExists = router.find('HEAD', url, constraints) != null
252
252
 
253
253
  try {
254
254
  router.on(opts.method, opts.url, { constraints }, routeHandler, context)
package/lib/server.js CHANGED
@@ -14,19 +14,20 @@ function createServer (options, httpHandler) {
14
14
  let server = null
15
15
  if (options.serverFactory) {
16
16
  server = options.serverFactory(httpHandler, options)
17
- } else if (options.https) {
18
- if (options.http2) {
17
+ } else if (options.http2) {
18
+ if (options.https) {
19
19
  server = http2().createSecureServer(options.https, httpHandler)
20
- server.on('session', sessionTimeout(options.http2SessionTimeout))
21
20
  } else {
22
- server = https.createServer(options.https, httpHandler)
23
- server.keepAliveTimeout = options.keepAliveTimeout
21
+ server = http2().createServer(httpHandler)
24
22
  }
25
- } else if (options.http2) {
26
- server = http2().createServer(httpHandler)
27
23
  server.on('session', sessionTimeout(options.http2SessionTimeout))
28
24
  } else {
29
- server = http.createServer(httpHandler)
25
+ // this is http1
26
+ if (options.https) {
27
+ server = https.createServer(options.https, httpHandler)
28
+ } else {
29
+ server = http.createServer(httpHandler)
30
+ }
30
31
  server.keepAliveTimeout = options.keepAliveTimeout
31
32
  server.requestTimeout = options.requestTimeout
32
33
  // we treat zero as null