fastify 3.27.2 → 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.
- package/README.md +5 -4
- package/build/build-error-serializer.js +27 -0
- package/build/build-validation.js +47 -35
- package/docs/Migration-Guide-V4.md +12 -0
- package/docs/Reference/ContentTypeParser.md +4 -0
- package/docs/Reference/Errors.md +51 -6
- package/docs/Reference/Hooks.md +4 -7
- package/docs/Reference/LTS.md +5 -4
- package/docs/Reference/Reply.md +23 -22
- package/docs/Reference/Request.md +1 -3
- package/docs/Reference/Routes.md +17 -10
- package/docs/Reference/Server.md +48 -63
- package/docs/Reference/TypeScript.md +11 -13
- package/docs/Reference/Validation-and-Serialization.md +28 -53
- package/docs/Type-Providers.md +257 -0
- package/examples/hooks.js +1 -1
- package/examples/simple-stream.js +18 -0
- package/fastify.d.ts +34 -22
- package/fastify.js +37 -35
- package/lib/configValidator.js +902 -1023
- package/lib/contentTypeParser.js +6 -16
- package/lib/context.js +36 -10
- package/lib/decorate.js +3 -1
- package/lib/error-handler.js +158 -0
- package/lib/error-serializer.js +257 -0
- package/lib/errors.js +43 -9
- package/lib/fourOhFour.js +31 -20
- package/lib/handleRequest.js +10 -13
- package/lib/hooks.js +14 -9
- package/lib/pluginOverride.js +0 -3
- package/lib/pluginUtils.js +3 -2
- package/lib/reply.js +28 -157
- package/lib/request.js +13 -10
- package/lib/route.js +131 -138
- package/lib/schema-controller.js +2 -2
- package/lib/schemas.js +27 -1
- package/lib/server.js +219 -116
- package/lib/symbols.js +4 -3
- package/lib/validation.js +2 -1
- package/lib/warnings.js +2 -12
- package/lib/wrapThenable.js +4 -11
- package/package.json +31 -35
- package/test/404s.test.js +243 -110
- package/test/500s.test.js +2 -2
- package/test/async-await.test.js +13 -69
- package/test/content-parser.test.js +32 -0
- package/test/context-config.test.js +52 -0
- package/test/custom-http-server.test.js +14 -7
- package/test/custom-parser-async.test.js +0 -65
- package/test/custom-parser.test.js +54 -121
- package/test/decorator.test.js +1 -3
- package/test/delete.test.js +5 -5
- package/test/encapsulated-error-handler.test.js +50 -0
- package/test/esm/index.test.js +0 -14
- package/test/fastify-instance.test.js +4 -4
- package/test/fluent-schema.test.js +4 -4
- package/test/get.test.js +3 -3
- package/test/helper.js +18 -3
- package/test/hooks-async.test.js +14 -47
- package/test/hooks.on-ready.test.js +9 -4
- package/test/hooks.test.js +58 -99
- package/test/http2/closing.test.js +5 -11
- package/test/http2/unknown-http-method.test.js +3 -9
- package/test/https/custom-https-server.test.js +12 -6
- package/test/input-validation.js +2 -2
- package/test/internals/handleRequest.test.js +3 -40
- package/test/internals/initialConfig.test.js +33 -12
- package/test/internals/reply.test.js +245 -3
- package/test/internals/request.test.js +13 -7
- package/test/internals/server.test.js +88 -0
- package/test/listen.test.js +84 -1
- package/test/logger.test.js +80 -40
- package/test/maxRequestsPerSocket.test.js +6 -4
- package/test/middleware.test.js +2 -25
- package/test/nullable-validation.test.js +51 -14
- package/test/plugin.test.js +31 -5
- package/test/pretty-print.test.js +22 -10
- package/test/reply-error.test.js +123 -12
- package/test/request-error.test.js +2 -5
- package/test/route-hooks.test.js +17 -17
- package/test/route-prefix.test.js +2 -1
- package/test/route.test.js +204 -20
- package/test/router-options.test.js +1 -1
- package/test/schema-examples.test.js +11 -5
- package/test/schema-feature.test.js +24 -19
- package/test/schema-serialization.test.js +9 -9
- package/test/schema-special-usage.test.js +14 -81
- package/test/schema-validation.test.js +9 -9
- package/test/skip-reply-send.test.js +1 -1
- package/test/stream.test.js +23 -12
- package/test/throw.test.js +8 -5
- package/test/type-provider.test.js +20 -0
- package/test/types/fastify.test-d.ts +10 -18
- package/test/types/import.js +2 -0
- package/test/types/import.ts +1 -0
- package/test/types/instance.test-d.ts +35 -14
- package/test/types/logger.test-d.ts +44 -15
- package/test/types/route.test-d.ts +8 -2
- package/test/types/schema.test-d.ts +2 -39
- package/test/types/type-provider.test-d.ts +417 -0
- package/test/validation-error-handling.test.js +8 -8
- package/test/versioned-routes.test.js +28 -16
- package/test/wrapThenable.test.js +7 -6
- package/types/content-type-parser.d.ts +17 -8
- package/types/hooks.d.ts +102 -59
- package/types/instance.d.ts +124 -104
- package/types/logger.d.ts +18 -104
- package/types/plugin.d.ts +10 -4
- package/types/reply.d.ts +16 -11
- package/types/request.d.ts +10 -5
- package/types/route.d.ts +42 -31
- package/types/schema.d.ts +1 -1
- package/types/type-provider.d.ts +99 -0
- package/types/utils.d.ts +1 -1
- package/lib/schema-compilers.js +0 -12
- package/test/emit-warning.test.js +0 -166
package/README.md
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
<div align="center">
|
|
2
|
-
<a href="https://fastify.io/">
|
|
1
|
+
<div align="center"> <a href="https://fastify.io/">
|
|
3
2
|
<img src="https://github.com/fastify/graphics/raw/HEAD/fastify-landscape-outlined.svg" width="650" height="auto"/>
|
|
4
3
|
</a>
|
|
5
4
|
</div>
|
|
@@ -45,6 +44,8 @@ How can you efficiently handle the resources of your server, knowing that you ar
|
|
|
45
44
|
|
|
46
45
|
Enter Fastify. Fastify is a web framework highly focused on providing the best developer experience with the least overhead and a powerful plugin architecture. It is inspired by Hapi and Express and as far as we know, it is one of the fastest web frameworks in town.
|
|
47
46
|
|
|
47
|
+
This branch refers to the upcoming Fastify v4 release. Check out the [v3.x](https://github.com/fastify/fastify/tree/v3.x) branch for v3.
|
|
48
|
+
|
|
48
49
|
### Quick start
|
|
49
50
|
|
|
50
51
|
Create a folder and make it your current working directory:
|
|
@@ -88,11 +89,11 @@ If installing in an existing project, then Fastify can be installed into the pro
|
|
|
88
89
|
|
|
89
90
|
Install with npm:
|
|
90
91
|
```sh
|
|
91
|
-
npm i fastify --save
|
|
92
|
+
npm i fastify@next --save
|
|
92
93
|
```
|
|
93
94
|
Install with yarn:
|
|
94
95
|
```sh
|
|
95
|
-
yarn add fastify
|
|
96
|
+
yarn add fastify@next
|
|
96
97
|
```
|
|
97
98
|
|
|
98
99
|
### Example
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const FJS = require('fast-json-stringify')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const fs = require('fs')
|
|
6
|
+
|
|
7
|
+
const debugCompiled = FJS({
|
|
8
|
+
type: 'object',
|
|
9
|
+
properties: {
|
|
10
|
+
statusCode: { type: 'number' },
|
|
11
|
+
code: { type: 'string' },
|
|
12
|
+
error: { type: 'string' },
|
|
13
|
+
message: { type: 'string' }
|
|
14
|
+
}
|
|
15
|
+
}, { debugMode: true })
|
|
16
|
+
|
|
17
|
+
const file = path.join(__dirname, '..', 'lib', 'error-serializer.js')
|
|
18
|
+
const rawString = debugCompiled.toString()
|
|
19
|
+
|
|
20
|
+
const moduleCode = `// This file is autogenerated by build/build-error-serializer.js, do not edit
|
|
21
|
+
/* istanbul ignore file */
|
|
22
|
+
module.exports = $main
|
|
23
|
+
${rawString.slice(5)}
|
|
24
|
+
`
|
|
25
|
+
|
|
26
|
+
fs.writeFileSync(file, moduleCode)
|
|
27
|
+
console.log(`Saved ${file} file successfully`)
|
|
@@ -1,20 +1,29 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const AjvStandaloneCompiler = require('@fastify/ajv-compiler/standalone')
|
|
4
|
+
const { _ } = require('ajv')
|
|
4
5
|
const fs = require('fs')
|
|
5
6
|
const path = require('path')
|
|
6
|
-
const pack = require('ajv-pack')
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
const factory = AjvStandaloneCompiler({
|
|
9
|
+
readMode: false,
|
|
10
|
+
storeFunction (routeOpts, schemaValidationCode) {
|
|
11
|
+
const moduleCode = `// This file is autogenerated by ${__filename.replace(__dirname, 'build')}, do not edit
|
|
12
|
+
/* istanbul ignore file */
|
|
13
|
+
${schemaValidationCode}
|
|
14
|
+
|
|
15
|
+
module.exports.defaultInitOptions = ${JSON.stringify(defaultInitOptions)}
|
|
16
|
+
`
|
|
17
|
+
|
|
18
|
+
const file = path.join(__dirname, '..', 'lib', 'configValidator.js')
|
|
19
|
+
fs.writeFileSync(file, moduleCode)
|
|
20
|
+
console.log(`Saved ${file} file successfully`)
|
|
21
|
+
}
|
|
13
22
|
})
|
|
14
23
|
|
|
15
24
|
const defaultInitOptions = {
|
|
16
25
|
connectionTimeout: 0, // 0 sec
|
|
17
|
-
keepAliveTimeout:
|
|
26
|
+
keepAliveTimeout: 72000, // 72 seconds
|
|
18
27
|
forceCloseConnections: false, // keep-alive connections
|
|
19
28
|
maxRequestsPerSocket: 0, // no limit
|
|
20
29
|
requestTimeout: 0, // no limit
|
|
@@ -29,21 +38,10 @@ const defaultInitOptions = {
|
|
|
29
38
|
pluginTimeout: 10000,
|
|
30
39
|
requestIdHeader: 'request-id',
|
|
31
40
|
requestIdLogLabel: 'reqId',
|
|
32
|
-
http2SessionTimeout:
|
|
41
|
+
http2SessionTimeout: 72000, // 72 seconds
|
|
42
|
+
exposeHeadRoutes: true
|
|
33
43
|
}
|
|
34
44
|
|
|
35
|
-
function customRule0 (schemaParamValue, validatedParamValue, validationSchemaObject, currentDataPath, validatedParamObject, validatedParam) {
|
|
36
|
-
validatedParamObject[validatedParam] = schemaParamValue
|
|
37
|
-
return true
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// We add a keyword that allow us to set default values
|
|
41
|
-
ajv.addKeyword('setDefaultValue', {
|
|
42
|
-
modifying: true,
|
|
43
|
-
validate: customRule0,
|
|
44
|
-
errors: false
|
|
45
|
-
})
|
|
46
|
-
|
|
47
45
|
const schema = {
|
|
48
46
|
type: 'object',
|
|
49
47
|
additionalProperties: false,
|
|
@@ -88,6 +86,7 @@ const schema = {
|
|
|
88
86
|
requestIdHeader: { type: 'string', default: defaultInitOptions.requestIdHeader },
|
|
89
87
|
requestIdLogLabel: { type: 'string', default: defaultInitOptions.requestIdLogLabel },
|
|
90
88
|
http2SessionTimeout: { type: 'integer', default: defaultInitOptions.http2SessionTimeout },
|
|
89
|
+
exposeHeadRoutes: { type: 'boolean', default: defaultInitOptions.exposeHeadRoutes },
|
|
91
90
|
// deprecated style of passing the versioning constraint
|
|
92
91
|
versioning: {
|
|
93
92
|
type: 'object',
|
|
@@ -115,18 +114,31 @@ const schema = {
|
|
|
115
114
|
}
|
|
116
115
|
}
|
|
117
116
|
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
117
|
+
const compiler = factory({}, {
|
|
118
|
+
customOptions: {
|
|
119
|
+
code: {
|
|
120
|
+
source: true,
|
|
121
|
+
lines: true,
|
|
122
|
+
optimize: 3
|
|
123
|
+
},
|
|
124
|
+
removeAdditional: true,
|
|
125
|
+
useDefaults: true,
|
|
126
|
+
coerceTypes: true,
|
|
127
|
+
keywords: [
|
|
128
|
+
{
|
|
129
|
+
keyword: 'setDefaultValue',
|
|
130
|
+
$data: true,
|
|
131
|
+
// error: false,
|
|
132
|
+
modifying: true,
|
|
133
|
+
valid: true,
|
|
134
|
+
code (keywordCxt) {
|
|
135
|
+
const { gen, it, schemaValue } = keywordCxt
|
|
136
|
+
const logicCode = gen.assign(_`${it.parentData}[${it.parentDataProperty}]`, schemaValue)
|
|
137
|
+
return logicCode
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
})
|
|
131
143
|
|
|
132
|
-
|
|
144
|
+
compiler({ schema })
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# V4 Migration Guide
|
|
2
|
+
|
|
3
|
+
This guide is intended to help with migration from Fastify v3 to v4.
|
|
4
|
+
|
|
5
|
+
Before migrating to v4, please ensure that you have fixed all deprecation warningx from v3.
|
|
6
|
+
All v3 deprecations have been removed and they will no longer work after upgrading.
|
|
7
|
+
|
|
8
|
+
## Breaking Changes
|
|
9
|
+
|
|
10
|
+
### Deprecation of `app.use()`
|
|
11
|
+
|
|
12
|
+
Starting this version of Fastify, we have deprecated the use of `app.use()`. We have decided not to support the use of middlewares. Both [`middie`](https://github.com/fastify/middie) and [`fastify-express`](https://github.com/fastify/fastify-express) will still be there and maintained. Use Fastify's [hooks](./Hooks.md) instead.
|
|
@@ -21,6 +21,9 @@ available only in that scope and its children.
|
|
|
21
21
|
Fastify automatically adds the parsed request payload to the [Fastify
|
|
22
22
|
request](./Request.md) object which you can access with `request.body`.
|
|
23
23
|
|
|
24
|
+
Note that for `GET` and `HEAD` requests the payload is never parsed. For `OPTIONS` and `DELETE` requests the payload is only parsed if
|
|
25
|
+
the content type is given in the content-type header. If it is not given, the [catch-all](#catch-all) parser is not executed as with `POST`, `PUT` and `PATCH`, but the payload is simply not parsed.
|
|
26
|
+
|
|
24
27
|
### Usage
|
|
25
28
|
```js
|
|
26
29
|
fastify.addContentTypeParser('application/jsoff', function (request, payload, done) {
|
|
@@ -90,6 +93,7 @@ if (!fastify.hasContentTypeParser('application/jsoff')){
|
|
|
90
93
|
}
|
|
91
94
|
```
|
|
92
95
|
|
|
96
|
+
=======
|
|
93
97
|
#### removeContentTypeParser
|
|
94
98
|
|
|
95
99
|
With `removeContentTypeParser` a single or an array of content types can be
|
package/docs/Reference/Errors.md
CHANGED
|
@@ -56,9 +56,19 @@ From the [Hooks documentation](./Hooks.md#manage-errors-from-a-hook):
|
|
|
56
56
|
> `done()` and Fastify will automatically close the request and send the
|
|
57
57
|
> appropriate error code to the user.
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
When a custom error handler has been defined through
|
|
60
|
+
[`setErrorHandler`](./Server.md#seterrorhandler), the custom error handler will
|
|
61
|
+
receive the error passed to the `done()` callback (or through other supported
|
|
62
|
+
automatic error handling mechanisms). If `setErrorHandler` has been used
|
|
63
|
+
multiple times to define multiple handlers, the error will be routed to the most
|
|
64
|
+
precedent handler defined within the error [encapsulation context](./Encapsulation.md).
|
|
65
|
+
Error handlers are fully encapsulated, so a `setErrorHandler` call within a
|
|
66
|
+
plugin will limit the error handler to that plugin's context.
|
|
67
|
+
|
|
68
|
+
The root error handler is Fastify's generic error handler. This error handler
|
|
69
|
+
will use the headers and status code in the `Error` object, if they exist. The
|
|
70
|
+
headers and status code will not be automatically set if a custom error handler
|
|
71
|
+
is provided.
|
|
62
72
|
|
|
63
73
|
Some things to consider in your custom error handler:
|
|
64
74
|
|
|
@@ -70,13 +80,12 @@ Some things to consider in your custom error handler:
|
|
|
70
80
|
headers (no serialization)
|
|
71
81
|
|
|
72
82
|
- You can throw a new error in your custom error handler
|
|
73
|
-
|
|
74
|
-
|
|
83
|
+
- errors (new error or the received error parameter re-thrown) - will call the parent `errorHandler`.
|
|
84
|
+
- `onError` hook will be triggered once only for the first error being thrown.
|
|
75
85
|
- an error will not be triggered twice from a lifecycle hook - Fastify
|
|
76
86
|
internally monitors the error invocation to avoid infinite loops for errors
|
|
77
87
|
thrown in the reply phases of the lifecycle. (those after the route handler)
|
|
78
88
|
|
|
79
|
-
|
|
80
89
|
### Fastify Error Codes
|
|
81
90
|
<a id="fastify-error-codes"></a>
|
|
82
91
|
|
|
@@ -85,6 +94,12 @@ Some things to consider in your custom error handler:
|
|
|
85
94
|
|
|
86
95
|
The router received an invalid url.
|
|
87
96
|
|
|
97
|
+
<a name="FST_ERR_DUPLICATED_ROUTE"></a>
|
|
98
|
+
#### FST_ERR_DUPLICATED_ROUTE
|
|
99
|
+
|
|
100
|
+
The HTTP method already has a registered controller for that URL
|
|
101
|
+
|
|
102
|
+
<a name="FST_ERR_CTP_ALREADY_PRESENT"></a>
|
|
88
103
|
#### FST_ERR_CTP_ALREADY_PRESENT
|
|
89
104
|
<a id="FST_ERR_CTP_ALREADY_PRESENT"></a>
|
|
90
105
|
|
|
@@ -199,3 +214,33 @@ You cannot use `send` inside the `onError` hook.
|
|
|
199
214
|
<a id="FST_ERR_SEND_UNDEFINED_ERR"></a>
|
|
200
215
|
|
|
201
216
|
Undefined error has occurred.
|
|
217
|
+
|
|
218
|
+
<a name="FST_ERR_PLUGIN_NOT_VALID"></a>
|
|
219
|
+
#### FST_ERR_PLUGIN_NOT_VALID
|
|
220
|
+
|
|
221
|
+
Plugin must be a function or a promise.
|
|
222
|
+
|
|
223
|
+
<a name="FST_ERR_PLUGIN_TIMEOUT"></a>
|
|
224
|
+
#### FST_ERR_PLUGIN_TIMEOUT
|
|
225
|
+
|
|
226
|
+
Plugin did not start in time. Default timeout (in millis): `10000`
|
|
227
|
+
|
|
228
|
+
<a name="FST_ERR_HOOK_TIMEOUT"></a>
|
|
229
|
+
#### FST_ERR_HOOK_TIMEOUT
|
|
230
|
+
|
|
231
|
+
A callback for a hook timed out
|
|
232
|
+
|
|
233
|
+
<a name="FST_ERR_ROOT_PLG_BOOTED"></a>
|
|
234
|
+
#### FST_ERR_ROOT_PLG_BOOTED
|
|
235
|
+
|
|
236
|
+
Root plugin has already booted (mapped directly from `avvio`)
|
|
237
|
+
|
|
238
|
+
<a name="FST_ERR_PARENT_PLUGIN_BOOTED"></a>
|
|
239
|
+
#### FST_ERR_PARENT_PLUGIN_BOOTED
|
|
240
|
+
|
|
241
|
+
Impossible to load plugin because the parent (mapped directly from `avvio`)
|
|
242
|
+
|
|
243
|
+
<a name="FST_ERR_PLUGIN_CALLBACK_NOT_FN"></a>
|
|
244
|
+
#### FST_ERR_PLUGIN_CALLBACK_NOT_FN
|
|
245
|
+
|
|
246
|
+
Callback for a hook is not a function (mapped directly from `avvio`)
|
package/docs/Reference/Hooks.md
CHANGED
|
@@ -65,7 +65,7 @@ fastify.addHook('onRequest', async (request, reply) => {
|
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
**Notice:** in the [onRequest](#onrequest) hook, `request.body` will always be
|
|
68
|
-
`
|
|
68
|
+
`undefined`, because the body parsing happens before the
|
|
69
69
|
[preValidation](#prevalidation) hook.
|
|
70
70
|
|
|
71
71
|
### preParsing
|
|
@@ -95,7 +95,7 @@ fastify.addHook('preParsing', async (request, reply, payload) => {
|
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
**Notice:** in the [preParsing](#preparsing) hook, `request.body` will always be
|
|
98
|
-
`
|
|
98
|
+
`undefined`, because the body parsing happens before the
|
|
99
99
|
[preValidation](#prevalidation) hook.
|
|
100
100
|
|
|
101
101
|
**Notice:** you should also add a `receivedEncodedLength` property to the
|
|
@@ -103,10 +103,6 @@ returned stream. This property is used to correctly match the request payload
|
|
|
103
103
|
with the `Content-Length` header value. Ideally, this property should be updated
|
|
104
104
|
on each received chunk.
|
|
105
105
|
|
|
106
|
-
**Notice**: The old syntaxes `function(request, reply, done)` and `async
|
|
107
|
-
function(request, reply)` for the parser are still supported but they are
|
|
108
|
-
deprecated.
|
|
109
|
-
|
|
110
106
|
### preValidation
|
|
111
107
|
|
|
112
108
|
If you are using the `preValidation` hook, you can change the payload before it
|
|
@@ -322,7 +318,7 @@ fastify.addHook('onRequest', (request, reply, done) => {
|
|
|
322
318
|
fastify.addHook('preHandler', async (request, reply) => {
|
|
323
319
|
await something()
|
|
324
320
|
reply.send({ hello: 'world' })
|
|
325
|
-
return reply //
|
|
321
|
+
return reply // mandatory, so the request is not executed further
|
|
326
322
|
})
|
|
327
323
|
```
|
|
328
324
|
|
|
@@ -419,6 +415,7 @@ fastify.addHook('onClose', async (instance) => {
|
|
|
419
415
|
Triggered when a new route is registered. Listeners are passed a `routeOptions`
|
|
420
416
|
object as the sole parameter. The interface is synchronous, and, as such, the
|
|
421
417
|
listeners are not passed a callback. This hook is encapsulated.
|
|
418
|
+
|
|
422
419
|
```js
|
|
423
420
|
fastify.addHook('onRoute', (routeOptions) => {
|
|
424
421
|
//Some code
|
package/docs/Reference/LTS.md
CHANGED
|
@@ -48,6 +48,7 @@ A "month" is defined as 30 consecutive days.
|
|
|
48
48
|
| 1.0.0 | 2018-03-06 | 2019-09-01 | 6, 8, 9, 10, 11 |
|
|
49
49
|
| 2.0.0 | 2019-02-25 | 2021-01-31 | 6, 8, 10, 12, 14 |
|
|
50
50
|
| 3.0.0 | 2020-07-07 | TBD | 10, 12, 14, 16 |
|
|
51
|
+
| 4.0.0 | TBD | TBD | 14, 16 |
|
|
51
52
|
|
|
52
53
|
### CI tested operating systems
|
|
53
54
|
<a id="supported-os"></a>
|
|
@@ -60,10 +61,10 @@ YAML workflow labels below:
|
|
|
60
61
|
|
|
61
62
|
| OS | YAML Workflow Label | Package Manager | Node.js |
|
|
62
63
|
|---------|------------------------|---------------------------|--------------|
|
|
63
|
-
| Linux | `ubuntu-latest` | npm |
|
|
64
|
-
| Linux | `ubuntu-18.04` | yarn,pnpm |
|
|
65
|
-
| Windows | `windows-latest` | npm |
|
|
66
|
-
| MacOS | `macos-latest` | npm |
|
|
64
|
+
| Linux | `ubuntu-latest` | npm | 14,16 |
|
|
65
|
+
| Linux | `ubuntu-18.04` | yarn,pnpm | 14,16 |
|
|
66
|
+
| Windows | `windows-latest` | npm | 14,16 |
|
|
67
|
+
| MacOS | `macos-latest` | npm | 14,16 |
|
|
67
68
|
|
|
68
69
|
Using [yarn](https://yarnpkg.com/) might require passing the `--ignore-engines`
|
|
69
70
|
flag.
|
package/docs/Reference/Reply.md
CHANGED
|
@@ -59,12 +59,10 @@ object that exposes the following functions and properties:
|
|
|
59
59
|
buffer, JSON, stream, or an Error object.
|
|
60
60
|
- `.sent` - A boolean value that you can use if you need to know if `send` has
|
|
61
61
|
already been called.
|
|
62
|
+
- `.hijack()` - interrupt the normal request lifecycle.
|
|
62
63
|
- `.raw` - The
|
|
63
64
|
[`http.ServerResponse`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_class_http_serverresponse)
|
|
64
65
|
from Node core.
|
|
65
|
-
- `.res` *(deprecated, use `.raw` instead)* - The
|
|
66
|
-
[`http.ServerResponse`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_class_http_serverresponse)
|
|
67
|
-
from Node core.
|
|
68
66
|
- `.log` - The logger instance of the incoming request.
|
|
69
67
|
- `.request` - The incoming request.
|
|
70
68
|
- `.context` - Access the [Request's context](./Request.md) property.
|
|
@@ -125,6 +123,8 @@ fastify.get('/', async function (req, rep) {
|
|
|
125
123
|
Sets a response header. If the value is omitted or undefined, it is coerced to
|
|
126
124
|
`''`.
|
|
127
125
|
|
|
126
|
+
> Note: the header's value must be properly encoded using [`encodeURI`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI) or similar modules such as [`encodeurl`](https://www.npmjs.com/package/encodeurl). Invalid characters will result in a 500 `TypeError` response.
|
|
127
|
+
|
|
128
128
|
For more information, see
|
|
129
129
|
[`http.ServerResponse#setHeader`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_response_setheader_name_value).
|
|
130
130
|
|
|
@@ -205,6 +205,8 @@ Returns a boolean indicating if the specified header has been set.
|
|
|
205
205
|
Redirects a request to the specified URL, the status code is optional, default
|
|
206
206
|
to `302` (if status code is not already set by calling `code`).
|
|
207
207
|
|
|
208
|
+
> Note: the input URL must be properly encoded using [`encodeURI`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI) or similar modules such as [`encodeurl`](https://www.npmjs.com/package/encodeurl). Invalid URLs will result in a 500 `TypeError` response.
|
|
209
|
+
|
|
208
210
|
Example (no `reply.code()` call) sets status code to `302` and redirects to
|
|
209
211
|
`/home`
|
|
210
212
|
```js
|
|
@@ -315,39 +317,38 @@ Another example of the misuse of `Reply.raw` is explained in
|
|
|
315
317
|
|
|
316
318
|
As the name suggests, `.sent` is a property to indicate if a response has been
|
|
317
319
|
sent via `reply.send()`.
|
|
320
|
+
It will also be `true` in case `reply.hijack()` was used.
|
|
318
321
|
|
|
319
322
|
In case a route handler is defined as an async function or it returns a promise,
|
|
320
|
-
it is possible to
|
|
323
|
+
it is possible to call `reply.hijack()` to indicate that the automatic
|
|
321
324
|
invocation of `reply.send()` once the handler promise resolve should be skipped.
|
|
322
|
-
By
|
|
325
|
+
By calling `reply.hijack()`, an application claims full responsibility for
|
|
323
326
|
the low-level request and response. Moreover, hooks will not be invoked.
|
|
324
327
|
|
|
325
|
-
|
|
328
|
+
*Modifying the `.sent` property directly is deprecated. Please use the aformentioned
|
|
329
|
+
`.hijack()` method to achieve the same effect.*
|
|
330
|
+
|
|
331
|
+
<a name="hijack"></a>
|
|
332
|
+
### .hijack()
|
|
333
|
+
Sometimes you might need to halt the execution of the normal request lifecycle and
|
|
334
|
+
handle sending the response manually.
|
|
335
|
+
|
|
336
|
+
To achieve this, Fastify provides the `reply.hijack()` method that can be called
|
|
337
|
+
during the request lifecycle (At any point before `reply.send()` is called), and
|
|
338
|
+
allows you to prevent Fastify from sending the response, and from running the
|
|
339
|
+
remaining hooks (and user handler if the reply was hijacked before).
|
|
326
340
|
|
|
327
341
|
```js
|
|
328
342
|
app.get('/', (req, reply) => {
|
|
329
|
-
reply.
|
|
343
|
+
reply.hijack()
|
|
330
344
|
reply.raw.end('hello world')
|
|
331
345
|
|
|
332
346
|
return Promise.resolve('this will be skipped')
|
|
333
347
|
})
|
|
334
348
|
```
|
|
335
349
|
|
|
336
|
-
If
|
|
337
|
-
|
|
338
|
-
### .hijack()
|
|
339
|
-
<a id="hijack"></a>
|
|
340
|
-
|
|
341
|
-
Sometimes you might need to halt the execution of the normal request lifecycle
|
|
342
|
-
and handle sending the response manually.
|
|
343
|
-
|
|
344
|
-
To achieve this, Fastify provides the `reply.hijack()` method that can be called
|
|
345
|
-
during the request lifecycle (At any point before `reply.send()` is called), and
|
|
346
|
-
allows you to prevent Fastify from sending the response, and from running the
|
|
347
|
-
remaining hooks (and user handler if the reply was hijacked before).
|
|
348
|
-
|
|
349
|
-
NB (*): If `reply.raw` is used to send a response back to the user, `onResponse`
|
|
350
|
-
hooks will still be executed
|
|
350
|
+
If `reply.raw` is used to send a response back to the user, the `onResponse`
|
|
351
|
+
hooks will still be executed.
|
|
351
352
|
|
|
352
353
|
### .send(data)
|
|
353
354
|
<a id="send"></a>
|
|
@@ -12,10 +12,8 @@ Request is a core Fastify object containing the following fields:
|
|
|
12
12
|
- `params` - the params matching the URL
|
|
13
13
|
- [`headers`](#headers) - the headers getter and setter
|
|
14
14
|
- `raw` - the incoming HTTP request from Node core
|
|
15
|
-
- `req` *(deprecated, use `.raw` instead)* - the incoming HTTP request from Node
|
|
16
|
-
core
|
|
17
15
|
- `server` - The Fastify server instance, scoped to the current [encapsulation
|
|
18
|
-
|
|
16
|
+
>>>>>>> main:docs/Reference/Request.md
|
|
19
17
|
- `id` - the request ID
|
|
20
18
|
- `log` - the logger instance of the incoming request
|
|
21
19
|
- `ip` - the IP address of the incoming request
|
package/docs/Reference/Routes.md
CHANGED
|
@@ -32,7 +32,7 @@ fastify.route(options)
|
|
|
32
32
|
### Routes options
|
|
33
33
|
<a id="options"></a>
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
*`method`: currently it supports `'DELETE'`, `'GET'`, `'HEAD'`, `'PATCH'`,
|
|
36
36
|
`'POST'`, `'PUT'` and `'OPTIONS'`. It could also be an array of methods.
|
|
37
37
|
* `url`: the path of the URL to match this route (alias: `path`).
|
|
38
38
|
* `schema`: an object containing the schemas for the request and response. They
|
|
@@ -54,6 +54,7 @@ fastify.route(options)
|
|
|
54
54
|
option, make sure to define it before the `GET` route.
|
|
55
55
|
* `attachValidation`: attach `validationError` to request, if there is a schema
|
|
56
56
|
validation error, instead of sending the error to the error handler.
|
|
57
|
+
The default [error format](https://ajv.js.org/api.html#error-objects) is the Ajv one.
|
|
57
58
|
* `onRequest(request, reply, done)`: a [function](./Hooks.md#onrequest) as soon
|
|
58
59
|
that a request is received, it could also be an array of functions.
|
|
59
60
|
* `preParsing(request, reply, done)`: a [function](./Hooks.md#preparsing) called
|
|
@@ -280,11 +281,14 @@ As you can see, we are not calling `reply.send` to send back the data to the
|
|
|
280
281
|
user. You just need to return the body and you are done!
|
|
281
282
|
|
|
282
283
|
If you need it you can also send back the data to the user with `reply.send`.
|
|
284
|
+
In this case do not forget to `return reply` or `await reply` in your `async`
|
|
285
|
+
handler or you will introduce a race condition in certain situations.
|
|
286
|
+
|
|
283
287
|
```js
|
|
284
288
|
fastify.get('/', options, async function (request, reply) {
|
|
285
289
|
var data = await getData()
|
|
286
290
|
var processed = await processData(data)
|
|
287
|
-
reply.send(processed)
|
|
291
|
+
return reply.send(processed)
|
|
288
292
|
})
|
|
289
293
|
```
|
|
290
294
|
|
|
@@ -316,24 +320,27 @@ fastify.get('/', options, async function (request, reply) {
|
|
|
316
320
|
first one that happens takes precedence, the second value will be discarded,
|
|
317
321
|
and a *warn* log will also be emitted because you tried to send a response
|
|
318
322
|
twice.
|
|
323
|
+
* Calling `reply.send()` outside of the promise is possible, but requires
|
|
324
|
+
special attention. For more details read
|
|
325
|
+
[promise-resolution](#promise-resolution).
|
|
319
326
|
* You cannot return `undefined`. For more details read
|
|
320
327
|
[promise-resolution](#promise-resolution).
|
|
321
328
|
|
|
322
329
|
### Promise resolution
|
|
323
330
|
<a id="promise-resolution"></a>
|
|
324
331
|
|
|
325
|
-
If your handler is an `async` function or returns a promise, you should be aware
|
|
326
|
-
|
|
327
|
-
control-flow.
|
|
328
|
-
|
|
332
|
+
If your handler is an `async` function or returns a promise, you should be aware of
|
|
333
|
+
a special behaviour which is necessary to support the callback and promise
|
|
334
|
+
control-flow. When the handler's promise is resolved, the reply will be
|
|
335
|
+
automatically sent with its value unless you explicitly await or return `reply`
|
|
336
|
+
in your handler.
|
|
329
337
|
|
|
330
|
-
1. If you want to use `async/await` or promises but
|
|
331
|
-
|
|
332
|
-
- **Do not** `return` any value.
|
|
338
|
+
1. If you want to use `async/await` or promises but respond a value with `reply.send`:
|
|
339
|
+
- **Do** `return reply` / `await reply`.
|
|
333
340
|
- **Do not** forget to call `reply.send`.
|
|
334
341
|
2. If you want to use `async/await` or promises:
|
|
335
342
|
- **Do not** use `reply.send`.
|
|
336
|
-
- **Do
|
|
343
|
+
- **Do** return the value that you want to send.
|
|
337
344
|
|
|
338
345
|
In this way, we can support both `callback-style` and `async-await`, with the
|
|
339
346
|
minimum trade-off. In spite of so much freedom we highly recommend to go with
|