fastify 5.2.0 → 5.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/PROJECT_CHARTER.md +7 -7
- package/README.md +65 -67
- package/SPONSORS.md +2 -0
- package/build/build-validation.js +1 -1
- package/docs/Guides/Benchmarking.md +4 -4
- package/docs/Guides/Database.md +1 -1
- package/docs/Guides/Delay-Accepting-Requests.md +10 -10
- package/docs/Guides/Ecosystem.md +5 -1
- package/docs/Guides/Fluent-Schema.md +1 -1
- package/docs/Guides/Getting-Started.md +9 -5
- package/docs/Guides/Index.md +1 -1
- package/docs/Guides/Migration-Guide-V4.md +1 -1
- package/docs/Guides/Migration-Guide-V5.md +12 -2
- package/docs/Guides/Plugins-Guide.md +6 -6
- package/docs/Guides/Serverless.md +14 -48
- package/docs/Guides/Style-Guide.md +2 -2
- package/docs/Guides/Testing.md +2 -2
- package/docs/Guides/Write-Plugin.md +2 -3
- package/docs/Reference/ContentTypeParser.md +58 -78
- package/docs/Reference/Decorators.md +50 -60
- package/docs/Reference/Encapsulation.md +28 -33
- package/docs/Reference/Errors.md +52 -53
- package/docs/Reference/HTTP2.md +7 -7
- package/docs/Reference/Hooks.md +31 -30
- package/docs/Reference/LTS.md +10 -15
- package/docs/Reference/Lifecycle.md +19 -24
- package/docs/Reference/Logging.md +59 -56
- package/docs/Reference/Middleware.md +19 -19
- package/docs/Reference/Plugins.md +55 -71
- package/docs/Reference/Principles.md +25 -30
- package/docs/Reference/Reply.md +11 -10
- package/docs/Reference/Request.md +89 -99
- package/docs/Reference/Routes.md +108 -128
- package/docs/Reference/Server.md +19 -17
- package/docs/Reference/Type-Providers.md +19 -21
- package/docs/Reference/TypeScript.md +1 -18
- package/docs/Reference/Validation-and-Serialization.md +134 -159
- package/docs/Reference/Warnings.md +22 -25
- package/fastify.js +1 -1
- package/lib/contentTypeParser.js +7 -8
- package/lib/error-handler.js +14 -12
- package/lib/errors.js +4 -0
- package/lib/headRoute.js +4 -2
- package/lib/pluginUtils.js +4 -2
- package/lib/reply.js +4 -0
- package/lib/request.js +13 -9
- package/lib/server.js +5 -0
- package/lib/validation.js +1 -1
- package/lib/warnings.js +9 -0
- package/lib/wrapThenable.js +8 -1
- package/package.json +28 -17
- package/test/build/error-serializer.test.js +2 -1
- package/test/bundler/esbuild/package.json +1 -1
- package/test/close.test.js +125 -108
- package/test/custom-parser-async.test.js +34 -36
- package/test/custom-parser.2.test.js +19 -20
- package/test/custom-parser.3.test.js +56 -45
- package/test/delete.test.js +79 -67
- package/test/genReqId.test.js +125 -174
- package/test/has-route.test.js +1 -3
- package/test/internals/content-type-parser.test.js +1 -1
- package/test/internals/errors.test.js +19 -7
- package/test/issue-4959.test.js +84 -0
- package/test/listen.1.test.js +37 -34
- package/test/listen.2.test.js +47 -40
- package/test/listen.3.test.js +28 -32
- package/test/listen.4.test.js +61 -45
- package/test/listen.5.test.js +23 -0
- package/test/nullable-validation.test.js +30 -27
- package/test/register.test.js +55 -50
- package/test/request-error.test.js +114 -94
- package/test/route-shorthand.test.js +36 -32
- package/test/server.test.js +0 -175
- package/test/stream.5.test.js +35 -33
- package/test/throw.test.js +87 -91
- package/test/toolkit.js +32 -0
- package/test/trust-proxy.test.js +23 -23
- package/test/types/instance.test-d.ts +1 -0
- package/test/upgrade.test.js +32 -30
- package/test/web-api.test.js +44 -0
- package/types/instance.d.ts +4 -0
- package/test/test-reporter.mjs +0 -68
|
@@ -3,21 +3,20 @@
|
|
|
3
3
|
## Encapsulation
|
|
4
4
|
<a id="encapsulation"></a>
|
|
5
5
|
|
|
6
|
-
A fundamental feature of Fastify is the "encapsulation context."
|
|
7
|
-
|
|
8
|
-
[
|
|
9
|
-
|
|
10
|
-
is shown in the following figure:
|
|
6
|
+
A fundamental feature of Fastify is the "encapsulation context." It governs
|
|
7
|
+
which [decorators](./Decorators.md), registered [hooks](./Hooks.md), and
|
|
8
|
+
[plugins](./Plugins.md) are available to [routes](./Routes.md). A visual
|
|
9
|
+
representation of the encapsulation context is shown in the following figure:
|
|
11
10
|
|
|
12
11
|

|
|
13
12
|
|
|
14
|
-
In the above
|
|
13
|
+
In the figure above, there are several entities:
|
|
15
14
|
|
|
16
15
|
1. The _root context_
|
|
17
16
|
2. Three _root plugins_
|
|
18
|
-
3. Two _child contexts_
|
|
17
|
+
3. Two _child contexts_, each with:
|
|
19
18
|
* Two _child plugins_
|
|
20
|
-
* One _grandchild context_
|
|
19
|
+
* One _grandchild context_, each with:
|
|
21
20
|
- Three _child plugins_
|
|
22
21
|
|
|
23
22
|
Every _child context_ and _grandchild context_ has access to the _root plugins_.
|
|
@@ -26,15 +25,14 @@ _child plugins_ registered within the containing _child context_, but the
|
|
|
26
25
|
containing _child context_ **does not** have access to the _child plugins_
|
|
27
26
|
registered within its _grandchild context_.
|
|
28
27
|
|
|
29
|
-
Given that everything in Fastify is a [plugin](./Plugins.md)
|
|
28
|
+
Given that everything in Fastify is a [plugin](./Plugins.md) except for the
|
|
30
29
|
_root context_, every "context" and "plugin" in this example is a plugin
|
|
31
|
-
that can consist of decorators, hooks, plugins, and routes.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
example is as follows:
|
|
30
|
+
that can consist of decorators, hooks, plugins, and routes. To put this
|
|
31
|
+
example into concrete terms, consider a basic scenario of a REST API server
|
|
32
|
+
with three routes: the first route (`/one`) requires authentication, the
|
|
33
|
+
second route (`/two`) does not, and the third route (`/three`) has access to
|
|
34
|
+
the same context as the second route. Using [@fastify/bearer-auth][bearer] to
|
|
35
|
+
provide authentication, the code for this example is as follows:
|
|
38
36
|
|
|
39
37
|
```js
|
|
40
38
|
'use strict'
|
|
@@ -52,9 +50,9 @@ fastify.register(async function authenticatedContext (childServer) {
|
|
|
52
50
|
handler (request, response) {
|
|
53
51
|
response.send({
|
|
54
52
|
answer: request.answer,
|
|
55
|
-
// request.foo will be undefined as it
|
|
53
|
+
// request.foo will be undefined as it is only defined in publicContext
|
|
56
54
|
foo: request.foo,
|
|
57
|
-
// request.bar will be undefined as it
|
|
55
|
+
// request.bar will be undefined as it is only defined in grandchildContext
|
|
58
56
|
bar: request.bar
|
|
59
57
|
})
|
|
60
58
|
}
|
|
@@ -71,7 +69,7 @@ fastify.register(async function publicContext (childServer) {
|
|
|
71
69
|
response.send({
|
|
72
70
|
answer: request.answer,
|
|
73
71
|
foo: request.foo,
|
|
74
|
-
// request.bar will be undefined as it
|
|
72
|
+
// request.bar will be undefined as it is only defined in grandchildContext
|
|
75
73
|
bar: request.bar
|
|
76
74
|
})
|
|
77
75
|
}
|
|
@@ -97,16 +95,16 @@ fastify.register(async function publicContext (childServer) {
|
|
|
97
95
|
fastify.listen({ port: 8000 })
|
|
98
96
|
```
|
|
99
97
|
|
|
100
|
-
The
|
|
98
|
+
The server example above demonstrates the encapsulation concepts from the
|
|
101
99
|
original diagram:
|
|
102
100
|
|
|
103
101
|
1. Each _child context_ (`authenticatedContext`, `publicContext`, and
|
|
104
|
-
`grandchildContext`) has access to the `answer` request decorator defined in
|
|
105
|
-
the _root context_.
|
|
102
|
+
`grandchildContext`) has access to the `answer` request decorator defined in
|
|
103
|
+
the _root context_.
|
|
106
104
|
2. Only the `authenticatedContext` has access to the `@fastify/bearer-auth`
|
|
107
|
-
plugin.
|
|
105
|
+
plugin.
|
|
108
106
|
3. Both the `publicContext` and `grandchildContext` have access to the `foo`
|
|
109
|
-
request decorator.
|
|
107
|
+
request decorator.
|
|
110
108
|
4. Only the `grandchildContext` has access to the `bar` request decorator.
|
|
111
109
|
|
|
112
110
|
To see this, start the server and issue requests:
|
|
@@ -125,16 +123,13 @@ To see this, start the server and issue requests:
|
|
|
125
123
|
## Sharing Between Contexts
|
|
126
124
|
<a id="shared-context"></a>
|
|
127
125
|
|
|
128
|
-
|
|
129
|
-
contexts
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
[fastify-plugin][fastify-plugin] such that anything registered in a descendent
|
|
133
|
-
context is available to the containing parent context.
|
|
126
|
+
Each context in the prior example inherits _only_ from its parent contexts. Parent
|
|
127
|
+
contexts cannot access entities within their descendant contexts. If needed,
|
|
128
|
+
encapsulation can be broken using [fastify-plugin][fastify-plugin], making
|
|
129
|
+
anything registered in a descendant context available to the parent context.
|
|
134
130
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
rewritten as:
|
|
131
|
+
To allow `publicContext` access to the `bar` decorator in `grandchildContext`,
|
|
132
|
+
rewrite the code as follows:
|
|
138
133
|
|
|
139
134
|
```js
|
|
140
135
|
'use strict'
|
package/docs/Reference/Errors.md
CHANGED
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
- [FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED](#fst_err_log_logger_and_logger_instance_provided)
|
|
50
50
|
- [FST_ERR_REP_INVALID_PAYLOAD_TYPE](#fst_err_rep_invalid_payload_type)
|
|
51
51
|
- [FST_ERR_REP_RESPONSE_BODY_CONSUMED](#fst_err_rep_response_body_consumed)
|
|
52
|
+
- [FST_ERR_REP_READABLE_STREAM_LOCKED](#fst_err_rep_readable_stream_locked)
|
|
52
53
|
- [FST_ERR_REP_ALREADY_SENT](#fst_err_rep_already_sent)
|
|
53
54
|
- [FST_ERR_REP_SENT_VALUE](#fst_err_rep_sent_value)
|
|
54
55
|
- [FST_ERR_SEND_INSIDE_ONERR](#fst_err_send_inside_onerr)
|
|
@@ -101,8 +102,8 @@
|
|
|
101
102
|
<a id="error-handling"></a>
|
|
102
103
|
|
|
103
104
|
#### Uncaught Errors
|
|
104
|
-
In Node.js, uncaught errors
|
|
105
|
-
|
|
105
|
+
In Node.js, uncaught errors can cause memory leaks, file descriptor leaks, and
|
|
106
|
+
other major production issues.
|
|
106
107
|
[Domains](https://nodejs.org/en/docs/guides/domain-postmortem/) were a failed
|
|
107
108
|
attempt to fix this.
|
|
108
109
|
|
|
@@ -111,29 +112,28 @@ way to deal with them is to
|
|
|
111
112
|
[crash](https://nodejs.org/api/process.html#process_warning_using_uncaughtexception_correctly).
|
|
112
113
|
|
|
113
114
|
#### Catching Errors In Promises
|
|
114
|
-
|
|
115
|
+
When using promises, attach a `.catch()` handler synchronously.
|
|
115
116
|
|
|
116
117
|
### Errors In Fastify
|
|
117
|
-
Fastify follows an all-or-nothing approach and aims to be lean and optimal
|
|
118
|
-
|
|
119
|
-
are handled properly.
|
|
118
|
+
Fastify follows an all-or-nothing approach and aims to be lean and optimal. The
|
|
119
|
+
developer is responsible for ensuring errors are handled properly.
|
|
120
120
|
|
|
121
121
|
#### Errors In Input Data
|
|
122
|
-
Most errors
|
|
123
|
-
|
|
122
|
+
Most errors result from unexpected input data, so it is recommended to
|
|
123
|
+
[validate input data against a JSON schema](./Validation-and-Serialization.md).
|
|
124
124
|
|
|
125
125
|
#### Catching Uncaught Errors In Fastify
|
|
126
|
-
Fastify tries to catch as many uncaught errors as
|
|
126
|
+
Fastify tries to catch as many uncaught errors as possible without hindering
|
|
127
127
|
performance. This includes:
|
|
128
128
|
|
|
129
129
|
1. synchronous routes, e.g. `app.get('/', () => { throw new Error('kaboom') })`
|
|
130
130
|
2. `async` routes, e.g. `app.get('/', async () => { throw new Error('kaboom')
|
|
131
131
|
})`
|
|
132
132
|
|
|
133
|
-
|
|
134
|
-
error handler
|
|
133
|
+
In both cases, the error will be caught safely and routed to Fastify's default
|
|
134
|
+
error handler, resulting in a generic `500 Internal Server Error` response.
|
|
135
135
|
|
|
136
|
-
To customize this behavior
|
|
136
|
+
To customize this behavior, use
|
|
137
137
|
[`setErrorHandler`](./Server.md#seterrorhandler).
|
|
138
138
|
|
|
139
139
|
### Errors In Fastify Lifecycle Hooks And A Custom Error Handler
|
|
@@ -143,52 +143,50 @@ From the [Hooks documentation](./Hooks.md#manage-errors-from-a-hook):
|
|
|
143
143
|
> `done()` and Fastify will automatically close the request and send the
|
|
144
144
|
> appropriate error code to the user.
|
|
145
145
|
|
|
146
|
-
When a custom error handler
|
|
147
|
-
[`setErrorHandler`](./Server.md#seterrorhandler),
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
plugin's context.
|
|
146
|
+
When a custom error handler is defined through
|
|
147
|
+
[`setErrorHandler`](./Server.md#seterrorhandler), it will receive the error
|
|
148
|
+
passed to the `done()` callback or through other supported automatic error
|
|
149
|
+
handling mechanisms. If `setErrorHandler` is used multiple times, the error will
|
|
150
|
+
be routed to the most precedent handler within the error
|
|
151
|
+
[encapsulation context](./Encapsulation.md). Error handlers are fully
|
|
152
|
+
encapsulated, so a `setErrorHandler` call within a plugin will limit the error
|
|
153
|
+
handler to that plugin's context.
|
|
155
154
|
|
|
156
155
|
The root error handler is Fastify's generic error handler. This error handler
|
|
157
156
|
will use the headers and status code in the `Error` object, if they exist. The
|
|
158
157
|
headers and status code will not be automatically set if a custom error handler
|
|
159
158
|
is provided.
|
|
160
159
|
|
|
161
|
-
|
|
160
|
+
The following should be considered when using a custom error handler:
|
|
162
161
|
|
|
163
|
-
-
|
|
164
|
-
handlers](./Reply.md#senddata)
|
|
162
|
+
- `reply.send(data)` behaves as in [regular route handlers](./Reply.md#senddata)
|
|
165
163
|
- objects are serialized, triggering the `preSerialization` lifecycle hook if
|
|
166
|
-
|
|
167
|
-
- strings, buffers, and streams are sent to the client
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
-
|
|
171
|
-
|
|
172
|
-
- `onError` hook will be triggered once
|
|
173
|
-
-
|
|
174
|
-
internally monitors
|
|
175
|
-
thrown in the reply phases of the lifecycle
|
|
176
|
-
|
|
177
|
-
When
|
|
178
|
-
|
|
179
|
-
error handlers.
|
|
180
|
-
|
|
181
|
-
If a plugin's error handler re-throws an error
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
To ensure consistent error handling,
|
|
188
|
-
`
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
164
|
+
defined
|
|
165
|
+
- strings, buffers, and streams are sent to the client with appropriate headers
|
|
166
|
+
(no serialization)
|
|
167
|
+
|
|
168
|
+
- Throwing a new error in a custom error handler will call the parent
|
|
169
|
+
`errorHandler`.
|
|
170
|
+
- The `onError` hook will be triggered once for the first error thrown
|
|
171
|
+
- An error will not be triggered twice from a lifecycle hook. Fastify
|
|
172
|
+
internally monitors error invocation to avoid infinite loops for errors
|
|
173
|
+
thrown in the reply phases of the lifecycle (those after the route handler)
|
|
174
|
+
|
|
175
|
+
When using Fastify's custom error handling through
|
|
176
|
+
[`setErrorHandler`](./Server.md#seterrorhandler), be aware of how errors are
|
|
177
|
+
propagated between custom and default error handlers.
|
|
178
|
+
|
|
179
|
+
If a plugin's error handler re-throws an error that is not an instance of
|
|
180
|
+
[Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error),
|
|
181
|
+
it will not propagate to the parent context error handler. Instead, it will be
|
|
182
|
+
caught by the default error handler. This can be seen in the `/bad` route of the
|
|
183
|
+
example below.
|
|
184
|
+
|
|
185
|
+
To ensure consistent error handling, throw instances of `Error`. For example,
|
|
186
|
+
replace `throw 'foo'` with `throw new Error('foo')` in the `/bad` route to
|
|
187
|
+
ensure errors propagate through the custom error handling chain as intended.
|
|
188
|
+
This practice helps avoid potential pitfalls when working with custom error
|
|
189
|
+
handling in Fastify.
|
|
192
190
|
|
|
193
191
|
For example:
|
|
194
192
|
```js
|
|
@@ -241,7 +239,7 @@ You can access `errorCodes` for mapping:
|
|
|
241
239
|
// ESM
|
|
242
240
|
import { errorCodes } from 'fastify'
|
|
243
241
|
|
|
244
|
-
//
|
|
242
|
+
// CommonJS
|
|
245
243
|
const errorCodes = require('fastify').errorCodes
|
|
246
244
|
```
|
|
247
245
|
|
|
@@ -266,7 +264,7 @@ fastify.setErrorHandler(function (error, request, reply) {
|
|
|
266
264
|
// Send error response
|
|
267
265
|
reply.status(500).send({ ok: false })
|
|
268
266
|
} else {
|
|
269
|
-
//
|
|
267
|
+
// Fastify will use parent error handler to handle this
|
|
270
268
|
reply.send(error)
|
|
271
269
|
}
|
|
272
270
|
})
|
|
@@ -281,7 +279,7 @@ fastify.listen({ port: 3000 }, function (err, address) {
|
|
|
281
279
|
})
|
|
282
280
|
```
|
|
283
281
|
|
|
284
|
-
Below is a table with all the error codes
|
|
282
|
+
Below is a table with all the error codes used by Fastify.
|
|
285
283
|
|
|
286
284
|
| Code | Description | How to solve | Discussion |
|
|
287
285
|
|------|-------------|--------------|------------|
|
|
@@ -321,6 +319,7 @@ Below is a table with all the error codes that Fastify uses.
|
|
|
321
319
|
| <a id="fst_err_log_logger_and_logger_instance_provided">FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED</a> | You cannot provide both `'logger'` and `'loggerInstance'`. | Please provide only one option. | [#5020](https://github.com/fastify/fastify/pull/5020) |
|
|
322
320
|
| <a id="fst_err_rep_invalid_payload_type">FST_ERR_REP_INVALID_PAYLOAD_TYPE</a> | Reply payload can be either a `string` or a `Buffer`. | Use a `string` or a `Buffer` for the payload. | [#1168](https://github.com/fastify/fastify/pull/1168) |
|
|
323
321
|
| <a id="fst_err_rep_response_body_consumed">FST_ERR_REP_RESPONSE_BODY_CONSUMED</a> | Using `Response` as reply payload, but the body is being consumed. | Make sure you don't consume the `Response.body` | [#5286](https://github.com/fastify/fastify/pull/5286) |
|
|
322
|
+
| <a id="fst_err_rep_readable_stream_locked">FST_ERR_REP_READABLE_STREAM_LOCKED</a> | Using `ReadableStream` as reply payload, but locked with another reader. | Make sure you don't call the `Readable.getReader` before sending or release lock with `reader.releaseLock()` before sending. | [#5920](https://github.com/fastify/fastify/pull/5920) |
|
|
324
323
|
| <a id="fst_err_rep_already_sent">FST_ERR_REP_ALREADY_SENT</a> | A response was already sent. | - | [#1336](https://github.com/fastify/fastify/pull/1336) |
|
|
325
324
|
| <a id="fst_err_rep_sent_value">FST_ERR_REP_SENT_VALUE</a> | The only possible value for `reply.sent` is `true`. | - | [#1336](https://github.com/fastify/fastify/pull/1336) |
|
|
326
325
|
| <a id="fst_err_send_inside_onerr">FST_ERR_SEND_INSIDE_ONERR</a> | You cannot use `send` inside the `onError` hook. | - | [#1348](https://github.com/fastify/fastify/pull/1348) |
|
package/docs/Reference/HTTP2.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
## HTTP2
|
|
4
4
|
|
|
5
|
-
_Fastify_ supports HTTP2 over
|
|
5
|
+
_Fastify_ supports HTTP2 over HTTPS (h2) or plaintext (h2c).
|
|
6
6
|
|
|
7
7
|
Currently, none of the HTTP2-specific APIs are available through _Fastify_, but
|
|
8
|
-
Node's `req` and `res` can be accessed through
|
|
9
|
-
|
|
8
|
+
Node's `req` and `res` can be accessed through the `Request` and `Reply`
|
|
9
|
+
interfaces. PRs are welcome.
|
|
10
10
|
|
|
11
11
|
### Secure (HTTPS)
|
|
12
12
|
|
|
@@ -61,7 +61,7 @@ fastify.get('/', function (request, reply) {
|
|
|
61
61
|
fastify.listen({ port: 3000 })
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
Test the new server with:
|
|
65
65
|
|
|
66
66
|
```
|
|
67
67
|
$ npx h2url https://localhost:3000
|
|
@@ -69,8 +69,8 @@ $ npx h2url https://localhost:3000
|
|
|
69
69
|
|
|
70
70
|
### Plain or insecure
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
For microservices, HTTP2 can connect in plain text, but this is not
|
|
73
|
+
supported by browsers.
|
|
74
74
|
|
|
75
75
|
```js
|
|
76
76
|
'use strict'
|
|
@@ -86,7 +86,7 @@ fastify.get('/', function (request, reply) {
|
|
|
86
86
|
fastify.listen({ port: 3000 })
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
Test the new server with:
|
|
90
90
|
|
|
91
91
|
```
|
|
92
92
|
$ npx h2url http://localhost:3000
|
package/docs/Reference/Hooks.md
CHANGED
|
@@ -34,9 +34,9 @@ are Request/Reply hooks and application hooks:
|
|
|
34
34
|
- [Using Hooks to Inject Custom Properties](#using-hooks-to-inject-custom-properties)
|
|
35
35
|
- [Diagnostics Channel Hooks](#diagnostics-channel-hooks)
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
returning a `Promise`. If you do invoke a `done` callback in this situation
|
|
39
|
-
unexpected behavior may occur, e.g. duplicate invocation of handlers.
|
|
37
|
+
> 🛈 Note: The `done` callback is not available when using `async`/`await` or
|
|
38
|
+
> returning a `Promise`. If you do invoke a `done` callback in this situation
|
|
39
|
+
> unexpected behavior may occur, e.g. duplicate invocation of handlers.
|
|
40
40
|
|
|
41
41
|
## Request/Reply Hooks
|
|
42
42
|
|
|
@@ -68,9 +68,9 @@ fastify.addHook('onRequest', async (request, reply) => {
|
|
|
68
68
|
})
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
`undefined`, because the body parsing happens before the
|
|
73
|
-
[preValidation](#prevalidation) hook.
|
|
71
|
+
> 🛈 Note: In the [onRequest](#onrequest) hook, `request.body` will always be
|
|
72
|
+
> `undefined`, because the body parsing happens before the
|
|
73
|
+
> [preValidation](#prevalidation) hook.
|
|
74
74
|
|
|
75
75
|
### preParsing
|
|
76
76
|
|
|
@@ -98,17 +98,17 @@ fastify.addHook('preParsing', async (request, reply, payload) => {
|
|
|
98
98
|
})
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
`undefined`, because the body parsing happens before the
|
|
103
|
-
[preValidation](#prevalidation) hook.
|
|
101
|
+
> 🛈 Note: In the [preParsing](#preparsing) hook, `request.body` will always be
|
|
102
|
+
> `undefined`, because the body parsing happens before the
|
|
103
|
+
> [preValidation](#prevalidation) hook.
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
returned stream. This property is used to correctly match the request payload
|
|
107
|
-
with the `Content-Length` header value. Ideally, this property should be updated
|
|
108
|
-
on each received chunk.
|
|
105
|
+
> 🛈 Note: You should also add a `receivedEncodedLength` property to the
|
|
106
|
+
> returned stream. This property is used to correctly match the request payload
|
|
107
|
+
> with the `Content-Length` header value. Ideally, this property should be updated
|
|
108
|
+
> on each received chunk.
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
set in [`bodyLimit`](./Server.md#bodylimit) option.
|
|
110
|
+
> 🛈 Note: The size of the returned stream is checked to not exceed the limit
|
|
111
|
+
> set in [`bodyLimit`](./Server.md#bodylimit) option.
|
|
112
112
|
|
|
113
113
|
### preValidation
|
|
114
114
|
|
|
@@ -166,8 +166,8 @@ fastify.addHook('preSerialization', async (request, reply, payload) => {
|
|
|
166
166
|
})
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
-
Note:
|
|
170
|
-
`stream`, or `null`.
|
|
169
|
+
> 🛈 Note: The hook is NOT called if the payload is a `string`, a `Buffer`, a
|
|
170
|
+
> `stream`, or `null`.
|
|
171
171
|
|
|
172
172
|
### onError
|
|
173
173
|
```js
|
|
@@ -196,8 +196,8 @@ user
|
|
|
196
196
|
*(Note that the default error handler always sends the error back to the
|
|
197
197
|
user)*.
|
|
198
198
|
|
|
199
|
-
|
|
200
|
-
supported.
|
|
199
|
+
> 🛈 Note: Unlike the other hooks, passing an error to the `done` function is not
|
|
200
|
+
> supported.
|
|
201
201
|
|
|
202
202
|
### onSend
|
|
203
203
|
If you are using the `onSend` hook, you can change the payload. For example:
|
|
@@ -233,8 +233,8 @@ fastify.addHook('onSend', (request, reply, payload, done) => {
|
|
|
233
233
|
> to `0`, whereas the `Content-Length` header will not be set if the payload is
|
|
234
234
|
> `null`.
|
|
235
235
|
|
|
236
|
-
Note: If you change the payload, you may only change it to a `string`, a
|
|
237
|
-
`Buffer`, a `stream`, a `ReadableStream`, a `Response`, or `null`.
|
|
236
|
+
> 🛈 Note: If you change the payload, you may only change it to a `string`, a
|
|
237
|
+
> `Buffer`, a `stream`, a `ReadableStream`, a `Response`, or `null`.
|
|
238
238
|
|
|
239
239
|
|
|
240
240
|
### onResponse
|
|
@@ -256,8 +256,8 @@ The `onResponse` hook is executed when a response has been sent, so you will not
|
|
|
256
256
|
be able to send more data to the client. It can however be useful for sending
|
|
257
257
|
data to external services, for example, to gather statistics.
|
|
258
258
|
|
|
259
|
-
|
|
260
|
-
inside the `onResponse` hook. In this case use `try - catch` to log errors.
|
|
259
|
+
> 🛈 Note: Setting `disableRequestLogging` to `true` will disable any error log
|
|
260
|
+
> inside the `onResponse` hook. In this case use `try - catch` to log errors.
|
|
261
261
|
|
|
262
262
|
### onTimeout
|
|
263
263
|
|
|
@@ -298,7 +298,8 @@ The `onRequestAbort` hook is executed when a client closes the connection before
|
|
|
298
298
|
the entire request has been processed. Therefore, you will not be able to send
|
|
299
299
|
data to the client.
|
|
300
300
|
|
|
301
|
-
|
|
301
|
+
> 🛈 Note: Client abort detection is not completely reliable.
|
|
302
|
+
> See: [`Detecting-When-Clients-Abort.md`](../Guides/Detecting-When-Clients-Abort.md)
|
|
302
303
|
|
|
303
304
|
### Manage Errors from a hook
|
|
304
305
|
If you get an error during the execution of your hook, just pass it to `done()`
|
|
@@ -451,8 +452,8 @@ fastify.addHook('onListen', async function () {
|
|
|
451
452
|
})
|
|
452
453
|
```
|
|
453
454
|
|
|
454
|
-
>
|
|
455
|
-
>
|
|
455
|
+
> 🛈 Note: This hook will not run when the server is started using
|
|
456
|
+
> fastify.inject()` or `fastify.ready()`.
|
|
456
457
|
|
|
457
458
|
### onClose
|
|
458
459
|
<a id="on-close"></a>
|
|
@@ -575,8 +576,8 @@ This hook can be useful if you are developing a plugin that needs to know when a
|
|
|
575
576
|
plugin context is formed, and you want to operate in that specific context, thus
|
|
576
577
|
this hook is encapsulated.
|
|
577
578
|
|
|
578
|
-
|
|
579
|
-
[`fastify-plugin`](https://github.com/fastify/fastify-plugin).
|
|
579
|
+
> 🛈 Note: This hook will not be called if a plugin is wrapped inside
|
|
580
|
+
> [`fastify-plugin`](https://github.com/fastify/fastify-plugin).
|
|
580
581
|
```js
|
|
581
582
|
fastify.decorate('data', [])
|
|
582
583
|
|
|
@@ -773,7 +774,7 @@ fastify.route({
|
|
|
773
774
|
})
|
|
774
775
|
```
|
|
775
776
|
|
|
776
|
-
|
|
777
|
+
> 🛈 Note: Both options also accept an array of functions.
|
|
777
778
|
|
|
778
779
|
## Using Hooks to Inject Custom Properties
|
|
779
780
|
<a id="using-hooks-to-inject-custom-properties"></a>
|
|
@@ -860,7 +861,7 @@ channel.subscribe(function ({ fastify }) {
|
|
|
860
861
|
})
|
|
861
862
|
```
|
|
862
863
|
|
|
863
|
-
>
|
|
864
|
+
> 🛈 Note: The TracingChannel class API is currently experimental and may undergo
|
|
864
865
|
> breaking changes even in semver-patch releases of Node.js.
|
|
865
866
|
|
|
866
867
|
Five other events are published on a per-request basis following the
|
package/docs/Reference/LTS.md
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
<h1 align="center">Fastify</h1>
|
|
2
2
|
|
|
3
3
|
## Long Term Support
|
|
4
|
-
|
|
5
|
-
`<a id="lts"></a>`
|
|
4
|
+
<a id="lts"></a>
|
|
6
5
|
|
|
7
6
|
Fastify's Long Term Support (LTS) is provided according to the schedule laid out
|
|
8
7
|
in this document:
|
|
@@ -25,13 +24,11 @@ in this document:
|
|
|
25
24
|
and verified against alternative runtimes that are compatible with Node.js.
|
|
26
25
|
The maintenance teams of these alternative runtimes are responsible for ensuring
|
|
27
26
|
and guaranteeing these tests work properly.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
LTS versions available at the time of the Fastify release.
|
|
34
|
-
This ensures users of N|Solid can confidently use Fastify.
|
|
27
|
+
1. [N|Solid](https://docs.nodesource.com/docs/product_suite) tests and
|
|
28
|
+
verifies each Fastify major release against current N|Solid LTS versions.
|
|
29
|
+
NodeSource ensures Fastify compatibility with N|Solid, aligning with the
|
|
30
|
+
support scope of N|Solid LTS versions at the time of the Fastify release.
|
|
31
|
+
This guarantees N|Solid users can confidently use Fastify.
|
|
35
32
|
|
|
36
33
|
A "month" is defined as 30 consecutive days.
|
|
37
34
|
|
|
@@ -41,12 +38,12 @@ A "month" is defined as 30 consecutive days.
|
|
|
41
38
|
> occasions where we need to release breaking changes as a _minor_ version
|
|
42
39
|
> release. Such changes will _always_ be noted in the [release
|
|
43
40
|
> notes](https://github.com/fastify/fastify/releases).
|
|
44
|
-
>
|
|
41
|
+
>
|
|
45
42
|
> To avoid automatically receiving breaking security updates it is possible to
|
|
46
43
|
> use the tilde (`~`) range qualifier. For example, to get patches for the 3.15
|
|
47
44
|
> release, and avoid automatically updating to the 3.16 release, specify the
|
|
48
45
|
> dependency as `"fastify": "~3.15.x"`. This will leave your application
|
|
49
|
-
> vulnerable, so please use with caution.
|
|
46
|
+
> vulnerable, so please use it with caution.
|
|
50
47
|
|
|
51
48
|
### Security Support Beyond LTS
|
|
52
49
|
|
|
@@ -55,8 +52,7 @@ OpenJS Ecosystem Sustainability Program for versions of Fastify that are EOL.
|
|
|
55
52
|
For more information, see their [Never Ending Support][hd-link] service.
|
|
56
53
|
|
|
57
54
|
### Schedule
|
|
58
|
-
|
|
59
|
-
`<a id="lts-schedule"></a>`
|
|
55
|
+
<a id="lts-schedule"></a>
|
|
60
56
|
|
|
61
57
|
| Version | Release Date | End Of LTS Date | Node.js | Nsolid(Node) |
|
|
62
58
|
| :------ | :----------- | :-------------- | :----------------- | :------------- |
|
|
@@ -67,8 +63,7 @@ For more information, see their [Never Ending Support][hd-link] service.
|
|
|
67
63
|
| 5.0.0 | 2024-09-17 | TBD | 20, 22 | v5(20) |
|
|
68
64
|
|
|
69
65
|
### CI tested operating systems
|
|
70
|
-
|
|
71
|
-
`<a id="supported-os"></a>`
|
|
66
|
+
<a id="supported-os"></a>
|
|
72
67
|
|
|
73
68
|
Fastify uses GitHub Actions for CI testing, please refer to [GitHub's
|
|
74
69
|
documentation regarding workflow
|
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
## Lifecycle
|
|
4
4
|
<a id="lifecycle"></a>
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
This schema shows the internal lifecycle of Fastify.
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
handled by Fastify)*.
|
|
8
|
+
The right branch of each section shows the next phase of the lifecycle. The left
|
|
9
|
+
branch shows the corresponding error code generated if the parent throws an
|
|
10
|
+
error. All errors are automatically handled by Fastify.
|
|
12
11
|
|
|
13
12
|
```
|
|
14
13
|
Incoming Request
|
|
@@ -42,26 +41,23 @@ Incoming Request
|
|
|
42
41
|
└─▶ onResponse Hook
|
|
43
42
|
```
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
-
|
|
48
|
-
- Sending the response automatically
|
|
44
|
+
Before or during the `User Handler`, `reply.hijack()` can be called to:
|
|
45
|
+
- Prevent Fastify from running subsequent hooks and the user handler
|
|
46
|
+
- Prevent Fastify from sending the response automatically
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
If `reply.raw` is used to send a response, `onResponse` hooks will still
|
|
49
|
+
be executed.
|
|
52
50
|
|
|
53
51
|
## Reply Lifecycle
|
|
54
52
|
<a id="reply-lifecycle"></a>
|
|
55
53
|
|
|
56
|
-
|
|
54
|
+
When the user handles the request, the result may be:
|
|
57
55
|
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
- in sync handler: it sends a payload
|
|
61
|
-
- in sync handler: it sends an `Error` instance
|
|
56
|
+
- In an async handler: it returns a payload or throws an `Error`
|
|
57
|
+
- In a sync handler: it sends a payload or an `Error` instance
|
|
62
58
|
|
|
63
|
-
If the reply was hijacked,
|
|
64
|
-
|
|
59
|
+
If the reply was hijacked, all subsequent steps are skipped. Otherwise, when
|
|
60
|
+
submitted, the data flow is as follows:
|
|
65
61
|
|
|
66
62
|
```
|
|
67
63
|
★ schema validation Error
|
|
@@ -81,9 +77,8 @@ being submitted, the data flow performed is the following:
|
|
|
81
77
|
└─▶ reply sent
|
|
82
78
|
```
|
|
83
79
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
- or by the default `JSON.stringify` function
|
|
80
|
+
`reply sent` means the JSON payload will be serialized by one of the following:
|
|
81
|
+
- The [reply serializer](./Server.md#setreplyserializer) if set
|
|
82
|
+
- The [serializer compiler](./Server.md#setserializercompiler) if a JSON schema
|
|
83
|
+
is set for the HTTP status code
|
|
84
|
+
- The default `JSON.stringify` function
|