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
|
@@ -2,17 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## Logging
|
|
4
4
|
|
|
5
|
-
### Enable
|
|
6
|
-
Logging is disabled by default
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
[abstract-logging](https://www.npmjs.com/package/abstract-logging) for
|
|
10
|
-
purpose.
|
|
5
|
+
### Enable Logging
|
|
6
|
+
Logging is disabled by default. Enable it by passing `{ logger: true }` or
|
|
7
|
+
`{ logger: { level: 'info' } }` when creating a Fastify instance. Note that if
|
|
8
|
+
the logger is disabled, it cannot be enabled at runtime.
|
|
9
|
+
[abstract-logging](https://www.npmjs.com/package/abstract-logging) is used for
|
|
10
|
+
this purpose.
|
|
11
11
|
|
|
12
12
|
As Fastify is focused on performance, it uses
|
|
13
13
|
[pino](https://github.com/pinojs/pino) as its logger, with the default log
|
|
14
|
-
level
|
|
14
|
+
level set to `'info'` when enabled.
|
|
15
15
|
|
|
16
|
+
#### Basic logging setup
|
|
16
17
|
Enabling the production JSON logger:
|
|
17
18
|
|
|
18
19
|
```js
|
|
@@ -21,8 +22,9 @@ const fastify = require('fastify')({
|
|
|
21
22
|
})
|
|
22
23
|
```
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
#### Environment-Specific Configuration
|
|
26
|
+
Enabling the logger with appropriate configuration for local development,
|
|
27
|
+
production, and test environments requires more configuration:
|
|
26
28
|
|
|
27
29
|
```js
|
|
28
30
|
const envToLogger = {
|
|
@@ -42,11 +44,11 @@ const fastify = require('fastify')({
|
|
|
42
44
|
logger: envToLogger[environment] ?? true // defaults to true if no entry matches in the map
|
|
43
45
|
})
|
|
44
46
|
```
|
|
45
|
-
⚠️ `pino-pretty` needs to be installed as a dev dependency
|
|
47
|
+
⚠️ `pino-pretty` needs to be installed as a dev dependency. It is not included
|
|
46
48
|
by default for performance reasons.
|
|
47
49
|
|
|
48
50
|
### Usage
|
|
49
|
-
|
|
51
|
+
The logger can be used in route handlers as follows:
|
|
50
52
|
|
|
51
53
|
```js
|
|
52
54
|
fastify.get('/', options, function (request, reply) {
|
|
@@ -55,16 +57,16 @@ fastify.get('/', options, function (request, reply) {
|
|
|
55
57
|
})
|
|
56
58
|
```
|
|
57
59
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
Trigger new logs outside route handlers using the Pino instance from the Fastify
|
|
61
|
+
instance:
|
|
60
62
|
```js
|
|
61
63
|
fastify.log.info('Something important happened!');
|
|
62
64
|
```
|
|
63
65
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
[Pino documentation](https://github.com/pinojs/pino/blob/master/docs/api.md#options)
|
|
67
|
-
|
|
66
|
+
#### Passing Logger Options
|
|
67
|
+
To pass options to the logger, provide them to Fastify. See the
|
|
68
|
+
[Pino documentation](https://github.com/pinojs/pino/blob/master/docs/api.md#options)
|
|
69
|
+
for available options. To specify a file destination, use:
|
|
68
70
|
|
|
69
71
|
```js
|
|
70
72
|
const fastify = require('fastify')({
|
|
@@ -80,8 +82,8 @@ fastify.get('/', options, function (request, reply) {
|
|
|
80
82
|
})
|
|
81
83
|
```
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
To pass a custom stream to the Pino instance, add a `stream` field to the logger
|
|
86
|
+
object:
|
|
85
87
|
|
|
86
88
|
```js
|
|
87
89
|
const split = require('split2')
|
|
@@ -95,19 +97,21 @@ const fastify = require('fastify')({
|
|
|
95
97
|
})
|
|
96
98
|
```
|
|
97
99
|
|
|
98
|
-
|
|
100
|
+
### Advanced Logger Configuration
|
|
99
101
|
|
|
102
|
+
<a id="logging-request-id"></a>
|
|
103
|
+
#### Request ID Tracking
|
|
100
104
|
By default, Fastify adds an ID to every request for easier tracking. If the
|
|
101
|
-
requestIdHeader
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
`requestIdHeader` option is set and the corresponding header is present, its
|
|
106
|
+
value is used; otherwise, a new incremental ID is generated. See Fastify Factory
|
|
107
|
+
[`requestIdHeader`](./Server.md#factory-request-id-header) and Fastify Factory
|
|
108
|
+
[`genReqId`](./Server.md#genreqid) for customization options.
|
|
105
109
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
can be customized
|
|
110
|
+
#### Serializers
|
|
111
|
+
The default logger uses standard serializers for objects with `req`, `res`, and
|
|
112
|
+
`err` properties. The `req` object is the Fastify [`Request`](./Request.md)
|
|
113
|
+
object, and the `res` object is the Fastify [`Reply`](./Reply.md) object. This
|
|
114
|
+
behavior can be customized with custom serializers.
|
|
111
115
|
|
|
112
116
|
```js
|
|
113
117
|
const fastify = require('fastify')({
|
|
@@ -121,7 +125,7 @@ const fastify = require('fastify')({
|
|
|
121
125
|
})
|
|
122
126
|
```
|
|
123
127
|
For example, the response payload and headers could be logged using the approach
|
|
124
|
-
below (
|
|
128
|
+
below (not recommended):
|
|
125
129
|
|
|
126
130
|
```js
|
|
127
131
|
const fastify = require('fastify')({
|
|
@@ -142,10 +146,9 @@ const fastify = require('fastify')({
|
|
|
142
146
|
url: request.url,
|
|
143
147
|
path: request.routeOptions.url,
|
|
144
148
|
parameters: request.params,
|
|
145
|
-
// Including
|
|
146
|
-
//
|
|
147
|
-
//
|
|
148
|
-
// the logs.
|
|
149
|
+
// Including headers in the log could violate privacy laws,
|
|
150
|
+
// e.g., GDPR. Use the "redact" option to remove sensitive
|
|
151
|
+
// fields. It could also leak authentication data in the logs.
|
|
149
152
|
headers: request.headers
|
|
150
153
|
};
|
|
151
154
|
}
|
|
@@ -154,11 +157,11 @@ const fastify = require('fastify')({
|
|
|
154
157
|
});
|
|
155
158
|
```
|
|
156
159
|
|
|
157
|
-
|
|
158
|
-
serializer cannot be fully constructed. When writing a custom `res`
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
`getHeaders`
|
|
160
|
+
> 🛈 Note: In some cases, the [`Reply`](./Reply.md) object passed to the `res`
|
|
161
|
+
> serializer cannot be fully constructed. When writing a custom `res`
|
|
162
|
+
> serializer, check for the existence of any properties on `reply` aside from
|
|
163
|
+
> `statusCode`, which is always present. For example, verify the existence of
|
|
164
|
+
> `getHeaders` before calling it:
|
|
162
165
|
|
|
163
166
|
```js
|
|
164
167
|
const fastify = require('fastify')({
|
|
@@ -170,7 +173,7 @@ const fastify = require('fastify')({
|
|
|
170
173
|
res (reply) {
|
|
171
174
|
// The default
|
|
172
175
|
return {
|
|
173
|
-
statusCode: reply.statusCode
|
|
176
|
+
statusCode: reply.statusCode,
|
|
174
177
|
headers: typeof reply.getHeaders === 'function'
|
|
175
178
|
? reply.getHeaders()
|
|
176
179
|
: {}
|
|
@@ -181,11 +184,11 @@ const fastify = require('fastify')({
|
|
|
181
184
|
});
|
|
182
185
|
```
|
|
183
186
|
|
|
184
|
-
|
|
185
|
-
request is serialized when
|
|
186
|
-
not yet parsed.
|
|
187
|
+
> 🛈 Note: The body cannot be serialized inside a `req` method because the
|
|
188
|
+
request is serialized when the child logger is created. At that time, the body
|
|
189
|
+
is not yet parsed.
|
|
187
190
|
|
|
188
|
-
See
|
|
191
|
+
See the following approach to log `req.body`:
|
|
189
192
|
|
|
190
193
|
```js
|
|
191
194
|
app.addHook('preHandler', function (req, reply, done) {
|
|
@@ -196,18 +199,18 @@ app.addHook('preHandler', function (req, reply, done) {
|
|
|
196
199
|
})
|
|
197
200
|
```
|
|
198
201
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
202
|
+
> 🛈 Note: Ensure serializers never throw errors, as this can cause the Node
|
|
203
|
+
> process to exit. See the
|
|
204
|
+
> [Pino documentation](https://getpino.io/#/docs/api?id=opt-serializers) for more
|
|
205
|
+
> information.
|
|
203
206
|
|
|
204
207
|
*Any logger other than Pino will ignore this option.*
|
|
205
208
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
conform to the Pino interface
|
|
209
|
-
`
|
|
210
|
-
|
|
209
|
+
### Using Custom Loggers
|
|
210
|
+
A custom logger instance can be supplied by passing it as `loggerInstance`. The
|
|
211
|
+
logger must conform to the Pino interface, with methods: `info`, `error`,
|
|
212
|
+
`debug`, `fatal`, `warn`, `trace`, `silent`, `child`, and a string property
|
|
213
|
+
`level`.
|
|
211
214
|
|
|
212
215
|
Example:
|
|
213
216
|
|
|
@@ -226,11 +229,11 @@ fastify.get('/', function (request, reply) {
|
|
|
226
229
|
*The logger instance for the current request is available in every part of the
|
|
227
230
|
[lifecycle](./Lifecycle.md).*
|
|
228
231
|
|
|
229
|
-
|
|
232
|
+
### Log Redaction
|
|
230
233
|
|
|
231
234
|
[Pino](https://getpino.io) supports low-overhead log redaction for obscuring
|
|
232
|
-
values of specific properties in recorded logs.
|
|
233
|
-
|
|
235
|
+
values of specific properties in recorded logs. For example, log all HTTP
|
|
236
|
+
headers except the `Authorization` header for security:
|
|
234
237
|
|
|
235
238
|
```js
|
|
236
239
|
const fastify = Fastify({
|
|
@@ -22,36 +22,36 @@ fastify.use(require('ienoopen')())
|
|
|
22
22
|
fastify.use(require('x-xss-protection')())
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
support for simple Express-style middleware
|
|
25
|
+
[`@fastify/middie`](https://github.com/fastify/middie) can also be used,
|
|
26
|
+
which provides support for simple Express-style middleware with improved
|
|
27
|
+
performance:
|
|
27
28
|
|
|
28
29
|
```js
|
|
29
30
|
await fastify.register(require('@fastify/middie'))
|
|
30
31
|
fastify.use(require('cors')())
|
|
31
32
|
```
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
[plugins guide](../Guides/Plugins-Guide.md).
|
|
34
|
+
Middleware can be encapsulated, allowing control over where it runs using
|
|
35
|
+
`register` as explained in the [plugins guide](../Guides/Plugins-Guide.md).
|
|
36
36
|
|
|
37
|
-
Fastify middleware does not expose the `send` method or other methods specific
|
|
38
|
-
the Fastify [Reply](./Reply.md#reply) instance. This is because Fastify wraps
|
|
37
|
+
Fastify middleware does not expose the `send` method or other methods specific
|
|
38
|
+
to the Fastify [Reply](./Reply.md#reply) instance. This is because Fastify wraps
|
|
39
39
|
the incoming `req` and `res` Node instances using the
|
|
40
40
|
[Request](./Request.md#request) and [Reply](./Reply.md#reply) objects
|
|
41
|
-
internally, but this is done after the middleware phase.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
[
|
|
45
|
-
|
|
41
|
+
internally, but this is done after the middleware phase. To create middleware,
|
|
42
|
+
use the Node `req` and `res` instances. Alternatively, use the `preHandler` hook
|
|
43
|
+
that already has the Fastify [Request](./Request.md#request) and
|
|
44
|
+
[Reply](./Reply.md#reply) instances. For more information, see
|
|
45
|
+
[Hooks](./Hooks.md#hooks).
|
|
46
46
|
|
|
47
47
|
#### Restrict middleware execution to certain paths
|
|
48
48
|
<a id="restrict-usage"></a>
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
To run middleware under certain paths, pass the path as the first parameter to
|
|
51
|
+
`use`.
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
`/user/:id/comments`) and wildcards are not supported in multiple paths
|
|
53
|
+
> 🛈 Note: This does not support routes with parameters
|
|
54
|
+
> (e.g. `/user/:id/comments`) and wildcards are not supported in multiple paths.
|
|
55
55
|
|
|
56
56
|
```js
|
|
57
57
|
const path = require('node:path')
|
|
@@ -69,10 +69,10 @@ fastify.use(['/css', '/js'], serveStatic(path.join(__dirname, '/assets')))
|
|
|
69
69
|
|
|
70
70
|
### Alternatives
|
|
71
71
|
|
|
72
|
-
Fastify offers
|
|
73
|
-
[`@fastify/helmet`](https://github.com/fastify/fastify-helmet)
|
|
72
|
+
Fastify offers alternatives to commonly used middleware, such as
|
|
73
|
+
[`@fastify/helmet`](https://github.com/fastify/fastify-helmet) for
|
|
74
74
|
[`helmet`](https://github.com/helmetjs/helmet),
|
|
75
75
|
[`@fastify/cors`](https://github.com/fastify/fastify-cors) for
|
|
76
76
|
[`cors`](https://github.com/expressjs/cors), and
|
|
77
77
|
[`@fastify/static`](https://github.com/fastify/fastify-static) for
|
|
78
|
-
[`serve-static`](https://github.com/expressjs/serve-static).
|
|
78
|
+
[`serve-static`](https://github.com/expressjs/serve-static).
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
<h1 align="center">Fastify</h1>
|
|
2
2
|
|
|
3
3
|
## Plugins
|
|
4
|
-
Fastify
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
By default, `register` creates a *new scope*,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Started](../Guides/Getting-Started.md#your-first-plugin) guide how easy it is
|
|
17
|
-
to use this API:
|
|
18
|
-
```
|
|
4
|
+
Fastify can be extended with plugins, which can be a set of routes, a server
|
|
5
|
+
[decorator](./Decorators.md), or other functionality. Use the `register` API to
|
|
6
|
+
add one or more plugins.
|
|
7
|
+
|
|
8
|
+
By default, `register` creates a *new scope*, meaning changes to the Fastify
|
|
9
|
+
instance (via `decorate`) will not affect the current context ancestors, only
|
|
10
|
+
its descendants. This feature enables plugin *encapsulation* and *inheritance*,
|
|
11
|
+
creating a *directed acyclic graph* (DAG) and avoiding cross-dependency issues.
|
|
12
|
+
|
|
13
|
+
The [Getting Started](../Guides/Getting-Started.md#your-first-plugin) guide
|
|
14
|
+
includes an example of using this API:
|
|
15
|
+
```js
|
|
19
16
|
fastify.register(plugin, [options])
|
|
20
17
|
```
|
|
21
18
|
|
|
@@ -33,10 +30,9 @@ Fastify specific options is:
|
|
|
33
30
|
+ [`logSerializers`](./Routes.md#custom-log-serializer)
|
|
34
31
|
+ [`prefix`](#route-prefixing-option)
|
|
35
32
|
|
|
36
|
-
|
|
33
|
+
These options will be ignored when used with fastify-plugin.
|
|
37
34
|
|
|
38
|
-
|
|
39
|
-
Thus, to avoid collisions, a plugin should consider namespacing its options. For
|
|
35
|
+
To avoid collisions, a plugin should consider namespacing its options. For
|
|
40
36
|
example, a plugin `foo` might be registered like so:
|
|
41
37
|
|
|
42
38
|
```js
|
|
@@ -49,8 +45,7 @@ fastify.register(require('fastify-foo'), {
|
|
|
49
45
|
})
|
|
50
46
|
```
|
|
51
47
|
|
|
52
|
-
If collisions are not a concern, the plugin may
|
|
53
|
-
as-is:
|
|
48
|
+
If collisions are not a concern, the plugin may accept the options object as-is:
|
|
54
49
|
|
|
55
50
|
```js
|
|
56
51
|
fastify.register(require('fastify-foo'), {
|
|
@@ -60,9 +55,8 @@ fastify.register(require('fastify-foo'), {
|
|
|
60
55
|
})
|
|
61
56
|
```
|
|
62
57
|
|
|
63
|
-
The `options` parameter can also be a `Function`
|
|
64
|
-
|
|
65
|
-
the first positional argument:
|
|
58
|
+
The `options` parameter can also be a `Function` evaluated at plugin registration,
|
|
59
|
+
providing access to the Fastify instance via the first argument:
|
|
66
60
|
|
|
67
61
|
```js
|
|
68
62
|
const fp = require('fastify-plugin')
|
|
@@ -77,40 +71,38 @@ fastify.register(fp((fastify, opts, done) => {
|
|
|
77
71
|
fastify.register(require('fastify-foo'), parent => parent.foo_bar)
|
|
78
72
|
```
|
|
79
73
|
|
|
80
|
-
The Fastify instance passed
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
74
|
+
The Fastify instance passed to the function is the latest state of the **external
|
|
75
|
+
Fastify instance** the plugin was declared on, allowing access to variables
|
|
76
|
+
injected via [`decorate`](./Decorators.md) by preceding plugins according to the
|
|
77
|
+
**order of registration**. This is useful if a plugin depends on changes made to
|
|
78
|
+
the Fastify instance by a preceding plugin, such as utilizing an existing database
|
|
79
|
+
connection.
|
|
86
80
|
|
|
87
|
-
Keep in mind that the Fastify instance passed
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
81
|
+
Keep in mind that the Fastify instance passed to the function is the same as the
|
|
82
|
+
one passed into the plugin, a copy of the external Fastify instance rather than a
|
|
83
|
+
reference. Any usage of the instance will behave the same as it would if called
|
|
84
|
+
within the plugin's function. For example, if `decorate` is called, the decorated
|
|
85
|
+
variables will be available within the plugin's function unless it was wrapped
|
|
86
|
+
with [`fastify-plugin`](https://github.com/fastify/fastify-plugin).
|
|
93
87
|
|
|
94
88
|
#### Route Prefixing option
|
|
95
89
|
<a id="route-prefixing-option"></a>
|
|
96
90
|
|
|
97
|
-
If
|
|
98
|
-
use it to prefix all the routes inside the register
|
|
91
|
+
If an option with the key `prefix` and a `string` value is passed, Fastify will
|
|
92
|
+
use it to prefix all the routes inside the register. For more info, check
|
|
99
93
|
[here](./Routes.md#route-prefixing).
|
|
100
94
|
|
|
101
|
-
Be aware that if
|
|
95
|
+
Be aware that if routes are wrapped with
|
|
102
96
|
[`fastify-plugin`](https://github.com/fastify/fastify-plugin), this option will
|
|
103
|
-
not work (
|
|
97
|
+
not work (see the [workaround](./Routes.md#fastify-plugin)).
|
|
104
98
|
|
|
105
99
|
#### Error handling
|
|
106
100
|
<a id="error-handling"></a>
|
|
107
101
|
|
|
108
|
-
|
|
109
|
-
[avvio](https://github.com/mcollina/avvio#error-handling).
|
|
102
|
+
Error handling is done by [avvio](https://github.com/mcollina/avvio#error-handling).
|
|
110
103
|
|
|
111
|
-
As a general rule,
|
|
112
|
-
|
|
113
|
-
callback.
|
|
104
|
+
As a general rule, handle errors in the next `after` or `ready` block, otherwise
|
|
105
|
+
they will be caught inside the `listen` callback.
|
|
114
106
|
|
|
115
107
|
```js
|
|
116
108
|
fastify.register(require('my-plugin'))
|
|
@@ -145,16 +137,15 @@ await fastify.ready()
|
|
|
145
137
|
|
|
146
138
|
await fastify.listen({ port: 3000 })
|
|
147
139
|
```
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
loaded will not be reflected in the parent instance.*
|
|
140
|
+
Using `await` when registering a plugin loads the plugin and its dependencies,
|
|
141
|
+
"finalizing" the encapsulation process. Any mutations to the plugin after it and
|
|
142
|
+
its dependencies have been loaded will not be reflected in the parent instance.
|
|
152
143
|
|
|
153
144
|
#### ESM support
|
|
154
145
|
<a id="esm-support"></a>
|
|
155
146
|
|
|
156
|
-
ESM is supported
|
|
157
|
-
|
|
147
|
+
ESM is supported from [Node.js `v13.3.0`](https://nodejs.org/api/esm.html)
|
|
148
|
+
and above.
|
|
158
149
|
|
|
159
150
|
```js
|
|
160
151
|
// main.mjs
|
|
@@ -179,9 +170,8 @@ export default plugin
|
|
|
179
170
|
### Create a plugin
|
|
180
171
|
<a id="create-plugin"></a>
|
|
181
172
|
|
|
182
|
-
Creating a plugin is
|
|
183
|
-
|
|
184
|
-
callback.
|
|
173
|
+
Creating a plugin is easy. Create a function that takes three parameters: the
|
|
174
|
+
`fastify` instance, an `options` object, and the `done` callback.
|
|
185
175
|
|
|
186
176
|
Example:
|
|
187
177
|
```js
|
|
@@ -193,7 +183,7 @@ module.exports = function (fastify, opts, done) {
|
|
|
193
183
|
done()
|
|
194
184
|
}
|
|
195
185
|
```
|
|
196
|
-
|
|
186
|
+
`register` can also be used inside another `register`:
|
|
197
187
|
```js
|
|
198
188
|
module.exports = function (fastify, opts, done) {
|
|
199
189
|
fastify.decorate('utility', function () {})
|
|
@@ -205,28 +195,23 @@ module.exports = function (fastify, opts, done) {
|
|
|
205
195
|
done()
|
|
206
196
|
}
|
|
207
197
|
```
|
|
208
|
-
Sometimes, you will need to know when the server is about to close, for example,
|
|
209
|
-
because you must close a connection to a database. To know when this is going to
|
|
210
|
-
happen, you can use the [`'onClose'`](./Hooks.md#on-close) hook.
|
|
211
198
|
|
|
212
|
-
|
|
213
|
-
|
|
199
|
+
Remember, `register` always creates a new Fastify scope. If this is not needed,
|
|
200
|
+
read the following section.
|
|
214
201
|
|
|
215
202
|
### Handle the scope
|
|
216
203
|
<a id="handle-scope"></a>
|
|
217
204
|
|
|
218
|
-
If
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
user in the upper scope.
|
|
205
|
+
If `register` is used only to extend server functionality with
|
|
206
|
+
[`decorate`](./Decorators.md), tell Fastify not to create a new scope. Otherwise,
|
|
207
|
+
changes will not be accessible in the upper scope.
|
|
222
208
|
|
|
223
|
-
|
|
209
|
+
There are two ways to avoid creating a new context:
|
|
224
210
|
- Use the [`fastify-plugin`](https://github.com/fastify/fastify-plugin) module
|
|
225
211
|
- Use the `'skip-override'` hidden property
|
|
226
212
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
plugin will support.
|
|
213
|
+
Using the `fastify-plugin` module is recommended, as it solves this problem and
|
|
214
|
+
allows passing a version range of Fastify that the plugin will support:
|
|
230
215
|
```js
|
|
231
216
|
const fp = require('fastify-plugin')
|
|
232
217
|
|
|
@@ -238,10 +223,9 @@ module.exports = fp(function (fastify, opts, done) {
|
|
|
238
223
|
Check the [`fastify-plugin`](https://github.com/fastify/fastify-plugin)
|
|
239
224
|
documentation to learn more about how to use this module.
|
|
240
225
|
|
|
241
|
-
If
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
`fastify-plugin`, you can be sure about backward compatibility.
|
|
226
|
+
If not using `fastify-plugin`, the `'skip-override'` hidden property can be used,
|
|
227
|
+
but it is not recommended. Future Fastify API changes will be your responsibility
|
|
228
|
+
to update, whilst `fastify-plugin` ensures backward compatibility.
|
|
245
229
|
```js
|
|
246
230
|
function yourPlugin (fastify, opts, done) {
|
|
247
231
|
fastify.decorate('utility', function () {})
|
|
@@ -16,48 +16,41 @@ the following technical principles:
|
|
|
16
16
|
|
|
17
17
|
## "Zero" Overhead in Production
|
|
18
18
|
|
|
19
|
-
Fastify aims to implement
|
|
20
|
-
|
|
21
|
-
This is usually delivered by implementing fast algorithms and data structures,
|
|
22
|
-
as well as JavaScript-specific features.
|
|
19
|
+
Fastify aims to implement features with minimal overhead. This is achieved by
|
|
20
|
+
using fast algorithms, data structures, and JavaScript-specific features.
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
as usually
|
|
22
|
+
Since JavaScript does not offer zero-overhead data structures, this principle
|
|
23
|
+
can conflict with providing a great developer experience and additional features,
|
|
24
|
+
as these usually incur some overhead.
|
|
27
25
|
|
|
28
26
|
## "Good" Developer Experience
|
|
29
27
|
|
|
30
|
-
Fastify aims to provide the best developer experience at
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
adapted to a variety of situations.
|
|
28
|
+
Fastify aims to provide the best developer experience at its performance point.
|
|
29
|
+
It offers a great out-of-the-box experience that is flexible enough to adapt to
|
|
30
|
+
various situations.
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
have access to a compiler.
|
|
32
|
+
For example, binary addons are forbidden because most JavaScript developers do
|
|
33
|
+
not have access to a compiler.
|
|
38
34
|
|
|
39
35
|
## Works great for small and big projects alike
|
|
40
36
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
the complexity of your application, providing advanced features to structure
|
|
44
|
-
your codebase.
|
|
37
|
+
Most applications start small and become more complex over time. Fastify aims to
|
|
38
|
+
grow with this complexity, providing advanced features to structure codebases.
|
|
45
39
|
|
|
46
40
|
## Easy to migrate to microservices (or even serverless) and back
|
|
47
41
|
|
|
48
|
-
|
|
42
|
+
Route deployment should not matter. The framework should "just work".
|
|
49
43
|
|
|
50
44
|
## Security and Data Validation
|
|
51
45
|
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
A web framework is the first point of contact with untrusted data and must act
|
|
47
|
+
as the first line of defense for the system.
|
|
54
48
|
|
|
55
49
|
## If something could be a plugin, it likely should
|
|
56
50
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
as you please.
|
|
51
|
+
Recognizing the infinite use cases for an HTTP framework, catering to all in a
|
|
52
|
+
single module would make the codebase unmaintainable. Therefore, hooks and
|
|
53
|
+
options are provided to customize the framework as needed.
|
|
61
54
|
|
|
62
55
|
## Easily testable
|
|
63
56
|
|
|
@@ -65,14 +58,16 @@ Testing Fastify applications should be a first-class concern.
|
|
|
65
58
|
|
|
66
59
|
## Do not monkeypatch core
|
|
67
60
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
Monkeypatching Node.js APIs or installing globals that alter the runtime makes
|
|
62
|
+
building modular applications harder and limits Fastify's use cases. Other
|
|
63
|
+
frameworks do this; Fastify does not.
|
|
71
64
|
|
|
72
65
|
## Semantic Versioning and Long Term Support
|
|
73
66
|
|
|
74
|
-
|
|
67
|
+
A clear [Long Term Support strategy is provided](./LTS.md) to inform developers when
|
|
68
|
+
to upgrade.
|
|
75
69
|
|
|
76
70
|
## Specification adherence
|
|
77
71
|
|
|
78
|
-
In doubt, we chose the strict behavior as defined by the relevant
|
|
72
|
+
In doubt, we chose the strict behavior as defined by the relevant
|
|
73
|
+
Specifications.
|