fastify 5.1.0 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -7
- package/docs/Guides/Database.md +15 -15
- package/docs/Guides/Detecting-When-Clients-Abort.md +28 -28
- package/docs/Guides/Ecosystem.md +13 -7
- package/docs/Guides/Index.md +1 -1
- package/docs/Guides/Migration-Guide-V4.md +11 -11
- package/docs/Guides/Migration-Guide-V5.md +5 -5
- package/docs/Guides/Plugins-Guide.md +1 -1
- package/docs/Guides/Prototype-Poisoning.md +3 -3
- package/docs/Guides/Recommendations.md +9 -9
- package/docs/Guides/Serverless.md +5 -5
- package/docs/Guides/Testing.md +8 -8
- package/docs/Guides/Write-Plugin.md +1 -1
- package/docs/Guides/Write-Type-Provider.md +3 -3
- package/docs/Reference/Decorators.md +2 -2
- package/docs/Reference/Errors.md +2 -2
- package/docs/Reference/Hooks.md +7 -7
- package/docs/Reference/LTS.md +8 -0
- package/docs/Reference/Logging.md +5 -4
- package/docs/Reference/Reply.md +54 -53
- package/docs/Reference/Request.md +49 -43
- package/docs/Reference/Routes.md +7 -7
- package/docs/Reference/Server.md +31 -27
- package/docs/Reference/TypeScript.md +9 -9
- package/docs/Reference/Validation-and-Serialization.md +5 -5
- package/examples/typescript-server.ts +1 -1
- package/fastify.d.ts +4 -4
- package/fastify.js +1 -1
- package/lib/error-handler.js +9 -9
- package/lib/errors.js +1 -1
- package/lib/hooks.js +4 -1
- package/lib/request.js +11 -10
- package/package.json +3 -4
- package/test/{allowUnsafeRegex.test.js → allow-unsafe-regex.test.js} +4 -4
- package/test/async-dispose.test.js +0 -1
- package/test/async_hooks.test.js +4 -4
- package/test/buffer.test.js +4 -4
- package/test/build-certificate.js +1 -1
- package/test/bundler/README.md +5 -5
- package/test/case-insensitive.test.js +10 -10
- package/test/check.test.js +2 -3
- package/test/{childLoggerFactory.test.js → child-logger-factory.test.js} +1 -1
- package/test/client-timeout.test.js +1 -1
- package/test/close-pipelining.test.js +0 -1
- package/test/conditional-pino.test.js +3 -3
- package/test/content-length.test.js +53 -68
- package/test/content-parser.test.js +178 -167
- package/test/content-type.test.js +8 -9
- package/test/context-config.test.js +44 -54
- package/test/custom-parser.5.test.js +32 -32
- package/test/encapsulated-child-logger-factory.test.js +8 -8
- package/test/encapsulated-error-handler.test.js +20 -20
- package/test/fastify-instance.test.js +33 -34
- package/test/{findRoute.test.js → find-route.test.js} +11 -10
- package/test/fluent-schema.test.js +33 -36
- package/test/handler-context.test.js +11 -11
- package/test/has-route.test.js +12 -15
- package/test/header-overflow.test.js +13 -12
- package/test/hooks.on-ready.test.js +2 -2
- package/test/hooks.test.js +19 -19
- package/test/http-methods/head.test.js +0 -3
- package/test/imports.test.js +2 -2
- package/test/internals/errors.test.js +1 -1
- package/test/listen.5.test.js +9 -9
- package/test/{maxRequestsPerSocket.test.js → max-requests-per-socket.test.js} +30 -30
- package/test/middleware.test.js +4 -5
- package/test/noop-set.test.js +1 -1
- package/test/post-empty-body.test.js +18 -11
- package/test/pretty-print.test.js +59 -49
- package/test/proto-poisoning.test.js +42 -37
- package/test/reply-code.test.js +34 -32
- package/test/{reply-earlyHints.test.js → reply-early-hints.test.js} +21 -19
- package/test/request-header-host.test.js +154 -12
- package/test/request-id.test.js +31 -25
- package/test/{requestTimeout.test.js → request-timeout.test.js} +11 -11
- package/test/route.3.test.js +3 -2
- package/test/route.8.test.js +20 -20
- package/test/router-options.test.js +80 -77
- package/test/schema-examples.test.js +72 -38
- package/test/server.test.js +12 -12
- package/test/set-error-handler.test.js +2 -3
- package/test/stream-serializers.test.js +10 -7
- package/test/sync-routes.test.js +18 -18
- package/test/trust-proxy.test.js +51 -45
- package/test/type-provider.test.js +8 -6
- package/test/types/content-type-parser.test-d.ts +1 -1
- package/test/types/fastify.test-d.ts +4 -4
- package/test/types/instance.test-d.ts +3 -1
- package/test/types/logger.test-d.ts +2 -2
- package/test/types/plugin.test-d.ts +2 -2
- package/test/types/register.test-d.ts +2 -2
- package/test/types/reply.test-d.ts +1 -1
- package/test/types/route.test-d.ts +1 -1
- package/test/types/serverFactory.test-d.ts +1 -1
- package/test/types/type-provider.test-d.ts +1 -1
- package/test/url-rewriting.test.js +35 -38
- package/test/{useSemicolonDelimiter.test.js → use-semicolon-delimiter.test.js} +30 -30
- package/test/validation-error-handling.test.js +259 -285
- package/types/hooks.d.ts +1 -1
- package/types/instance.d.ts +9 -2
- package/types/reply.d.ts +1 -1
- package/types/request.d.ts +0 -4
- package/types/serverFactory.d.ts +3 -3
- package/types/utils.d.ts +3 -3
- /package/test/{connectionTimeout.test.js → connection-timeout.test.js} +0 -0
- /package/test/internals/{contentTypeParser.test.js → content-type-parser.test.js} +0 -0
- /package/test/internals/{handleRequest.test.js → handle-request.test.js} +0 -0
- /package/test/internals/{hookRunner.test.js → hook-runner.test.js} +0 -0
- /package/test/internals/{initialConfig.test.js → initial-config.test.js} +0 -0
- /package/test/internals/{reqIdGenFactory.test.js → req-id-gen-factory.test.js} +0 -0
- /package/test/{wrapThenable.test.js → wrap-thenable.test.js} +0 -0
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
<div align="center">
|
|
11
11
|
|
|
12
|
-
[](https://github.com/fastify/fastify/actions/workflows/ci.yml)
|
|
12
|
+
[](https://github.com/fastify/fastify/actions/workflows/ci.yml)
|
|
13
13
|
[](https://github.com/fastify/fastify/actions/workflows/package-manager-ci.yml)
|
|
15
15
|
[](https://www.np
|
|
|
29
29
|
Disclosure](https://img.shields.io/badge/Security-Responsible%20Disclosure-yellow.svg)](https://github.com/fastify/fastify/blob/main/SECURITY.md)
|
|
30
30
|
[](https://discord.gg/fastify)
|
|
31
31
|
[](https://gitpod.io/#https://github.com/fastify/fastify)
|
|
32
|
-

|
|
32
|
+
[](https://github.com/sponsors/fastify#sponsors)
|
|
33
33
|
|
|
34
34
|
</div>
|
|
35
35
|
|
|
@@ -106,14 +106,9 @@ generate functionality of [Fastify CLI](https://github.com/fastify/fastify-cli).
|
|
|
106
106
|
|
|
107
107
|
To install Fastify in an existing project as a dependency:
|
|
108
108
|
|
|
109
|
-
Install with npm:
|
|
110
109
|
```sh
|
|
111
110
|
npm i fastify
|
|
112
111
|
```
|
|
113
|
-
Install with yarn:
|
|
114
|
-
```sh
|
|
115
|
-
yarn add fastify
|
|
116
|
-
```
|
|
117
112
|
|
|
118
113
|
### Example
|
|
119
114
|
|
|
@@ -266,6 +261,13 @@ application, you should __always__ benchmark if performance matters to you.
|
|
|
266
261
|
Please visit [Fastify help](https://github.com/fastify/help) to view prior
|
|
267
262
|
support issues and to ask new support questions.
|
|
268
263
|
|
|
264
|
+
Version 3 of Fastify and lower are EOL and will not receive any security or bug fixes.
|
|
265
|
+
|
|
266
|
+
Fastify's partner, HeroDevs, provides commercial security fixes for all
|
|
267
|
+
unsupported versions at [https://herodevs.com/support/fastify-nes][hd-link].
|
|
268
|
+
Fastify's supported version matrix is available in the
|
|
269
|
+
[Long Term Support][lts-link] documentation.
|
|
270
|
+
|
|
269
271
|
## Contributing
|
|
270
272
|
|
|
271
273
|
Whether reporting bugs, discussing improvements and new ideas or writing code,
|
|
@@ -414,3 +416,6 @@ dependencies:
|
|
|
414
416
|
- ISC
|
|
415
417
|
- BSD-3-Clause
|
|
416
418
|
- BSD-2-Clause
|
|
419
|
+
|
|
420
|
+
[hd-link]: https://www.herodevs.com/support/fastify-nes?utm_source=fastify&utm_medium=link&utm_campaign=github_readme
|
|
421
|
+
[lts-link]: https://fastify.dev/docs/latest/Reference/LTS/
|
package/docs/Guides/Database.md
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## Database
|
|
4
4
|
|
|
5
|
-
Fastify's ecosystem provides a handful of
|
|
6
|
-
plugins for connecting to various database engines.
|
|
7
|
-
This guide covers engines that have Fastify
|
|
5
|
+
Fastify's ecosystem provides a handful of
|
|
6
|
+
plugins for connecting to various database engines.
|
|
7
|
+
This guide covers engines that have Fastify
|
|
8
8
|
plugins maintained within the Fastify organization.
|
|
9
9
|
|
|
10
|
-
> If a plugin for your database of choice does not exist
|
|
11
|
-
> you can still use the database as Fastify is database agnostic.
|
|
12
|
-
> By following the examples of the database plugins listed in this guide,
|
|
13
|
-
> a plugin can be written for the missing database engine.
|
|
10
|
+
> If a plugin for your database of choice does not exist
|
|
11
|
+
> you can still use the database as Fastify is database agnostic.
|
|
12
|
+
> By following the examples of the database plugins listed in this guide,
|
|
13
|
+
> a plugin can be written for the missing database engine.
|
|
14
14
|
|
|
15
|
-
> If you would like to write your own Fastify plugin
|
|
15
|
+
> If you would like to write your own Fastify plugin
|
|
16
16
|
> please take a look at the [plugins guide](./Plugins-Guide.md)
|
|
17
17
|
|
|
18
18
|
### [MySQL](https://github.com/fastify/fastify-mysql)
|
|
@@ -104,8 +104,8 @@ fastify.listen({ port: 3000 }, err => {
|
|
|
104
104
|
})
|
|
105
105
|
```
|
|
106
106
|
|
|
107
|
-
By default `@fastify/redis` doesn't close
|
|
108
|
-
the client connection when Fastify server shuts down.
|
|
107
|
+
By default `@fastify/redis` doesn't close
|
|
108
|
+
the client connection when Fastify server shuts down.
|
|
109
109
|
To opt-in to this behavior, register the client like so:
|
|
110
110
|
|
|
111
111
|
```javascript
|
|
@@ -126,7 +126,7 @@ fastify.register(require('@fastify/mongodb'), {
|
|
|
126
126
|
// force to close the mongodb connection when app stopped
|
|
127
127
|
// the default value is false
|
|
128
128
|
forceClose: true,
|
|
129
|
-
|
|
129
|
+
|
|
130
130
|
url: 'mongodb://mongo/mydb'
|
|
131
131
|
})
|
|
132
132
|
|
|
@@ -178,8 +178,8 @@ fastify.listen({ port: 3000 }, err => {
|
|
|
178
178
|
```
|
|
179
179
|
|
|
180
180
|
### Writing plugin for a database library
|
|
181
|
-
We could write a plugin for a database
|
|
182
|
-
library too (e.g. Knex, Prisma, or TypeORM).
|
|
181
|
+
We could write a plugin for a database
|
|
182
|
+
library too (e.g. Knex, Prisma, or TypeORM).
|
|
183
183
|
We will use [Knex](https://knexjs.org/) in our example.
|
|
184
184
|
|
|
185
185
|
```javascript
|
|
@@ -281,7 +281,7 @@ async function migrate() {
|
|
|
281
281
|
const client = new pg.Client({
|
|
282
282
|
host: 'localhost',
|
|
283
283
|
port: 5432,
|
|
284
|
-
database: 'example',
|
|
284
|
+
database: 'example',
|
|
285
285
|
user: 'example',
|
|
286
286
|
password: 'example',
|
|
287
287
|
});
|
|
@@ -313,7 +313,7 @@ async function migrate() {
|
|
|
313
313
|
console.error(err)
|
|
314
314
|
process.exitCode = 1
|
|
315
315
|
}
|
|
316
|
-
|
|
316
|
+
|
|
317
317
|
await client.end()
|
|
318
318
|
}
|
|
319
319
|
|
|
@@ -4,30 +4,30 @@
|
|
|
4
4
|
|
|
5
5
|
## Introduction
|
|
6
6
|
|
|
7
|
-
Fastify provides request events to trigger at certain points in a request's
|
|
8
|
-
lifecycle. However, there isn't a built-in mechanism to
|
|
9
|
-
detect unintentional client disconnection scenarios such as when the client's
|
|
7
|
+
Fastify provides request events to trigger at certain points in a request's
|
|
8
|
+
lifecycle. However, there isn't a built-in mechanism to
|
|
9
|
+
detect unintentional client disconnection scenarios such as when the client's
|
|
10
10
|
internet connection is interrupted. This guide covers methods to detect if
|
|
11
11
|
and when a client intentionally aborts a request.
|
|
12
12
|
|
|
13
|
-
Keep in mind, Fastify's `clientErrorHandler` is not designed to detect when a
|
|
14
|
-
client aborts a request. This works in the same way as the standard Node HTTP
|
|
15
|
-
module, which triggers the `clientError` event when there is a bad request or
|
|
16
|
-
exceedingly large header data. When a client aborts a request, there is no
|
|
13
|
+
Keep in mind, Fastify's `clientErrorHandler` is not designed to detect when a
|
|
14
|
+
client aborts a request. This works in the same way as the standard Node HTTP
|
|
15
|
+
module, which triggers the `clientError` event when there is a bad request or
|
|
16
|
+
exceedingly large header data. When a client aborts a request, there is no
|
|
17
17
|
error on the socket and the `clientErrorHandler` will not be triggered.
|
|
18
18
|
|
|
19
19
|
## Solution
|
|
20
20
|
|
|
21
21
|
### Overview
|
|
22
22
|
|
|
23
|
-
The proposed solution is a possible way of detecting when a client
|
|
24
|
-
intentionally aborts a request, such as when a browser is closed or the HTTP
|
|
25
|
-
request is aborted from your client application. If there is an error in your
|
|
26
|
-
application code that results in the server crashing, you may require
|
|
23
|
+
The proposed solution is a possible way of detecting when a client
|
|
24
|
+
intentionally aborts a request, such as when a browser is closed or the HTTP
|
|
25
|
+
request is aborted from your client application. If there is an error in your
|
|
26
|
+
application code that results in the server crashing, you may require
|
|
27
27
|
additional logic to avoid a false abort detection.
|
|
28
28
|
|
|
29
|
-
The goal here is to detect when a client intentionally aborts a connection
|
|
30
|
-
so your application logic can proceed accordingly. This can be useful for
|
|
29
|
+
The goal here is to detect when a client intentionally aborts a connection
|
|
30
|
+
so your application logic can proceed accordingly. This can be useful for
|
|
31
31
|
logging purposes or halting business logic.
|
|
32
32
|
|
|
33
33
|
### Hands-on
|
|
@@ -78,10 +78,10 @@ const start = async () => {
|
|
|
78
78
|
start()
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
Our code is setting up a Fastify server which includes the following
|
|
81
|
+
Our code is setting up a Fastify server which includes the following
|
|
82
82
|
functionality:
|
|
83
83
|
|
|
84
|
-
- Accepting requests at http://localhost:3000, with a 3 second delayed response
|
|
84
|
+
- Accepting requests at http://localhost:3000, with a 3 second delayed response
|
|
85
85
|
of `{ ok: true }`.
|
|
86
86
|
- An onRequest hook that triggers when every request is received.
|
|
87
87
|
- Logic that triggers in the hook when the request is closed.
|
|
@@ -108,7 +108,7 @@ app.get('/', async (request, reply) => {
|
|
|
108
108
|
})
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
At any point in your business logic, you can check if the request has been
|
|
111
|
+
At any point in your business logic, you can check if the request has been
|
|
112
112
|
aborted and perform alternative actions.
|
|
113
113
|
|
|
114
114
|
```js
|
|
@@ -122,14 +122,14 @@ app.get('/', async (request, reply) => {
|
|
|
122
122
|
})
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
-
A benefit to adding this in your application code is that you can log Fastify
|
|
126
|
-
details such as the reqId, which may be unavailable in lower-level code that
|
|
125
|
+
A benefit to adding this in your application code is that you can log Fastify
|
|
126
|
+
details such as the reqId, which may be unavailable in lower-level code that
|
|
127
127
|
only has access to the raw request information.
|
|
128
128
|
|
|
129
129
|
### Testing
|
|
130
130
|
|
|
131
|
-
To test this functionality you can use an app like Postman and cancel your
|
|
132
|
-
request within 3 seconds. Alternatively, you can use Node to send an HTTP
|
|
131
|
+
To test this functionality you can use an app like Postman and cancel your
|
|
132
|
+
request within 3 seconds. Alternatively, you can use Node to send an HTTP
|
|
133
133
|
request with logic to abort the request before 3 seconds. Example:
|
|
134
134
|
|
|
135
135
|
```js
|
|
@@ -151,7 +151,7 @@ setTimeout(() => {
|
|
|
151
151
|
}, 1000);
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
-
With either approach, you should see the Fastify log appear at the moment the
|
|
154
|
+
With either approach, you should see the Fastify log appear at the moment the
|
|
155
155
|
request is aborted.
|
|
156
156
|
|
|
157
157
|
## Conclusion
|
|
@@ -160,13 +160,13 @@ Specifics of the implementation will vary from one problem to another, but the
|
|
|
160
160
|
main goal of this guide was to show a very specific use case of an issue that
|
|
161
161
|
could be solved within Fastify's ecosystem.
|
|
162
162
|
|
|
163
|
-
You can listen to the request close event and determine if the request was
|
|
164
|
-
aborted or if it was successfully delivered. You can implement this solution
|
|
163
|
+
You can listen to the request close event and determine if the request was
|
|
164
|
+
aborted or if it was successfully delivered. You can implement this solution
|
|
165
165
|
in an onRequest hook or directly in an individual route.
|
|
166
166
|
|
|
167
|
-
This approach will not trigger in the event of internet disruption, and such
|
|
168
|
-
detection would require additional business logic. If you have flawed backend
|
|
169
|
-
application logic that results in a server crash, then you could trigger a
|
|
170
|
-
false detection. The `clientErrorHandler`, either by default or with custom
|
|
171
|
-
logic, is not intended to handle this scenario and will not trigger when the
|
|
167
|
+
This approach will not trigger in the event of internet disruption, and such
|
|
168
|
+
detection would require additional business logic. If you have flawed backend
|
|
169
|
+
application logic that results in a server crash, then you could trigger a
|
|
170
|
+
false detection. The `clientErrorHandler`, either by default or with custom
|
|
171
|
+
logic, is not intended to handle this scenario and will not trigger when the
|
|
172
172
|
client aborts a request.
|
package/docs/Guides/Ecosystem.md
CHANGED
|
@@ -175,6 +175,10 @@ section.
|
|
|
175
175
|
- [`@ethicdevs/fastify-git-server`](https://github.com/EthicDevs/fastify-git-server)
|
|
176
176
|
A plugin to easily create git server and make one/many Git repositories available
|
|
177
177
|
for clone/fetch/push through the standard `git` (over http) commands.
|
|
178
|
+
- [`@exortek/fastify-mongo-sanitize`](https://github.com/ExorTek/fastify-mongo-sanitize)
|
|
179
|
+
A Fastify plugin that protects against No(n)SQL injection by sanitizing data.
|
|
180
|
+
- [`@exortek/remix-fastify`](https://github.com/ExorTek/remix-fastify)
|
|
181
|
+
Fastify plugin for Remix.
|
|
178
182
|
- [`@fastify-userland/request-id`](https://github.com/fastify-userland/request-id)
|
|
179
183
|
Fastify Request ID Plugin
|
|
180
184
|
- [`@fastify-userland/typeorm-query-runner`](https://github.com/fastify-userland/typeorm-query-runner)
|
|
@@ -214,9 +218,9 @@ section.
|
|
|
214
218
|
Beautiful OpenAPI/Swagger API references for Fastify
|
|
215
219
|
- [`@trubavuong/fastify-seaweedfs`](https://github.com/trubavuong/fastify-seaweedfs)
|
|
216
220
|
SeaweedFS for Fastify
|
|
217
|
-
- [`apitally`](https://github.com/apitally/
|
|
218
|
-
integrate with [Apitally](https://apitally.io),
|
|
219
|
-
|
|
221
|
+
- [`apitally`](https://github.com/apitally/apitally-js) Fastify plugin to
|
|
222
|
+
integrate with [Apitally](https://apitally.io/fastify), an API analytics,
|
|
223
|
+
logging and monitoring tool.
|
|
220
224
|
- [`arecibo`](https://github.com/nucleode/arecibo) Fastify ping responder for
|
|
221
225
|
Kubernetes Liveness and Readiness Probes.
|
|
222
226
|
- [`aws-xray-sdk-fastify`](https://github.com/aws/aws-xray-sdk-node/tree/master/sdk_contrib/fastify)
|
|
@@ -249,7 +253,7 @@ section.
|
|
|
249
253
|
plugin to authenticate HTTP requests based on API key and signature
|
|
250
254
|
- [`fastify-appwrite`](https://github.com/Dev-Manny/fastify-appwrite) Fastify
|
|
251
255
|
Plugin for interacting with Appwrite server.
|
|
252
|
-
- [`fastify-asyncforge`](https://github.com/mcollina/fastify-asyncforge) Plugin
|
|
256
|
+
- [`fastify-asyncforge`](https://github.com/mcollina/fastify-asyncforge) Plugin
|
|
253
257
|
to access Fastify instance, logger, request and reply from Node.js [Async
|
|
254
258
|
Local Storage](https://nodejs.org/api/async_context.html#class-asynclocalstorage).
|
|
255
259
|
- [`fastify-at-mysql`](https://github.com/mateonunez/fastify-at-mysql) Fastify
|
|
@@ -277,7 +281,7 @@ section.
|
|
|
277
281
|
development servers that require Babel transformations of JavaScript sources.
|
|
278
282
|
- [`fastify-bcrypt`](https://github.com/beliven-it/fastify-bcrypt) A Bcrypt hash
|
|
279
283
|
generator & checker.
|
|
280
|
-
- [`fastify-better-sqlite3`](https://github.com/punkish/fastify-better-sqlite3)
|
|
284
|
+
- [`fastify-better-sqlite3`](https://github.com/punkish/fastify-better-sqlite3)
|
|
281
285
|
Plugin for better-sqlite3.
|
|
282
286
|
- [`fastify-blipp`](https://github.com/PavelPolyakov/fastify-blipp) Prints your
|
|
283
287
|
routes to the console, so you definitely know which endpoints are available.
|
|
@@ -289,7 +293,7 @@ section.
|
|
|
289
293
|
to add [bree](https://github.com/breejs/bree) support.
|
|
290
294
|
- [`fastify-bugsnag`](https://github.com/ZigaStrgar/fastify-bugsnag) Fastify plugin
|
|
291
295
|
to add support for [Bugsnag](https://www.bugsnag.com/) error reporting.
|
|
292
|
-
- [`fastify-cacheman`](https://gitlab.com/aalfiann/fastify-cacheman)
|
|
296
|
+
- [`fastify-cacheman`](https://gitlab.com/aalfiann/fastify-cacheman)
|
|
293
297
|
Small and efficient cache provider for Node.js with In-memory, File, Redis
|
|
294
298
|
and MongoDB engines for Fastify
|
|
295
299
|
- [`fastify-casbin`](https://github.com/nearform/fastify-casbin) Casbin support
|
|
@@ -344,7 +348,7 @@ section.
|
|
|
344
348
|
- [`fastify-event-bus`](https://github.com/Shiva127/fastify-event-bus) Event bus
|
|
345
349
|
support for Fastify. Built upon [js-event-bus](https://github.com/bcerati/js-event-bus).
|
|
346
350
|
- [`fastify-evervault`](https://github.com/Briscoooe/fastify-evervault/) Fastify
|
|
347
|
-
plugin for instantiating and encapsulating the
|
|
351
|
+
plugin for instantiating and encapsulating the
|
|
348
352
|
[Evervault](https://evervault.com/) client.
|
|
349
353
|
- [`fastify-explorer`](https://github.com/Eomm/fastify-explorer) Get control of
|
|
350
354
|
your decorators across all the encapsulated contexts.
|
|
@@ -538,6 +542,8 @@ middlewares into Fastify plugins
|
|
|
538
542
|
OSM plugin to run overpass queries by OpenStreetMap.
|
|
539
543
|
- [`fastify-override`](https://github.com/matthyk/fastify-override)
|
|
540
544
|
Fastify plugin to override decorators, plugins and hooks for testing purposes
|
|
545
|
+
- [`fastify-passkit-webservice`](https://github.com/alexandercerutti/fastify-passkit-webservice)
|
|
546
|
+
A set of Fastify plugins to integrate Apple Wallet Web Service specification
|
|
541
547
|
- [`fastify-peekaboo`](https://github.com/simone-sanfratello/fastify-peekaboo)
|
|
542
548
|
Fastify plugin for memoize responses by expressive settings.
|
|
543
549
|
- [`fastify-piscina`](https://github.com/piscinajs/fastify-piscina) A worker
|
package/docs/Guides/Index.md
CHANGED
|
@@ -15,7 +15,7 @@ This table of contents is in alphabetical order.
|
|
|
15
15
|
met in your application. This guide focuses on solving the problem using
|
|
16
16
|
[`Hooks`](../Reference/Hooks.md), [`Decorators`](../Reference/Decorators.md),
|
|
17
17
|
and [`Plugins`](../Reference/Plugins.md).
|
|
18
|
-
+ [Detecting When Clients Abort](./Detecting-When-Clients-Abort.md): A
|
|
18
|
+
+ [Detecting When Clients Abort](./Detecting-When-Clients-Abort.md): A
|
|
19
19
|
practical guide on detecting if and when a client aborts a request.
|
|
20
20
|
+ [Ecosystem](./Ecosystem.md): Lists all core plugins and many known community
|
|
21
21
|
plugins.
|
|
@@ -9,13 +9,13 @@ work after upgrading.
|
|
|
9
9
|
## Codemods
|
|
10
10
|
### Fastify v4 Codemods
|
|
11
11
|
|
|
12
|
-
To help with the upgrade, we’ve worked with the team at
|
|
12
|
+
To help with the upgrade, we’ve worked with the team at
|
|
13
13
|
[Codemod](https://github.com/codemod-com/codemod) to
|
|
14
|
-
publish codemods that will automatically update your code to many of
|
|
14
|
+
publish codemods that will automatically update your code to many of
|
|
15
15
|
the new APIs and patterns in Fastify v4.
|
|
16
16
|
|
|
17
|
-
Run the following
|
|
18
|
-
[migration recipe](https://go.codemod.com/fastify-4-migration-recipe) to
|
|
17
|
+
Run the following
|
|
18
|
+
[migration recipe](https://go.codemod.com/fastify-4-migration-recipe) to
|
|
19
19
|
automatically update your code to Fastify v4:
|
|
20
20
|
|
|
21
21
|
```
|
|
@@ -30,7 +30,7 @@ This will run the following codemods:
|
|
|
30
30
|
- [`fastify/4/await-register-calls`](https://go.codemod.com/fastify-4-await-register-calls)
|
|
31
31
|
|
|
32
32
|
Each of these codemods automates the changes listed in the v4 migration guide.
|
|
33
|
-
For a complete list of available Fastify codemods and further details,
|
|
33
|
+
For a complete list of available Fastify codemods and further details,
|
|
34
34
|
see [Codemod Registry](https://go.codemod.com/fastify).
|
|
35
35
|
|
|
36
36
|
|
|
@@ -52,14 +52,14 @@ fastify.register(async fastify => {
|
|
|
52
52
|
console.log(err.message) // 'kaboom'
|
|
53
53
|
throw new Error('caught')
|
|
54
54
|
})
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
fastify.get('/encapsulated', async () => {
|
|
57
57
|
throw new Error('kaboom')
|
|
58
58
|
})
|
|
59
59
|
})
|
|
60
60
|
|
|
61
61
|
fastify.setErrorHandler(async err => {
|
|
62
|
-
console.log(err.message) // 'caught'
|
|
62
|
+
console.log(err.message) // 'caught'
|
|
63
63
|
throw new Error('wrapped')
|
|
64
64
|
})
|
|
65
65
|
|
|
@@ -67,10 +67,10 @@ const res = await fastify.inject('/encapsulated')
|
|
|
67
67
|
console.log(res.json().message) // 'wrapped'
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
>The root error handler is Fastify’s generic error handler.
|
|
71
|
-
>This error handler will use the headers and status code in the Error object,
|
|
70
|
+
>The root error handler is Fastify’s generic error handler.
|
|
71
|
+
>This error handler will use the headers and status code in the Error object,
|
|
72
72
|
>if they exist. **The headers and status code will not be automatically set if
|
|
73
|
-
>a custom error handler is provided**.
|
|
73
|
+
>a custom error handler is provided**.
|
|
74
74
|
|
|
75
75
|
### Removed `app.use()` ([#3506](https://github.com/fastify/fastify/pull/3506))
|
|
76
76
|
|
|
@@ -242,7 +242,7 @@ As such, schemas like below will need to be changed from:
|
|
|
242
242
|
properties: {
|
|
243
243
|
api_key: { type: 'string' },
|
|
244
244
|
image: { type: ['object', 'array'] }
|
|
245
|
-
}
|
|
245
|
+
}
|
|
246
246
|
}
|
|
247
247
|
```
|
|
248
248
|
|
|
@@ -159,7 +159,7 @@ the following:
|
|
|
159
159
|
+++ b/index.ts
|
|
160
160
|
@@ -11,7 +11,8 @@ import {
|
|
161
161
|
import { FromSchema, FromSchemaDefaultOptions, FromSchemaOptions, JSONSchema } from 'json-schema-to-ts'
|
|
162
|
-
|
|
162
|
+
|
|
163
163
|
export interface JsonSchemaToTsProvider<
|
|
164
164
|
Options extends FromSchemaOptions = FromSchemaDefaultOptions
|
|
165
165
|
> extends FastifyTypeProvider {
|
|
@@ -298,7 +298,7 @@ use the `constraints` option instead.
|
|
|
298
298
|
We have a more strict requirement for custom `HEAD` route when
|
|
299
299
|
`exposeHeadRoutes: true`.
|
|
300
300
|
|
|
301
|
-
When you provides a custom `HEAD` route, you must either explicitly
|
|
301
|
+
When you provides a custom `HEAD` route, you must either explicitly
|
|
302
302
|
set `exposeHeadRoutes` to `false`
|
|
303
303
|
|
|
304
304
|
```js
|
|
@@ -403,7 +403,7 @@ and requires the route definition to be passed as it is defined in the route.
|
|
|
403
403
|
fastify.get('/example/:file(^\\d+).png', function (request, reply) { })
|
|
404
404
|
|
|
405
405
|
console.log(fastify.hasRoute({
|
|
406
|
-
method: 'GET',
|
|
406
|
+
method: 'GET',
|
|
407
407
|
url: '/example/12345.png'
|
|
408
408
|
)); // true
|
|
409
409
|
```
|
|
@@ -414,7 +414,7 @@ console.log(fastify.hasRoute({
|
|
|
414
414
|
fastify.get('/example/:file(^\\d+).png', function (request, reply) { })
|
|
415
415
|
|
|
416
416
|
console.log(fastify.hasRoute({
|
|
417
|
-
method: 'GET',
|
|
417
|
+
method: 'GET',
|
|
418
418
|
url: '/example/:file(^\\d+).png'
|
|
419
419
|
)); // true
|
|
420
420
|
```
|
|
@@ -480,7 +480,7 @@ or as a getter
|
|
|
480
480
|
```js
|
|
481
481
|
// v5
|
|
482
482
|
fastify.decorateRequest('myObject', {
|
|
483
|
-
getter () {
|
|
483
|
+
getter () {
|
|
484
484
|
return { hello: 'world' }
|
|
485
485
|
}
|
|
486
486
|
});
|
|
@@ -316,7 +316,7 @@ based on a [route config option](../Reference/Routes.md#routes-options):
|
|
|
316
316
|
```js
|
|
317
317
|
fastify.register((instance, opts, done) => {
|
|
318
318
|
instance.decorate('util', (request, key, value) => { request[key] = value })
|
|
319
|
-
|
|
319
|
+
|
|
320
320
|
function handler(request, reply, done) {
|
|
321
321
|
instance.util(request, 'timestamp', new Date())
|
|
322
322
|
done()
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<a id="pp"></a>
|
|
9
9
|
|
|
10
10
|
Based on the article by Eran Hammer,the issue is created by a web security bug.
|
|
11
|
-
It is also a perfect illustration of the efforts required to maintain
|
|
11
|
+
It is also a perfect illustration of the efforts required to maintain
|
|
12
12
|
open-source software and the limitations of existing communication channels.
|
|
13
13
|
|
|
14
14
|
But first, if we use a JavaScript framework to process incoming JSON data, take
|
|
@@ -16,7 +16,7 @@ a moment to read up on [Prototype Poisoning](https://medium.com/intrinsic/javasc
|
|
|
16
16
|
in general, and the specific
|
|
17
17
|
[technical details](https://github.com/hapijs/hapi/issues/3916) of this issue.
|
|
18
18
|
This could be a critical issue so, we might need to verify your own code first.
|
|
19
|
-
It focuses on specific framework however, any solution that uses `JSON.parse()`
|
|
19
|
+
It focuses on specific framework however, any solution that uses `JSON.parse()`
|
|
20
20
|
to process external data is potentially at risk.
|
|
21
21
|
|
|
22
22
|
### BOOM
|
|
@@ -42,7 +42,7 @@ defect a validation library can have.
|
|
|
42
42
|
|
|
43
43
|
To understand this, we need to understand how JavaScript works a bit.
|
|
44
44
|
Every object in JavaScript can have a prototype. It is a set of methods and
|
|
45
|
-
properties it "inherits" from another object. I have put inherits in quotes
|
|
45
|
+
properties it "inherits" from another object. I have put inherits in quotes
|
|
46
46
|
because JavaScript isn't really an object-oriented language. It is a prototype-
|
|
47
47
|
based object-oriented language.
|
|
48
48
|
|
|
@@ -307,22 +307,22 @@ readinessProbe:
|
|
|
307
307
|
## Capacity Planning For Production
|
|
308
308
|
<a id="capacity"></a>
|
|
309
309
|
|
|
310
|
-
In order to rightsize the production environment for your Fastify application,
|
|
311
|
-
it is highly recommended that you perform your own measurements against
|
|
310
|
+
In order to rightsize the production environment for your Fastify application,
|
|
311
|
+
it is highly recommended that you perform your own measurements against
|
|
312
312
|
different configurations of the environment, which may
|
|
313
313
|
use real CPU cores, virtual CPU cores (vCPU), or even fractional
|
|
314
314
|
vCPU cores. We will use the term vCPU throughout this
|
|
315
315
|
recommendation to represent any CPU type.
|
|
316
316
|
|
|
317
|
-
Tools such as [k6](https://github.com/grafana/k6)
|
|
317
|
+
Tools such as [k6](https://github.com/grafana/k6)
|
|
318
318
|
or [autocannon](https://github.com/mcollina/autocannon) can be used for
|
|
319
319
|
conducting the necessary performance tests.
|
|
320
320
|
|
|
321
321
|
That said, you may also consider the following as a rule of thumb:
|
|
322
322
|
|
|
323
|
-
* To have the lowest possible latency, 2 vCPU are recommended per app
|
|
324
|
-
instance (e.g., a k8s pod). The second vCPU will mostly be used by the
|
|
325
|
-
garbage collector (GC) and libuv threadpool. This will minimize the latency
|
|
323
|
+
* To have the lowest possible latency, 2 vCPU are recommended per app
|
|
324
|
+
instance (e.g., a k8s pod). The second vCPU will mostly be used by the
|
|
325
|
+
garbage collector (GC) and libuv threadpool. This will minimize the latency
|
|
326
326
|
for your users, as well as the memory usage, as the GC will be run more
|
|
327
327
|
frequently. Also, the main thread won't have to stop to let the GC run.
|
|
328
328
|
|
|
@@ -330,7 +330,7 @@ frequently. Also, the main thread won't have to stop to let the GC run.
|
|
|
330
330
|
requests per second per vCPU available), consider using a smaller amount of vCPUs
|
|
331
331
|
per app instance. It is totally fine to run Node.js applications with 1 vCPU.
|
|
332
332
|
|
|
333
|
-
* You may experiment with an even smaller amount of vCPU, which may provide
|
|
333
|
+
* You may experiment with an even smaller amount of vCPU, which may provide
|
|
334
334
|
even better throughput in certain use-cases. There are reports of API gateway
|
|
335
335
|
solutions working well with 100m-200m vCPU in Kubernetes.
|
|
336
336
|
|
|
@@ -347,7 +347,7 @@ would be exposing metrics endpoints on a separate port,
|
|
|
347
347
|
to prevent public access, when using a reverse proxy or an ingress
|
|
348
348
|
firewall is not an option.
|
|
349
349
|
|
|
350
|
-
It is perfectly fine to spin up several Fastify instances within the same
|
|
351
|
-
Node.js process and run them concurrently, even in high load systems.
|
|
350
|
+
It is perfectly fine to spin up several Fastify instances within the same
|
|
351
|
+
Node.js process and run them concurrently, even in high load systems.
|
|
352
352
|
Each Fastify instance only generates as much load as the traffic it receives,
|
|
353
353
|
plus the memory used for that Fastify instance.
|
|
@@ -36,10 +36,10 @@ snippet of code.
|
|
|
36
36
|
|
|
37
37
|
To integrate with AWS, you have two choices of library:
|
|
38
38
|
|
|
39
|
-
- Using [@fastify/aws-lambda](https://github.com/fastify/aws-lambda-fastify)
|
|
39
|
+
- Using [@fastify/aws-lambda](https://github.com/fastify/aws-lambda-fastify)
|
|
40
40
|
which only adds API Gateway support but has heavy optimizations for fastify.
|
|
41
|
-
- Using [@h4ad/serverless-adapter](https://github.com/H4ad/serverless-adapter)
|
|
42
|
-
which is a little slower as it creates an HTTP request for each AWS event but
|
|
41
|
+
- Using [@h4ad/serverless-adapter](https://github.com/H4ad/serverless-adapter)
|
|
42
|
+
which is a little slower as it creates an HTTP request for each AWS event but
|
|
43
43
|
has support for more AWS services such as: AWS SQS, AWS SNS and others.
|
|
44
44
|
|
|
45
45
|
So you can decide which option is best for you, but you can test both libraries.
|
|
@@ -263,7 +263,7 @@ curl -X POST https://$GOOGLE_REGION-$GOOGLE_PROJECT.cloudfunctions.net/me \
|
|
|
263
263
|
|
|
264
264
|
## Google Firebase Functions
|
|
265
265
|
|
|
266
|
-
Follow this guide if you want to use Fastify as the HTTP framework for
|
|
266
|
+
Follow this guide if you want to use Fastify as the HTTP framework for
|
|
267
267
|
Firebase Functions instead of the vanilla JavaScript router provided with
|
|
268
268
|
`onRequest(async (req, res) => {}`.
|
|
269
269
|
|
|
@@ -280,7 +280,7 @@ const { onRequest } = require("firebase-functions/v2/https")
|
|
|
280
280
|
### Creation of Fastify instance
|
|
281
281
|
|
|
282
282
|
Create the Fastify instance and encapsulate the returned application instance
|
|
283
|
-
in a function which will register routes, await the server's processing of
|
|
283
|
+
in a function which will register routes, await the server's processing of
|
|
284
284
|
plugins, hooks and other settings. As follows:
|
|
285
285
|
|
|
286
286
|
```js
|
package/docs/Guides/Testing.md
CHANGED
|
@@ -264,7 +264,7 @@ test('should work with undici', async t => {
|
|
|
264
264
|
'http://localhost:' + fastify.server.address().port, {
|
|
265
265
|
keepAliveTimeout: 10,
|
|
266
266
|
keepAliveMaxTimeout: 10
|
|
267
|
-
}
|
|
267
|
+
}
|
|
268
268
|
)
|
|
269
269
|
|
|
270
270
|
t.after(() => {
|
|
@@ -279,8 +279,8 @@ test('should work with undici', async t => {
|
|
|
279
279
|
})
|
|
280
280
|
```
|
|
281
281
|
|
|
282
|
-
Alternatively, starting with Node.js 18,
|
|
283
|
-
[`fetch`](https://nodejs.org/docs/latest-v18.x/api/globals.html#fetch)
|
|
282
|
+
Alternatively, starting with Node.js 18,
|
|
283
|
+
[`fetch`](https://nodejs.org/docs/latest-v18.x/api/globals.html#fetch)
|
|
284
284
|
may be used without requiring any extra dependencies:
|
|
285
285
|
|
|
286
286
|
**test-listen.js**
|
|
@@ -296,7 +296,7 @@ test('should work with fetch', async t => {
|
|
|
296
296
|
t.after(() => fastify.close())
|
|
297
297
|
|
|
298
298
|
await fastify.listen()
|
|
299
|
-
|
|
299
|
+
|
|
300
300
|
const response = await fetch(
|
|
301
301
|
'http://localhost:' + fastify.server.address().port
|
|
302
302
|
)
|
|
@@ -386,7 +386,7 @@ test("Test the Plugin Route", async t => {
|
|
|
386
386
|
|
|
387
387
|
fastify.register(myPlugin)
|
|
388
388
|
|
|
389
|
-
// Add an endpoint of your choice
|
|
389
|
+
// Add an endpoint of your choice
|
|
390
390
|
fastify.get("/", async (request, reply) => {
|
|
391
391
|
return ({ message: request.helloRequest })
|
|
392
392
|
})
|
|
@@ -396,7 +396,7 @@ test("Test the Plugin Route", async t => {
|
|
|
396
396
|
method: "GET",
|
|
397
397
|
url: "/"
|
|
398
398
|
})
|
|
399
|
-
|
|
399
|
+
|
|
400
400
|
console.log('status code: ', fastifyResponse.statusCode)
|
|
401
401
|
console.log('body: ', fastifyResponse.body)
|
|
402
402
|
})
|
|
@@ -440,7 +440,7 @@ test("Test the Plugin Route", async t => {
|
|
|
440
440
|
method: "GET",
|
|
441
441
|
url: "/"
|
|
442
442
|
})
|
|
443
|
-
|
|
443
|
+
|
|
444
444
|
t.assert.strictEqual(fastifyResponse.statusCode, 200)
|
|
445
445
|
t.assert.deepStrictEqual(JSON.parse(fastifyResponse.body), { message: "Hello World" })
|
|
446
446
|
})
|
|
@@ -465,7 +465,7 @@ test("Test the Plugin Route", async t => {
|
|
|
465
465
|
|
|
466
466
|
fastify.get("/", async (request, reply) => {
|
|
467
467
|
// Testing the fastify decorators
|
|
468
|
-
t.assert.ifError(request.helloRequest)
|
|
468
|
+
t.assert.ifError(request.helloRequest)
|
|
469
469
|
t.assert.ok(request.helloRequest, "Hello World")
|
|
470
470
|
t.assert.ok(fastify.helloInstance, "Hello Fastify Instance")
|
|
471
471
|
return ({ message: request.helloRequest })
|
|
@@ -63,7 +63,7 @@ among different versions of its dependencies.
|
|
|
63
63
|
We do not enforce any testing library. We use [`node:test`](https://nodejs.org/api/test.html)
|
|
64
64
|
since it offers out-of-the-box parallel testing and code coverage, but it is up
|
|
65
65
|
to you to choose your library of preference.
|
|
66
|
-
We highly recommend you read the [Plugin Testing](./Testing.md#plugins) to
|
|
66
|
+
We highly recommend you read the [Plugin Testing](./Testing.md#plugins) to
|
|
67
67
|
learn about how to test your plugins.
|
|
68
68
|
|
|
69
69
|
## Code Linter
|
|
@@ -10,9 +10,9 @@ Whereas exhaustive type narrowing checks normally rely on `never` to represent
|
|
|
10
10
|
an unreachable state, reduction in type provider interfaces should only be done
|
|
11
11
|
up to `unknown`.
|
|
12
12
|
|
|
13
|
-
The reasoning is that certain methods of `FastifyInstance` are
|
|
14
|
-
contravariant on `TypeProvider`, which can lead to TypeScript surfacing
|
|
15
|
-
assignability issues unless the custom type provider interface is
|
|
13
|
+
The reasoning is that certain methods of `FastifyInstance` are
|
|
14
|
+
contravariant on `TypeProvider`, which can lead to TypeScript surfacing
|
|
15
|
+
assignability issues unless the custom type provider interface is
|
|
16
16
|
substitutable with `FastifyTypeProviderDefault`.
|
|
17
17
|
|
|
18
18
|
For example, `FastifyTypeProviderDefault` will not be assignable to the following:
|
|
@@ -59,7 +59,7 @@ close as possible to the value intended to be set dynamically in the future.
|
|
|
59
59
|
Initialize a decorator as a `''` if the intended value is a string, and as
|
|
60
60
|
`null` if it will be an object or a function.
|
|
61
61
|
|
|
62
|
-
Remember this example works only with value types as reference types will
|
|
62
|
+
Remember this example works only with value types as reference types will
|
|
63
63
|
thrown and error during the fastify startup. See [decorateRequest](#decorate-request).
|
|
64
64
|
|
|
65
65
|
See [JavaScript engine fundamentals: Shapes and Inline
|
|
@@ -109,7 +109,7 @@ fastify.decorate('db', new DbConnection())
|
|
|
109
109
|
fastify.get('/', async function (request, reply) {
|
|
110
110
|
// using return
|
|
111
111
|
return { hello: await this.db.query('world') }
|
|
112
|
-
|
|
112
|
+
|
|
113
113
|
// or
|
|
114
114
|
// using reply.send()
|
|
115
115
|
reply.send({ hello: await this.db.query('world') })
|