fastify 4.1.0 → 4.3.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 +13 -14
- package/docs/Guides/Database.md +2 -2
- package/docs/Guides/Delay-Accepting-Requests.md +1 -1
- package/docs/Guides/Ecosystem.md +31 -16
- package/docs/Guides/Migration-Guide-V4.md +69 -1
- package/docs/Guides/Plugins-Guide.md +5 -0
- package/docs/Guides/Serverless.md +23 -10
- package/docs/Reference/HTTP2.md +1 -3
- package/docs/Reference/Hooks.md +52 -0
- package/docs/Reference/Plugins.md +1 -1
- package/docs/Reference/Reply.md +176 -0
- package/docs/Reference/Request.md +171 -0
- package/docs/Reference/Type-Providers.md +1 -15
- package/docs/Reference/TypeScript.md +65 -28
- package/docs/Reference/Validation-and-Serialization.md +11 -0
- package/docs/index.md +1 -1
- package/fastify.d.ts +3 -3
- package/fastify.js +2 -2
- package/integration/server.js +27 -0
- package/integration/test.sh +23 -0
- package/lib/contentTypeParser.js +10 -2
- package/lib/context.js +14 -2
- package/lib/error-serializer.js +24 -27
- package/lib/errors.js +8 -0
- package/lib/handleRequest.js +1 -1
- package/lib/reply.js +101 -24
- package/lib/request.js +97 -1
- package/lib/route.js +41 -29
- package/lib/symbols.js +17 -10
- package/lib/validation.js +2 -0
- package/package.json +9 -9
- package/test/build/error-serializer.test.js +3 -1
- package/test/content-parser.test.js +15 -0
- package/test/hooks.test.js +21 -0
- package/test/internals/reply-serialize.test.js +583 -0
- package/test/internals/request-validate.test.js +1269 -0
- package/test/internals/request.test.js +11 -2
- package/test/pretty-print.test.js +3 -3
- package/test/reply-error.test.js +1 -1
- package/test/request-error.test.js +44 -1
- package/test/schema-feature.test.js +2 -2
- package/test/schema-validation.test.js +71 -0
- package/test/types/fastify.test-d.ts +24 -2
- package/test/types/hooks.test-d.ts +1 -2
- package/test/types/import.ts +1 -1
- package/test/types/instance.test-d.ts +4 -1
- package/test/types/request.test-d.ts +8 -4
- package/test/types/type-provider.test-d.ts +87 -8
- package/test/validation-error-handling.test.js +38 -1
- package/types/hooks.d.ts +19 -39
- package/types/instance.d.ts +78 -130
- package/types/reply.d.ts +5 -0
- package/types/request.d.ts +16 -3
- package/types/route.d.ts +25 -33
- package/types/schema.d.ts +4 -1
- package/types/type-provider.d.ts +19 -11
package/README.md
CHANGED
|
@@ -38,18 +38,18 @@ resources of your server, knowing that you are serving the highest number of
|
|
|
38
38
|
requests as possible, without sacrificing security validations and handy
|
|
39
39
|
development?
|
|
40
40
|
|
|
41
|
-
- [Quick start](
|
|
42
|
-
- [Install](
|
|
43
|
-
- [Example](
|
|
44
|
-
- [Fastify v1.x and v2.x](
|
|
45
|
-
- [Core features](
|
|
46
|
-
- [Benchmarks](
|
|
47
|
-
- [Documentation](
|
|
48
|
-
- [Ecosystem](
|
|
49
|
-
- [Support](
|
|
50
|
-
- [Team](
|
|
51
|
-
- [Hosted by](
|
|
52
|
-
- [License](
|
|
41
|
+
- [Quick start](#quick-start)
|
|
42
|
+
- [Install](#install)
|
|
43
|
+
- [Example](#example)
|
|
44
|
+
- [Fastify v1.x and v2.x](#fastify-v1x-and-v2x)
|
|
45
|
+
- [Core features](#core-features)
|
|
46
|
+
- [Benchmarks](#benchmarks)
|
|
47
|
+
- [Documentation](#documentation)
|
|
48
|
+
- [Ecosystem](#ecosystem)
|
|
49
|
+
- [Support](#support)
|
|
50
|
+
- [Team](#team)
|
|
51
|
+
- [Hosted by](#hosted-by)
|
|
52
|
+
- [License](#license)
|
|
53
53
|
|
|
54
54
|
Enter Fastify. Fastify is a web framework highly focused on providing the best
|
|
55
55
|
developer experience with the least overhead and a powerful plugin architecture.
|
|
@@ -99,8 +99,7 @@ generate functionality of [Fastify CLI](https://github.com/fastify/fastify-cli).
|
|
|
99
99
|
|
|
100
100
|
### Install
|
|
101
101
|
|
|
102
|
-
|
|
103
|
-
project as a dependency:
|
|
102
|
+
To install Fastify in an existing project as a dependency:
|
|
104
103
|
|
|
105
104
|
Install with npm:
|
|
106
105
|
```sh
|
package/docs/Guides/Database.md
CHANGED
|
@@ -204,7 +204,7 @@ function knexPlugin(fastify, options, done) {
|
|
|
204
204
|
done()
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
export default fp(
|
|
207
|
+
export default fp(knexPlugin, { name: 'fastify-knex-example' })
|
|
208
208
|
```
|
|
209
209
|
|
|
210
210
|
### Writing a plugin for a database engine
|
|
@@ -213,7 +213,7 @@ In this example, we will create a basic Fastify MySQL plugin from scratch (it is
|
|
|
213
213
|
a stripped-down example, please use the official plugin in production).
|
|
214
214
|
|
|
215
215
|
```javascript
|
|
216
|
-
const fp = require('
|
|
216
|
+
const fp = require('fastify-plugin')
|
|
217
217
|
const mysql = require('mysql2/promise')
|
|
218
218
|
|
|
219
219
|
function fastifyMysql(fastify, options, done) {
|
|
@@ -48,7 +48,7 @@ server (fewer resources allocated to a bound-to-fail task) and for the client
|
|
|
48
48
|
That will be achieved by wrapping into a custom plugin two main features:
|
|
49
49
|
|
|
50
50
|
1. the mechanism for authenticating with the provider
|
|
51
|
-
[decorating](../
|
|
51
|
+
[decorating](../Reference/Decorators.md) the `fastify` object with the
|
|
52
52
|
authentication key (`magicKey` from here onwards)
|
|
53
53
|
1. the mechanism for denying requests that would, otherwise, fail
|
|
54
54
|
|
package/docs/Guides/Ecosystem.md
CHANGED
|
@@ -132,9 +132,15 @@ section.
|
|
|
132
132
|
sampling process metrics.
|
|
133
133
|
- [`@dnlup/fastify-traps`](https://github.com/dnlup/fastify-traps) A plugin to
|
|
134
134
|
close the server gracefully on `SIGINT` and `SIGTERM` signals.
|
|
135
|
+
- [`@eropple/fastify-openapi3`](https://github.com/eropple/fastify-openapi3) Provides
|
|
136
|
+
easy, developer-friendly OpenAPI 3.1 specs + doc explorer based on your routes.
|
|
135
137
|
- [`@gquittet/graceful-server`](https://github.com/gquittet/graceful-server)
|
|
136
138
|
Tiny (~5k), Fast, KISS, and dependency-free Node.JS library to make your
|
|
137
139
|
Fastify API graceful.
|
|
140
|
+
- [`@h4ad/serverless-adapter`](https://github.com/H4ad/serverless-adapter)
|
|
141
|
+
Run REST APIs and other web applications using your existing Node.js
|
|
142
|
+
application framework (Express, Koa, Hapi and Fastify), on top of AWS Lambda,
|
|
143
|
+
Huawei and many other clouds.
|
|
138
144
|
- [`@immobiliarelabs/fastify-metrics`](https://github.com/immobiliare/fastify-metrics)
|
|
139
145
|
Minimalistic and opinionated plugin that collects usage/process metrics and
|
|
140
146
|
dispatches to [statsd](https://github.com/statsd/statsd).
|
|
@@ -145,12 +151,12 @@ section.
|
|
|
145
151
|
A plugin to close the server gracefully
|
|
146
152
|
- [`@mgcrea/fastify-request-logger`](https://github.com/mgcrea/fastify-request-logger)
|
|
147
153
|
A plugin to enable compact request logging for Fastify
|
|
154
|
+
- [`@mgcrea/fastify-session`](https://github.com/mgcrea/fastify-session) Session
|
|
155
|
+
plugin for Fastify that supports both stateless and stateful sessions
|
|
148
156
|
- [`@mgcrea/fastify-session-redis-store`](https://github.com/mgcrea/fastify-session-redis-store)
|
|
149
157
|
Redis store for @mgcrea/fastify-session using ioredis
|
|
150
158
|
- [`@mgcrea/fastify-session-sodium-crypto`](https://github.com/mgcrea/fastify-session-sodium-crypto)
|
|
151
159
|
Fast sodium-based crypto for @mgcrea/fastify-session
|
|
152
|
-
- [`@mgcrea/fastify-session`](https://github.com/mgcrea/fastify-session) Session
|
|
153
|
-
plugin for Fastify that supports both stateless and stateful sessions
|
|
154
160
|
- [`@mgcrea/pino-pretty-compact`](https://github.com/mgcrea/pino-pretty-compact)
|
|
155
161
|
A custom compact pino-base prettifier
|
|
156
162
|
- [`@trubavuong/fastify-seaweedfs`](https://github.com/trubavuong/fastify-seaweedfs)
|
|
@@ -163,6 +169,10 @@ section.
|
|
|
163
169
|
- [`cls-rtracer`](https://github.com/puzpuzpuz/cls-rtracer) Fastify middleware
|
|
164
170
|
for CLS-based request ID generation. An out-of-the-box solution for adding
|
|
165
171
|
request IDs into your logs.
|
|
172
|
+
- [`electron-server`](https://github.com/anonrig/electron-server) A plugin for
|
|
173
|
+
using Fastify without the need of consuming a port on Electron apps.
|
|
174
|
+
- [`fast-water`](https://github.com/tswayne/fast-water) A Fastify plugin for
|
|
175
|
+
waterline. Decorates Fastify with waterline models.
|
|
166
176
|
- [`fastify-405`](https://github.com/Eomm/fastify-405) Fastify plugin that adds
|
|
167
177
|
405 HTTP status to your routes
|
|
168
178
|
- [`fastify-allow`](https://github.com/mattbishop/fastify-allow) Fastify plugin
|
|
@@ -281,13 +291,13 @@ section.
|
|
|
281
291
|
good Fastify sessions plugin focused on speed.
|
|
282
292
|
- [`fastify-google-cloud-storage`](https://github.com/carlozamagni/fastify-google-cloud-storage)
|
|
283
293
|
Fastify plugin that exposes a GCP Cloud Storage client instance.
|
|
294
|
+
- [`fastify-graceful-shutdown`](https://github.com/hemerajs/fastify-graceful-shutdown)
|
|
295
|
+
Shutdown Fastify gracefully and asynchronously.
|
|
284
296
|
- [`fastify-grant`](https://github.com/simov/fastify-grant)
|
|
285
297
|
Authentication/Authorization plugin for Fastify that supports 200+ OAuth
|
|
286
298
|
Providers.
|
|
287
299
|
- [`fastify-guard`](https://github.com/hsynlms/fastify-guard) A Fastify plugin
|
|
288
300
|
that protects endpoints by checking authenticated user roles and/or scopes.
|
|
289
|
-
- [`fastify-graceful-shutdown`](https://github.com/hemerajs/fastify-graceful-shutdown)
|
|
290
|
-
Shutdown Fastify gracefully and asynchronously.
|
|
291
301
|
- [`fastify-hasura`](https://github.com/ManUtopiK/fastify-hasura) A Fastify
|
|
292
302
|
plugin to have fun with [Hasura](https://github.com/hasura/graphql-engine).
|
|
293
303
|
- [`fastify-healthcheck`](https://github.com/smartiniOnGitHub/fastify-healthcheck)
|
|
@@ -295,20 +305,19 @@ section.
|
|
|
295
305
|
- [`fastify-hemera`](https://github.com/hemerajs/fastify-hemera) Fastify Hemera
|
|
296
306
|
plugin, for writing reliable & fault-tolerant microservices with
|
|
297
307
|
[nats.io](https://nats.io/).
|
|
308
|
+
- [`fastify-http-client`](https://github.com/kenuyx/fastify-http-client) Plugin
|
|
309
|
+
to send HTTP(s) requests. Built upon [urllib](https://github.com/node-modules/urllib).
|
|
298
310
|
- [`fastify-http-context`](https://github.com/thorough-developer/fastify-http-context)
|
|
299
311
|
Fastify plugin for "simulating" a thread of execution to allow for true HTTP
|
|
300
312
|
context to take place per API call within the Fastify lifecycle of calls.
|
|
313
|
+
- [`fastify-http-errors-enhanced`](https://github.com/ShogunPanda/fastify-http-errors-enhanced)
|
|
314
|
+
An error handling plugin for Fastify that uses enhanced HTTP errors.
|
|
301
315
|
- [`fastify-http2https`](https://github.com/lolo32/fastify-http2https) Redirect
|
|
302
316
|
HTTP requests to HTTPS, both using the same port number, or different response
|
|
303
317
|
on HTTP and HTTPS.
|
|
304
|
-
- [`fastify-http-client`](https://github.com/kenuyx/fastify-http-client) Plugin
|
|
305
|
-
to send HTTP(s) requests. Built upon
|
|
306
|
-
[urllib](https://github.com/node-modules/urllib).
|
|
307
|
-
- [`fastify-http-errors-enhanced`](https://github.com/ShogunPanda/fastify-http-errors-enhanced)
|
|
308
|
-
An error handling plugin for Fastify that uses enhanced HTTP errors.
|
|
309
318
|
- [`fastify-https-redirect`](https://github.com/tomsvogel/fastify-https-redirect)
|
|
310
319
|
Fastify plugin for auto-redirect from HTTP to HTTPS.
|
|
311
|
-
- [`
|
|
320
|
+
- [`fastify-impressions`](https://github.com/manju4ever/fastify-impressions)
|
|
312
321
|
Fastify plugin to track impressions of all the routes.
|
|
313
322
|
- [`fastify-influxdb`](https://github.com/alex-ppg/fastify-influxdb) Fastify
|
|
314
323
|
InfluxDB plugin connecting to an InfluxDB instance via the Influx default
|
|
@@ -327,6 +336,8 @@ section.
|
|
|
327
336
|
Kubernetes client plugin.
|
|
328
337
|
- [`fastify-language-parser`](https://github.com/lependu/fastify-language-parser)
|
|
329
338
|
Fastify plugin to parse request language.
|
|
339
|
+
- [`fastify-lcache`](https://github.com/denbon05/fastify-lcache)
|
|
340
|
+
Lightweight cache plugin
|
|
330
341
|
- [`fastify-loader`](https://github.com/TheNoim/fastify-loader) Load routes from
|
|
331
342
|
a directory and inject the Fastify instance in each file.
|
|
332
343
|
- [`fastify-lured`](https://github.com/lependu/fastify-lured) Plugin to load lua
|
|
@@ -400,10 +411,10 @@ section.
|
|
|
400
411
|
- [`fastify-orientdb`](https://github.com/mahmed8003/fastify-orientdb) Fastify
|
|
401
412
|
OrientDB connection plugin, with which you can share the OrientDB connection
|
|
402
413
|
across every part of your server.
|
|
403
|
-
- [`fastify-piscina`](https://github.com/piscinajs/fastify-piscina) A worker
|
|
404
|
-
thread pool plugin using [Piscina](https://github.com/piscinajs/piscina).
|
|
405
414
|
- [`fastify-peekaboo`](https://github.com/simone-sanfratello/fastify-peekaboo)
|
|
406
415
|
Fastify plugin for memoize responses by expressive settings.
|
|
416
|
+
- [`fastify-piscina`](https://github.com/piscinajs/fastify-piscina) A worker
|
|
417
|
+
thread pool plugin using [Piscina](https://github.com/piscinajs/piscina).
|
|
407
418
|
- [`fastify-polyglot`](https://github.com/heply/fastify-polyglot) A plugin to
|
|
408
419
|
handle i18n using
|
|
409
420
|
[node-polyglot](https://www.npmjs.com/package/node-polyglot).
|
|
@@ -436,10 +447,10 @@ section.
|
|
|
436
447
|
- [`fastify-register-routes`](https://github.com/israeleriston/fastify-register-routes)
|
|
437
448
|
Plugin to automatically load routes from a specified path and optionally limit
|
|
438
449
|
loaded file names by a regular expression.
|
|
439
|
-
- [`fastify-response-time`](https://github.com/lolo32/fastify-response-time) Add
|
|
440
|
-
`X-Response-Time` header at each request for Fastify, in milliseconds.
|
|
441
450
|
- [`fastify-response-caching`](https://github.com/codeaholicguy/fastify-response-caching)
|
|
442
451
|
A Fastify plugin for caching the response.
|
|
452
|
+
- [`fastify-response-time`](https://github.com/lolo32/fastify-response-time) Add
|
|
453
|
+
`X-Response-Time` header at each request for Fastify, in milliseconds.
|
|
443
454
|
- [`fastify-resty`](https://github.com/FastifyResty/fastify-resty) Fastify-based
|
|
444
455
|
web framework with REST API routes auto-generation for TypeORM entities using
|
|
445
456
|
DI and decorators.
|
|
@@ -478,6 +489,8 @@ section.
|
|
|
478
489
|
Events with `reply.sse( … )` to Fastify.
|
|
479
490
|
- [`fastify-sse-v2`](https://github.com/nodefactoryio/fastify-sse-v2) to provide
|
|
480
491
|
Server-Sent Events using Async Iterators (supports newer versions of Fastify).
|
|
492
|
+
- [`fastify-ssr-vite`](https://github.com/nineohnine/fastify-ssr-vite) A simple
|
|
493
|
+
plugin for setting up server side rendering with vite.
|
|
481
494
|
- [`fastify-stripe`](https://github.com/coopflow/fastify-stripe) Plugin to
|
|
482
495
|
initialize and encapsulate [Stripe
|
|
483
496
|
Node.js](https://github.com/stripe/stripe-node) instances in Fastify.
|
|
@@ -508,8 +521,6 @@ section.
|
|
|
508
521
|
should use.
|
|
509
522
|
- [`fastify-wamp-router`](https://github.com/lependu/fastify-wamp-router) Web
|
|
510
523
|
Application Messaging Protocol router for Fastify.
|
|
511
|
-
- [`fast-water`](https://github.com/tswayne/fast-water) A Fastify plugin for
|
|
512
|
-
waterline. Decorates Fastify with waterline models.
|
|
513
524
|
- [`fastify-webpack-hmr`](https://github.com/lependu/fastify-webpack-hmr)
|
|
514
525
|
Webpack hot module reloading plugin for Fastify.
|
|
515
526
|
- [`fastify-webpack-hot`](https://github.com/gajus/fastify-webpack-hot) Webpack
|
|
@@ -542,7 +553,11 @@ section.
|
|
|
542
553
|
Fastify.
|
|
543
554
|
- [`sequelize-fastify`](https://github.com/hsynlms/sequelize-fastify) A simple
|
|
544
555
|
and lightweight Sequelize plugin for Fastify.
|
|
556
|
+
- [`typeorm-fastify-plugin`](https://github.com/jclemens24/fastify-typeorm) A simple
|
|
557
|
+
and updated Typeorm plugin for use with Fastify.
|
|
545
558
|
|
|
546
559
|
#### [Community Tools](#community-tools)
|
|
547
560
|
- [`fast-maker`](https://github.com/imjuni/fast-maker) route configuration
|
|
548
561
|
generator by directory structure.
|
|
562
|
+
- [`simple-tjscli`](https://github.com/imjuni/simple-tjscli) CLI tool to
|
|
563
|
+
generate JSON Schema from TypeScript interfaces.
|
|
@@ -8,7 +8,39 @@ work after upgrading.
|
|
|
8
8
|
|
|
9
9
|
## Breaking Changes
|
|
10
10
|
|
|
11
|
-
###
|
|
11
|
+
### Error handling composition ([#3261](https://github.com/fastify/fastify/pull/3261))
|
|
12
|
+
|
|
13
|
+
When an error is thrown in a async error handler function,
|
|
14
|
+
the upper-level error handler is executed if set.
|
|
15
|
+
If there is not a upper-level error handler, the default will
|
|
16
|
+
be executed as it was previously.
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
import Fastify from 'fastify'
|
|
20
|
+
|
|
21
|
+
const fastify = Fastify()
|
|
22
|
+
|
|
23
|
+
fastify.register(async fastify => {
|
|
24
|
+
fastify.setErrorHandler(async err => {
|
|
25
|
+
console.log(err.message) // 'kaboom'
|
|
26
|
+
throw new Error('caught')
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
fastify.get('/encapsulated', async () => {
|
|
30
|
+
throw new Error('kaboom')
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
fastify.setErrorHandler(async err => {
|
|
35
|
+
console.log(err.message) // 'caught'
|
|
36
|
+
throw new Error('wrapped')
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const res = await fastify.inject('/encapsulated')
|
|
40
|
+
console.log(res.json().message) // 'wrapped'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Deprecation of `app.use()` ([#3506](https://github.com/fastify/fastify/pull/3506))
|
|
12
44
|
|
|
13
45
|
Starting this version of Fastify, we have deprecated the use of `app.use()`. We
|
|
14
46
|
have decided not to support the use of middlewares. Both
|
|
@@ -33,6 +65,35 @@ Starting from v4, all the `GET` routes will create a sibling `HEAD` route.
|
|
|
33
65
|
You can revert this behaviour by setting the server's option `exposeHeadRoutes`
|
|
34
66
|
to `false`.
|
|
35
67
|
|
|
68
|
+
### Synchronous route definitions
|
|
69
|
+
|
|
70
|
+
The route registration has been made synchronous from v4.
|
|
71
|
+
This change was done to provide better error reporting for route definition.
|
|
72
|
+
As a result if you specify an `onRoute` hook in a plugin you should either:
|
|
73
|
+
* wrap your routes in a plugin (recommended)
|
|
74
|
+
* use `await register(...)`
|
|
75
|
+
|
|
76
|
+
For example refactor this:
|
|
77
|
+
```
|
|
78
|
+
fastify.register((instance, opts, done) => {
|
|
79
|
+
instance.addHook('onRoute', (routeOptions) => {
|
|
80
|
+
const { path, method } = routeOptions;
|
|
81
|
+
console.log({ path, method });
|
|
82
|
+
});
|
|
83
|
+
done();
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
Into this:
|
|
87
|
+
```
|
|
88
|
+
await fastify.register((instance, opts, done) => {
|
|
89
|
+
instance.addHook('onRoute', (routeOptions) => {
|
|
90
|
+
const { path, method } = routeOptions;
|
|
91
|
+
console.log({ path, method });
|
|
92
|
+
});
|
|
93
|
+
done();
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
36
97
|
## Non Breaking Changes
|
|
37
98
|
|
|
38
99
|
### Change of schema for multiple types
|
|
@@ -70,3 +131,10 @@ properties: {
|
|
|
70
131
|
}
|
|
71
132
|
}
|
|
72
133
|
```
|
|
134
|
+
|
|
135
|
+
### Add `reply.trailers` methods ([#3794](https://github.com/fastify/fastify/pull/3794))
|
|
136
|
+
|
|
137
|
+
Fastify now supports the [HTTP Trailer] response headers.
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
[HTTP Trailer]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Trailer
|
|
@@ -196,6 +196,11 @@ fastify.get('/html', (request, reply) => {
|
|
|
196
196
|
reply.html({ hello: 'world' })
|
|
197
197
|
})
|
|
198
198
|
```
|
|
199
|
+
Reminder that the `this` keyword is not available on *arrow functions*,
|
|
200
|
+
so when passing functions in *`decorateReply`* and *`decorateRequest`* as
|
|
201
|
+
a utility that also needs access to the `request` and `reply` instance,
|
|
202
|
+
a function that is defined using the `function` keyword is needed instead
|
|
203
|
+
of an *arrow function expression*.
|
|
199
204
|
|
|
200
205
|
In the same way you can do this for the `request` object:
|
|
201
206
|
```js
|
|
@@ -24,23 +24,31 @@ snippet of code.
|
|
|
24
24
|
|
|
25
25
|
### Contents
|
|
26
26
|
|
|
27
|
-
- [AWS
|
|
27
|
+
- [AWS](#aws)
|
|
28
28
|
- [Google Cloud Functions](#google-cloud-functions)
|
|
29
29
|
- [Google Cloud Run](#google-cloud-run)
|
|
30
30
|
- [Netlify Lambda](#netlify-lambda)
|
|
31
31
|
- [Vercel](#vercel)
|
|
32
32
|
|
|
33
|
-
## AWS
|
|
33
|
+
## AWS
|
|
34
|
+
|
|
35
|
+
To integrate with AWS, you have two choices of library:
|
|
36
|
+
|
|
37
|
+
- Using [@fastify/aws-lambda](https://github.com/fastify/aws-lambda-fastify)
|
|
38
|
+
which only adds API Gateway support but has heavy optimizations for fastify.
|
|
39
|
+
- Using [@h4ad/serverless-adapter](https://github.com/H4ad/serverless-adapter)
|
|
40
|
+
which is a little slower as it creates an HTTP request for each AWS event but
|
|
41
|
+
has support for more AWS services such as: AWS SQS, AWS SNS and others.
|
|
42
|
+
|
|
43
|
+
So you can decide which option is best for you, but you can test both libraries.
|
|
44
|
+
|
|
45
|
+
### Using @fastify/aws-lambda
|
|
34
46
|
|
|
35
47
|
The sample provided allows you to easily build serverless web
|
|
36
48
|
applications/services and RESTful APIs using Fastify on top of AWS Lambda and
|
|
37
49
|
Amazon API Gateway.
|
|
38
50
|
|
|
39
|
-
|
|
40
|
-
[@fastify/aws-lambda](https://github.com/fastify/aws-lambda-fastify) is just one
|
|
41
|
-
possible way.*
|
|
42
|
-
|
|
43
|
-
### app.js
|
|
51
|
+
#### app.js
|
|
44
52
|
|
|
45
53
|
```js
|
|
46
54
|
const fastify = require('fastify');
|
|
@@ -71,7 +79,7 @@ When you execute your Fastify application like always, i.e. `node app.js` *(the
|
|
|
71
79
|
detection for this could be `require.main === module`)*, you can normally listen
|
|
72
80
|
to your port, so you can still run your Fastify function locally.
|
|
73
81
|
|
|
74
|
-
|
|
82
|
+
#### lambda.js
|
|
75
83
|
|
|
76
84
|
```js
|
|
77
85
|
const awsLambdaFastify = require('@fastify/aws-lambda')
|
|
@@ -99,14 +107,13 @@ signature to be used as a lambda `handler` function. This way all the incoming
|
|
|
99
107
|
events (API Gateway requests) are passed to the `proxy` function of
|
|
100
108
|
[@fastify/aws-lambda](https://github.com/fastify/aws-lambda-fastify).
|
|
101
109
|
|
|
102
|
-
|
|
110
|
+
#### Example
|
|
103
111
|
|
|
104
112
|
An example deployable with
|
|
105
113
|
[claudia.js](https://claudiajs.com/tutorials/serverless-express.html) can be
|
|
106
114
|
found
|
|
107
115
|
[here](https://github.com/claudiajs/example-projects/tree/master/fastify-app-lambda).
|
|
108
116
|
|
|
109
|
-
|
|
110
117
|
### Considerations
|
|
111
118
|
|
|
112
119
|
- API Gateway does not support streams yet, so you are not able to handle
|
|
@@ -114,6 +121,12 @@ found
|
|
|
114
121
|
- API Gateway has a timeout of 29 seconds, so it is important to provide a reply
|
|
115
122
|
during this time.
|
|
116
123
|
|
|
124
|
+
#### Beyond API Gateway
|
|
125
|
+
|
|
126
|
+
If you need to integrate with more AWS services, take a look at
|
|
127
|
+
[@h4ad/serverless-adapter](https://viniciusl.com.br/serverless-adapter/docs/main/frameworks/fastify)
|
|
128
|
+
on Fastify to find out how to integrate.
|
|
129
|
+
|
|
117
130
|
## Google Cloud Functions
|
|
118
131
|
|
|
119
132
|
### Creation of Fastify instance
|
package/docs/Reference/HTTP2.md
CHANGED
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## HTTP2
|
|
4
4
|
|
|
5
|
-
_Fastify_
|
|
6
|
-
which includes HTTP2 without a flag; HTTP2 is supported over either HTTPS or
|
|
7
|
-
plaintext.
|
|
5
|
+
_Fastify_ supports HTTP2 over either HTTPS (h2) or plaintext (h2c).
|
|
8
6
|
|
|
9
7
|
Currently, none of the HTTP2-specific APIs are available through _Fastify_, but
|
|
10
8
|
Node's `req` and `res` can be accessed through our `Request` and `Reply`
|
package/docs/Reference/Hooks.md
CHANGED
|
@@ -28,6 +28,7 @@ are Request/Reply hooks and application hooks:
|
|
|
28
28
|
- [onRegister](#onregister)
|
|
29
29
|
- [Scope](#scope)
|
|
30
30
|
- [Route level hooks](#route-level-hooks)
|
|
31
|
+
- [Using Hooks to Inject Custom Properties](#using-hooks-to-inject-custom-properties)
|
|
31
32
|
- [Diagnostics Channel Hooks](#diagnostics-channel-hooks)
|
|
32
33
|
|
|
33
34
|
**Notice:** the `done` callback is not available when using `async`/`await` or
|
|
@@ -649,6 +650,57 @@ fastify.route({
|
|
|
649
650
|
|
|
650
651
|
**Note**: both options also accept an array of functions.
|
|
651
652
|
|
|
653
|
+
## Using Hooks to Inject Custom Properties
|
|
654
|
+
<a id="using-hooks-to-inject-custom-properties"></a>
|
|
655
|
+
|
|
656
|
+
You can use a hook to inject custom properties into incoming requests.
|
|
657
|
+
This is useful for reusing processed data from hooks in controllers.
|
|
658
|
+
|
|
659
|
+
A very common use case is, for example, checking user authentication based
|
|
660
|
+
on their token and then storing their recovered data into
|
|
661
|
+
the [Request](./Request.md) instance. This way, your controllers can read it
|
|
662
|
+
easily with `request.authenticatedUser` or whatever you want to call it.
|
|
663
|
+
That's how it might look like:
|
|
664
|
+
|
|
665
|
+
```js
|
|
666
|
+
fastify.addHook('preParsing', async (request) => {
|
|
667
|
+
request.authenticatedUser = {
|
|
668
|
+
id: 42,
|
|
669
|
+
name: 'Jane Doe',
|
|
670
|
+
role: 'admin'
|
|
671
|
+
}
|
|
672
|
+
})
|
|
673
|
+
|
|
674
|
+
fastify.get('/me/is-admin', async function (req, reply) {
|
|
675
|
+
return { isAdmin: req.authenticatedUser?.role === 'admin' || false }
|
|
676
|
+
})
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
Note that `.authenticatedUser` could actually be any property name
|
|
680
|
+
choosen by yourself. Using your own custom property prevents you
|
|
681
|
+
from mutating existing properties, which
|
|
682
|
+
would be a dangerous and destructive operation. So be careful and
|
|
683
|
+
make sure your property is entirely new, also using this approach
|
|
684
|
+
only for very specific and small cases like this example.
|
|
685
|
+
|
|
686
|
+
Regarding TypeScript in this example, you'd need to update the
|
|
687
|
+
`FastifyRequest` core interface to include your new property typing
|
|
688
|
+
(for more about it, see [TypeScript](./TypeScript.md) page), like:
|
|
689
|
+
|
|
690
|
+
```ts
|
|
691
|
+
interface AuthenticatedUser { /* ... */ }
|
|
692
|
+
|
|
693
|
+
declare module 'fastify' {
|
|
694
|
+
export interface FastifyRequest {
|
|
695
|
+
authenticatedUser?: AuthenticatedUser;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
Although this is a very pragmatic approach, if you're trying to do
|
|
701
|
+
something more complex that changes these core objects, then
|
|
702
|
+
consider creating a custom [Plugin](./Plugins.md) instead.
|
|
703
|
+
|
|
652
704
|
## Diagnostics Channel Hooks
|
|
653
705
|
|
|
654
706
|
> **Note:** The `diagnostics_channel` is currently experimental on Node.js, so
|
|
@@ -13,7 +13,7 @@ way we create a *directed acyclic graph* (DAG) and we will not have issues
|
|
|
13
13
|
caused by cross dependencies.
|
|
14
14
|
|
|
15
15
|
You may have already seen in the [Getting
|
|
16
|
-
Started](
|
|
16
|
+
Started](../Guides/Getting-Started.md#your-first-plugin) guide how easy it is
|
|
17
17
|
to use this API:
|
|
18
18
|
```
|
|
19
19
|
fastify.register(plugin, [options])
|
package/docs/Reference/Reply.md
CHANGED
|
@@ -20,6 +20,9 @@
|
|
|
20
20
|
- [.callNotFound()](#callnotfound)
|
|
21
21
|
- [.getResponseTime()](#getresponsetime)
|
|
22
22
|
- [.type(contentType)](#typecontenttype)
|
|
23
|
+
- [.getSerializationFunction(schema | httpStatus)](#getserializationfunction)
|
|
24
|
+
- [.compileSerializationSchema(schema, httpStatus)](#compileserializationschema)
|
|
25
|
+
- [.serializeInput(data, [schema | httpStatus], [httpStatus])](#serializeinput)
|
|
23
26
|
- [.serializer(func)](#serializerfunc)
|
|
24
27
|
- [.raw](#raw)
|
|
25
28
|
- [.sent](#sent)
|
|
@@ -60,6 +63,16 @@ object that exposes the following functions and properties:
|
|
|
60
63
|
- `.serialize(payload)` - Serializes the specified payload using the default
|
|
61
64
|
JSON serializer or using the custom serializer (if one is set) and returns the
|
|
62
65
|
serialized payload.
|
|
66
|
+
- `.getSerializationFunction(schema | httpStatus)` - Returns the serialization
|
|
67
|
+
function for the specified schema or http status, if any of either are set.
|
|
68
|
+
- `.compileSerializationSchema(schema, httpStatus)` - Compiles the specified
|
|
69
|
+
schema and returns a serialization function using the default (or customized)
|
|
70
|
+
`SerializerCompiler`. The optional `httpStatus` is forwarded to the
|
|
71
|
+
`SerializerCompiler` if provided, default to `undefined`.
|
|
72
|
+
- `.serializeInput(data, schema, [,httpStatus])` - Serializes the specified data
|
|
73
|
+
using the specified schema and returns the serialized payload.
|
|
74
|
+
If the optional `httpStatus` is provided, the function will use the serializer
|
|
75
|
+
function given for that HTTP Status Code. Default to `undefined`.
|
|
63
76
|
- `.serializer(function)` - Sets a custom serializer for the payload.
|
|
64
77
|
- `.send(payload)` - Sends the payload to the user, could be a plain text, a
|
|
65
78
|
buffer, JSON, stream, or an Error object.
|
|
@@ -326,6 +339,169 @@ reply.type('text/html')
|
|
|
326
339
|
If the `Content-Type` has a JSON subtype, and the charset parameter is not set,
|
|
327
340
|
`utf-8` will be used as the charset by default.
|
|
328
341
|
|
|
342
|
+
### .getSerializationFunction(schema | httpStatus)
|
|
343
|
+
<a id="getserializationfunction"></a>
|
|
344
|
+
|
|
345
|
+
By calling this function using a provided `schema` or `httpStatus`,
|
|
346
|
+
it will return a `serialzation` function that can be used to
|
|
347
|
+
serialize diverse inputs. It returns `undefined` if no
|
|
348
|
+
serialization function was found using either of the provided inputs.
|
|
349
|
+
|
|
350
|
+
This heavily depends of the `schema#responses` attached to the route, or
|
|
351
|
+
the serialization functions compiled by using `compileSerializationSchema`.
|
|
352
|
+
|
|
353
|
+
```js
|
|
354
|
+
const serialize = reply
|
|
355
|
+
.getSerializationFunction({
|
|
356
|
+
type: 'object',
|
|
357
|
+
properties: {
|
|
358
|
+
foo: {
|
|
359
|
+
type: 'string'
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
})
|
|
363
|
+
serialize({ foo: 'bar' }) // '{"foo":"bar"}'
|
|
364
|
+
|
|
365
|
+
// or
|
|
366
|
+
|
|
367
|
+
const serialize = reply
|
|
368
|
+
.getSerializationFunction(200)
|
|
369
|
+
serialize({ foo: 'bar' }) // '{"foo":"bar"}'
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
See [.compileSerializationSchema(schema, [httpStatus])](#compileserializationschema)
|
|
373
|
+
for more information on how to compile serialization schemas.
|
|
374
|
+
|
|
375
|
+
### .compileSerializationSchema(schema, httpStatus)
|
|
376
|
+
<a id="compileserializationschema"></a>
|
|
377
|
+
|
|
378
|
+
This function will compile a serialization schema and
|
|
379
|
+
return a function that can be used to serialize data.
|
|
380
|
+
The function returned (a.k.a. _serialization function_) returned is compiled
|
|
381
|
+
by using the provided `SerializerCompiler`. Also this is cached by using
|
|
382
|
+
a `WeakMap` for reducing compilation calls.
|
|
383
|
+
|
|
384
|
+
The optional paramater `httpStatus`, if provided, is forwarded directly
|
|
385
|
+
the `SerializerCompiler`, so it can be used to compile the serialization
|
|
386
|
+
function if a custom `SerializerCompiler` is used.
|
|
387
|
+
|
|
388
|
+
This heavily depends of the `schema#responses` attached to the route, or
|
|
389
|
+
the serialization functions compiled by using `compileSerializationSchema`.
|
|
390
|
+
|
|
391
|
+
```js
|
|
392
|
+
const serialize = reply
|
|
393
|
+
.compileSerializationSchema({
|
|
394
|
+
type: 'object',
|
|
395
|
+
properties: {
|
|
396
|
+
foo: {
|
|
397
|
+
type: 'string'
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
})
|
|
401
|
+
serialize({ foo: 'bar' }) // '{"foo":"bar"}'
|
|
402
|
+
|
|
403
|
+
// or
|
|
404
|
+
|
|
405
|
+
const serialize = reply
|
|
406
|
+
.compileSerializationSchema({
|
|
407
|
+
type: 'object',
|
|
408
|
+
properties: {
|
|
409
|
+
foo: {
|
|
410
|
+
type: 'string'
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}, 200)
|
|
414
|
+
serialize({ foo: 'bar' }) // '{"foo":"bar"}'
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
Note that you should be careful when using this function, as it will cache
|
|
418
|
+
the compiled serialization functions based on the schema provided. If the
|
|
419
|
+
schemas provided is mutated or changed, the serialization functions will not
|
|
420
|
+
detect that the schema has been altered and for instance it will reuse the
|
|
421
|
+
previously compiled serialization function based on the reference of the schema
|
|
422
|
+
previously provided.
|
|
423
|
+
|
|
424
|
+
If there's a need to change the properties of a schema, always opt to create
|
|
425
|
+
a totally new object, otherwise the implementation won't benefit from the cache
|
|
426
|
+
mechanism.
|
|
427
|
+
|
|
428
|
+
:Using the following schema as example:
|
|
429
|
+
```js
|
|
430
|
+
const schema1 = {
|
|
431
|
+
type: 'object',
|
|
432
|
+
properties: {
|
|
433
|
+
foo: {
|
|
434
|
+
type: 'string'
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
*Not*
|
|
441
|
+
```js
|
|
442
|
+
const serialize = reply.compileSerializationSchema(schema1)
|
|
443
|
+
|
|
444
|
+
// Later on...
|
|
445
|
+
schema1.properties.foo.type. = 'integer'
|
|
446
|
+
const newSerialize = reply.compileSerializationSchema(schema1)
|
|
447
|
+
|
|
448
|
+
console.log(newSerialize === serialize) // true
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
*Instead*
|
|
452
|
+
```js
|
|
453
|
+
const serialize = reply.compileSerializationSchema(schema1)
|
|
454
|
+
|
|
455
|
+
// Later on...
|
|
456
|
+
const newSchema = Object.assign({}, schema1)
|
|
457
|
+
newSchema.properties.foo.type = 'integer'
|
|
458
|
+
|
|
459
|
+
const newSerialize = reply.compileSerializationSchema(newSchema)
|
|
460
|
+
|
|
461
|
+
console.log(newSerialize === serialize) // false
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### .serializeInput(data, [schema | httpStatus], [httpStatus])
|
|
465
|
+
<a id="serializeinput"></a>
|
|
466
|
+
|
|
467
|
+
This function will serialize the input data based on the provided schema,
|
|
468
|
+
or http status code. If both provided, the `httpStatus` will take presedence.
|
|
469
|
+
|
|
470
|
+
If there is not a serialization function for a given `schema`, a new serialization
|
|
471
|
+
function will be compiled forwarding the `httpStatus` if provided.
|
|
472
|
+
|
|
473
|
+
```js
|
|
474
|
+
reply
|
|
475
|
+
.serializeInput({ foo: 'bar'}, {
|
|
476
|
+
type: 'object',
|
|
477
|
+
properties: {
|
|
478
|
+
foo: {
|
|
479
|
+
type: 'string'
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}) // '{"foo":"bar"}'
|
|
483
|
+
|
|
484
|
+
// or
|
|
485
|
+
|
|
486
|
+
reply
|
|
487
|
+
.serializeInput({ foo: 'bar'}, {
|
|
488
|
+
type: 'object',
|
|
489
|
+
properties: {
|
|
490
|
+
foo: {
|
|
491
|
+
type: 'string'
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}, 200) // '{"foo":"bar"}'
|
|
495
|
+
|
|
496
|
+
// or
|
|
497
|
+
|
|
498
|
+
reply
|
|
499
|
+
.serializeInput({ foo: 'bar'}, 200) // '{"foo":"bar"}'
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
See [.compileSerializationSchema(schema, [httpStatus])](#compileserializationschema)
|
|
503
|
+
for more information on how to compile serialization schemas.
|
|
504
|
+
|
|
329
505
|
### .serializer(func)
|
|
330
506
|
<a id="serializer"></a>
|
|
331
507
|
|