fastify 3.27.4 → 4.0.0-alpha.3
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/.taprc +3 -0
- package/README.md +7 -7
- package/build/build-error-serializer.js +27 -0
- package/build/build-validation.js +47 -35
- package/docs/Guides/Database.md +320 -0
- package/docs/Guides/Ecosystem.md +9 -0
- package/docs/Guides/Getting-Started.md +7 -7
- package/docs/Guides/Plugins-Guide.md +1 -1
- package/docs/Guides/Serverless.md +3 -3
- package/docs/Guides/Testing.md +2 -2
- package/docs/Migration-Guide-V4.md +12 -0
- package/docs/Reference/ContentTypeParser.md +4 -0
- package/docs/Reference/Decorators.md +2 -2
- package/docs/Reference/Encapsulation.md +2 -2
- package/docs/Reference/Errors.md +51 -6
- package/docs/Reference/HTTP2.md +3 -3
- package/docs/Reference/Hooks.md +4 -7
- package/docs/Reference/LTS.md +5 -4
- package/docs/Reference/Plugins.md +3 -3
- package/docs/Reference/Reply.md +73 -22
- package/docs/Reference/Request.md +1 -3
- package/docs/Reference/Routes.md +22 -15
- package/docs/Reference/Server.md +69 -119
- package/docs/Reference/TypeScript.md +20 -22
- package/docs/Reference/Validation-and-Serialization.md +30 -55
- package/docs/Type-Providers.md +257 -0
- package/examples/asyncawait.js +1 -1
- package/examples/benchmark/hooks-benchmark-async-await.js +1 -1
- package/examples/benchmark/hooks-benchmark.js +1 -1
- package/examples/benchmark/simple.js +1 -1
- package/examples/hooks.js +2 -2
- package/examples/http2.js +1 -1
- package/examples/https.js +1 -1
- package/examples/parser.js +13 -3
- package/examples/route-prefix.js +1 -1
- package/examples/shared-schema.js +1 -1
- package/examples/simple-stream.js +18 -0
- package/examples/simple.js +1 -1
- package/examples/simple.mjs +1 -1
- package/examples/typescript-server.ts +1 -1
- package/examples/use-plugin.js +1 -1
- package/fastify.d.ts +34 -22
- package/fastify.js +40 -36
- 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 +51 -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 +121 -175
- 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 +242 -116
- package/lib/symbols.js +5 -3
- package/lib/validation.js +11 -9
- package/lib/warnings.js +4 -12
- package/lib/wrapThenable.js +4 -11
- package/package.json +37 -39
- package/test/404s.test.js +258 -125
- package/test/500s.test.js +3 -3
- package/test/als.test.js +1 -1
- package/test/async-await.test.js +20 -76
- package/test/bodyLimit.test.js +1 -1
- package/test/build-certificate.js +6 -7
- package/test/case-insensitive.test.js +4 -4
- package/test/close-pipelining.test.js +2 -2
- package/test/close.test.js +11 -11
- 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 +1 -66
- package/test/custom-parser.test.js +92 -159
- package/test/custom-querystring-parser.test.js +3 -3
- package/test/decorator.test.js +11 -13
- package/test/delete.test.js +6 -6
- 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/genReqId.test.js +1 -1
- package/test/get.test.js +4 -4
- package/test/handler-context.test.js +2 -2
- package/test/head.test.js +1 -1
- package/test/helper.js +19 -4
- package/test/hooks-async.test.js +15 -48
- package/test/hooks.on-ready.test.js +10 -5
- package/test/hooks.test.js +78 -119
- package/test/http2/closing.test.js +10 -16
- package/test/http2/constraint.test.js +1 -1
- package/test/http2/head.test.js +1 -1
- package/test/http2/plain.test.js +1 -1
- package/test/http2/secure-with-fallback.test.js +1 -1
- package/test/http2/secure.test.js +1 -1
- package/test/http2/unknown-http-method.test.js +4 -10
- package/test/https/custom-https-server.test.js +12 -6
- package/test/https/https.test.js +1 -1
- package/test/input-validation.js +3 -3
- package/test/internals/handleRequest.test.js +6 -43
- package/test/internals/initialConfig.test.js +41 -12
- package/test/internals/logger.test.js +2 -2
- package/test/internals/reply.test.js +317 -48
- package/test/internals/request.test.js +13 -7
- package/test/internals/server.test.js +88 -0
- package/test/listen.deprecated.test.js +202 -0
- package/test/listen.test.js +140 -145
- package/test/logger.test.js +82 -42
- package/test/maxRequestsPerSocket.test.js +8 -6
- package/test/middleware.test.js +2 -25
- package/test/nullable-validation.test.js +53 -16
- package/test/output-validation.test.js +1 -1
- package/test/plugin.test.js +47 -21
- package/test/pretty-print.test.js +22 -10
- package/test/promises.test.js +1 -1
- package/test/proto-poisoning.test.js +6 -6
- package/test/register.test.js +3 -3
- package/test/reply-error.test.js +126 -15
- package/test/reply-trailers.test.js +270 -0
- package/test/request-error.test.js +3 -6
- package/test/route-hooks.test.js +18 -18
- package/test/route-prefix.test.js +2 -1
- package/test/route.test.js +206 -22
- package/test/router-options.test.js +2 -2
- package/test/schema-examples.test.js +11 -5
- package/test/schema-feature.test.js +25 -20
- package/test/schema-serialization.test.js +9 -9
- package/test/schema-special-usage.test.js +5 -153
- package/test/schema-validation.test.js +9 -9
- package/test/skip-reply-send.test.js +2 -2
- package/test/stream.test.js +82 -23
- package/test/throw.test.js +8 -5
- package/test/trust-proxy.test.js +6 -6
- package/test/type-provider.test.js +20 -0
- package/test/types/fastify.test-d.ts +10 -18
- package/test/types/hooks.test-d.ts +61 -5
- package/test/types/import.js +2 -0
- package/test/types/import.ts +1 -0
- package/test/types/instance.test-d.ts +68 -17
- package/test/types/logger.test-d.ts +44 -15
- package/test/types/reply.test-d.ts +2 -1
- package/test/types/request.test-d.ts +71 -1
- 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 +424 -0
- package/test/url-rewriting.test.js +3 -3
- package/test/validation-error-handling.test.js +8 -8
- package/test/versioned-routes.test.js +30 -18
- package/test/wrapThenable.test.js +7 -6
- package/types/content-type-parser.d.ts +17 -8
- package/types/hooks.d.ts +182 -85
- package/types/instance.d.ts +286 -118
- package/types/logger.d.ts +18 -104
- package/types/plugin.d.ts +10 -4
- package/types/reply.d.ts +18 -12
- package/types/request.d.ts +13 -8
- package/types/route.d.ts +62 -34
- 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
|
@@ -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
|
|
@@ -265,7 +265,7 @@ server.decorateReply('view', function (template, args) {
|
|
|
265
265
|
// Another rendering engine
|
|
266
266
|
})
|
|
267
267
|
|
|
268
|
-
server.listen(3000)
|
|
268
|
+
server.listen({ port: 3000 })
|
|
269
269
|
```
|
|
270
270
|
|
|
271
271
|
|
|
@@ -291,7 +291,7 @@ server.register(async function (server, opts) {
|
|
|
291
291
|
})
|
|
292
292
|
}, { prefix: '/bar' })
|
|
293
293
|
|
|
294
|
-
server.listen(3000)
|
|
294
|
+
server.listen({ port: 3000 })
|
|
295
295
|
```
|
|
296
296
|
|
|
297
297
|
### Getters and Setters
|
|
@@ -94,7 +94,7 @@ fastify.register(async function publicContext (childServer) {
|
|
|
94
94
|
})
|
|
95
95
|
})
|
|
96
96
|
|
|
97
|
-
fastify.listen(8000)
|
|
97
|
+
fastify.listen({ port: 8000 })
|
|
98
98
|
```
|
|
99
99
|
|
|
100
100
|
The above server example shows all of the encapsulation concepts outlined in the
|
|
@@ -180,7 +180,7 @@ fastify.register(async function publicContext (childServer) {
|
|
|
180
180
|
}
|
|
181
181
|
})
|
|
182
182
|
|
|
183
|
-
fastify.listen(8000)
|
|
183
|
+
fastify.listen({ port: 8000 })
|
|
184
184
|
```
|
|
185
185
|
|
|
186
186
|
Restarting the server and re-issuing the requests for `/two` and `/three`:
|
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/HTTP2.md
CHANGED
|
@@ -31,7 +31,7 @@ fastify.get('/', function (request, reply) {
|
|
|
31
31
|
reply.code(200).send({ hello: 'world' })
|
|
32
32
|
})
|
|
33
33
|
|
|
34
|
-
fastify.listen(3000)
|
|
34
|
+
fastify.listen({ port: 3000 })
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
ALPN negotiation allows support for both HTTPS and HTTP/2 over the same socket.
|
|
@@ -59,7 +59,7 @@ fastify.get('/', function (request, reply) {
|
|
|
59
59
|
reply.code(200).send({ hello: 'world' })
|
|
60
60
|
})
|
|
61
61
|
|
|
62
|
-
fastify.listen(3000)
|
|
62
|
+
fastify.listen({ port: 3000 })
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
You can test your new server with:
|
|
@@ -84,7 +84,7 @@ fastify.get('/', function (request, reply) {
|
|
|
84
84
|
reply.code(200).send({ hello: 'world' })
|
|
85
85
|
})
|
|
86
86
|
|
|
87
|
-
fastify.listen(3000)
|
|
87
|
+
fastify.listen({ port: 3000 })
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
You can test your new server with:
|
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.
|
|
@@ -124,7 +124,7 @@ fastify.ready(err => console.log(err))
|
|
|
124
124
|
|
|
125
125
|
// `listen` is a special ready,
|
|
126
126
|
// so it behaves in the same way
|
|
127
|
-
fastify.listen(3000, (err, address) => {
|
|
127
|
+
fastify.listen({ port: 3000 }, (err, address) => {
|
|
128
128
|
if (err) console.log(err)
|
|
129
129
|
})
|
|
130
130
|
```
|
|
@@ -142,7 +142,7 @@ await fastify.after()
|
|
|
142
142
|
|
|
143
143
|
await fastify.ready()
|
|
144
144
|
|
|
145
|
-
await fastify.listen(3000)
|
|
145
|
+
await fastify.listen({ port: 3000 })
|
|
146
146
|
```
|
|
147
147
|
|
|
148
148
|
#### ESM support
|
|
@@ -158,7 +158,7 @@ const fastify = Fastify()
|
|
|
158
158
|
|
|
159
159
|
fastify.register(import('./plugin.mjs'))
|
|
160
160
|
|
|
161
|
-
fastify.listen(3000, console.log)
|
|
161
|
+
fastify.listen({ port: 3000 }, console.log)
|
|
162
162
|
|
|
163
163
|
|
|
164
164
|
// plugin.mjs
|
package/docs/Reference/Reply.md
CHANGED
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
- [.getHeaders()](#getheaders)
|
|
14
14
|
- [.removeHeader(key)](#removeheaderkey)
|
|
15
15
|
- [.hasHeader(key)](#hasheaderkey)
|
|
16
|
+
- [.trailer(key, function)](#trailerkey-function)
|
|
17
|
+
- [.hasTrailer(key)](#hastrailerkey)
|
|
18
|
+
- [.removeTrailer(key)](#removetrailerkey)
|
|
16
19
|
- [.redirect([code,] dest)](#redirectcode--dest)
|
|
17
20
|
- [.callNotFound()](#callnotfound)
|
|
18
21
|
- [.getResponseTime()](#getresponsetime)
|
|
@@ -47,6 +50,9 @@ object that exposes the following functions and properties:
|
|
|
47
50
|
- `.getHeaders()` - Gets a shallow copy of all current response headers.
|
|
48
51
|
- `.removeHeader(key)` - Remove the value of a previously set header.
|
|
49
52
|
- `.hasHeader(name)` - Determine if a header has been set.
|
|
53
|
+
- `.trailer(key, function)` - Sets a response trailer.
|
|
54
|
+
- `.hasTrailer(key)` - Determine if a trailer has been set.
|
|
55
|
+
- `.removeTrailer(key)` - Remove the value of a previously set trailer.
|
|
50
56
|
- `.type(value)` - Sets the header `Content-Type`.
|
|
51
57
|
- `.redirect([code,] dest)` - Redirect to the specified url, the status code is
|
|
52
58
|
optional (default to `302`).
|
|
@@ -59,12 +65,10 @@ object that exposes the following functions and properties:
|
|
|
59
65
|
buffer, JSON, stream, or an Error object.
|
|
60
66
|
- `.sent` - A boolean value that you can use if you need to know if `send` has
|
|
61
67
|
already been called.
|
|
68
|
+
- `.hijack()` - interrupt the normal request lifecycle.
|
|
62
69
|
- `.raw` - The
|
|
63
70
|
[`http.ServerResponse`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_class_http_serverresponse)
|
|
64
71
|
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
72
|
- `.log` - The logger instance of the incoming request.
|
|
69
73
|
- `.request` - The incoming request.
|
|
70
74
|
- `.context` - Access the [Request's context](./Request.md) property.
|
|
@@ -125,6 +129,8 @@ fastify.get('/', async function (req, rep) {
|
|
|
125
129
|
Sets a response header. If the value is omitted or undefined, it is coerced to
|
|
126
130
|
`''`.
|
|
127
131
|
|
|
132
|
+
> 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.
|
|
133
|
+
|
|
128
134
|
For more information, see
|
|
129
135
|
[`http.ServerResponse#setHeader`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_response_setheader_name_value).
|
|
130
136
|
|
|
@@ -199,12 +205,57 @@ reply.getHeader('x-foo') // undefined
|
|
|
199
205
|
|
|
200
206
|
Returns a boolean indicating if the specified header has been set.
|
|
201
207
|
|
|
208
|
+
### .trailer(key, function)
|
|
209
|
+
<a id="trailer"></a>
|
|
210
|
+
|
|
211
|
+
Sets a response trailer. Trailer usually used when you want some header that require heavy resources to be sent after the `data`, for example `Server-Timing`, `Etag`. It can ensure the client get the response data as soon as possible.
|
|
212
|
+
|
|
213
|
+
*Note: The header `Transfer-Encoding: chunked` will be added once you use the trailer. It is a hard requipment for using trailer in Node.js.*
|
|
214
|
+
|
|
215
|
+
*Note: Currently, the computation function only supports synchronous function. That means `async-await` and `promise` are not supported.*
|
|
216
|
+
|
|
217
|
+
```js
|
|
218
|
+
reply.trailer('server-timing', function() {
|
|
219
|
+
return 'db;dur=53, app;dur=47.2'
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
const { createHash } = require('crypto')
|
|
223
|
+
// trailer function also recieve two argument
|
|
224
|
+
// @param {object} reply fastify reply
|
|
225
|
+
// @param {string|Buffer|null} payload payload that already sent, note that it will be null when stream is sent
|
|
226
|
+
reply.trailer('content-md5', function(reply, payload) {
|
|
227
|
+
const hash = createHash('md5')
|
|
228
|
+
hash.update(payload)
|
|
229
|
+
return hash.disgest('hex')
|
|
230
|
+
})
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### .hasTrailer(key)
|
|
234
|
+
<a id="hasTrailer"></a>
|
|
235
|
+
|
|
236
|
+
Returns a boolean indicating if the specified trailer has been set.
|
|
237
|
+
|
|
238
|
+
### .removeTrailer(key)
|
|
239
|
+
<a id="removeTrailer"></a>
|
|
240
|
+
|
|
241
|
+
Remove the value of a previously set trailer.
|
|
242
|
+
```js
|
|
243
|
+
reply.trailer('server-timing', function() {
|
|
244
|
+
return 'db;dur=53, app;dur=47.2'
|
|
245
|
+
})
|
|
246
|
+
reply.removeTrailer('server-timing')
|
|
247
|
+
reply.getTrailer('server-timing') // undefined
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
|
|
202
251
|
### .redirect([code ,] dest)
|
|
203
252
|
<a id="redirect"></a>
|
|
204
253
|
|
|
205
254
|
Redirects a request to the specified URL, the status code is optional, default
|
|
206
255
|
to `302` (if status code is not already set by calling `code`).
|
|
207
256
|
|
|
257
|
+
> 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.
|
|
258
|
+
|
|
208
259
|
Example (no `reply.code()` call) sets status code to `302` and redirects to
|
|
209
260
|
`/home`
|
|
210
261
|
```js
|
|
@@ -259,6 +310,7 @@ Sets the content type for the response. This is a shortcut for
|
|
|
259
310
|
```js
|
|
260
311
|
reply.type('text/html')
|
|
261
312
|
```
|
|
313
|
+
If the `Content-Type` has a JSON subtype, and the charset parameter is not set, `utf-8` will be used as the charset by default.
|
|
262
314
|
|
|
263
315
|
### .serializer(func)
|
|
264
316
|
<a id="serializer"></a>
|
|
@@ -315,39 +367,38 @@ Another example of the misuse of `Reply.raw` is explained in
|
|
|
315
367
|
|
|
316
368
|
As the name suggests, `.sent` is a property to indicate if a response has been
|
|
317
369
|
sent via `reply.send()`.
|
|
370
|
+
It will also be `true` in case `reply.hijack()` was used.
|
|
318
371
|
|
|
319
372
|
In case a route handler is defined as an async function or it returns a promise,
|
|
320
|
-
it is possible to
|
|
373
|
+
it is possible to call `reply.hijack()` to indicate that the automatic
|
|
321
374
|
invocation of `reply.send()` once the handler promise resolve should be skipped.
|
|
322
|
-
By
|
|
375
|
+
By calling `reply.hijack()`, an application claims full responsibility for
|
|
323
376
|
the low-level request and response. Moreover, hooks will not be invoked.
|
|
324
377
|
|
|
325
|
-
|
|
378
|
+
*Modifying the `.sent` property directly is deprecated. Please use the aformentioned
|
|
379
|
+
`.hijack()` method to achieve the same effect.*
|
|
380
|
+
|
|
381
|
+
<a name="hijack"></a>
|
|
382
|
+
### .hijack()
|
|
383
|
+
Sometimes you might need to halt the execution of the normal request lifecycle and
|
|
384
|
+
handle sending the response manually.
|
|
385
|
+
|
|
386
|
+
To achieve this, Fastify provides the `reply.hijack()` method that can be called
|
|
387
|
+
during the request lifecycle (At any point before `reply.send()` is called), and
|
|
388
|
+
allows you to prevent Fastify from sending the response, and from running the
|
|
389
|
+
remaining hooks (and user handler if the reply was hijacked before).
|
|
326
390
|
|
|
327
391
|
```js
|
|
328
392
|
app.get('/', (req, reply) => {
|
|
329
|
-
reply.
|
|
393
|
+
reply.hijack()
|
|
330
394
|
reply.raw.end('hello world')
|
|
331
395
|
|
|
332
396
|
return Promise.resolve('this will be skipped')
|
|
333
397
|
})
|
|
334
398
|
```
|
|
335
399
|
|
|
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
|
|
400
|
+
If `reply.raw` is used to send a response back to the user, the `onResponse`
|
|
401
|
+
hooks will still be executed.
|
|
351
402
|
|
|
352
403
|
### .send(data)
|
|
353
404
|
<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
|
|
@@ -358,7 +365,7 @@ const fastify = require('fastify')()
|
|
|
358
365
|
fastify.register(require('./routes/v1/users'), { prefix: '/v1' })
|
|
359
366
|
fastify.register(require('./routes/v2/users'), { prefix: '/v2' })
|
|
360
367
|
|
|
361
|
-
fastify.listen(3000)
|
|
368
|
+
fastify.listen({ port: 3000 })
|
|
362
369
|
```
|
|
363
370
|
|
|
364
371
|
```js
|
|
@@ -420,7 +427,7 @@ const fastify = require('fastify')({ logger: true })
|
|
|
420
427
|
fastify.register(require('./routes/user'), { logLevel: 'warn' })
|
|
421
428
|
fastify.register(require('./routes/events'), { logLevel: 'debug' })
|
|
422
429
|
|
|
423
|
-
fastify.listen(3000)
|
|
430
|
+
fastify.listen({ port: 3000 })
|
|
424
431
|
```
|
|
425
432
|
|
|
426
433
|
Or you can directly pass it to a route:
|
|
@@ -454,7 +461,7 @@ fastify.register(require('./routes/events'), {
|
|
|
454
461
|
}
|
|
455
462
|
})
|
|
456
463
|
|
|
457
|
-
fastify.listen(3000)
|
|
464
|
+
fastify.listen({ port: 3000 })
|
|
458
465
|
```
|
|
459
466
|
|
|
460
467
|
You can inherit serializers by context:
|
|
@@ -492,7 +499,7 @@ async function context1 (fastify, opts) {
|
|
|
492
499
|
})
|
|
493
500
|
}
|
|
494
501
|
|
|
495
|
-
fastify.listen(3000)
|
|
502
|
+
fastify.listen({ port: 3000 })
|
|
496
503
|
```
|
|
497
504
|
|
|
498
505
|
### Config
|
|
@@ -512,7 +519,7 @@ function handler (req, reply) {
|
|
|
512
519
|
fastify.get('/en', { config: { output: 'hello world!' } }, handler)
|
|
513
520
|
fastify.get('/it', { config: { output: 'ciao mondo!' } }, handler)
|
|
514
521
|
|
|
515
|
-
fastify.listen(3000)
|
|
522
|
+
fastify.listen({ port: 3000 })
|
|
516
523
|
```
|
|
517
524
|
|
|
518
525
|
### Constraints
|