fastify 3.20.2 → 3.21.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.taprc +1 -0
- package/README.md +30 -1
- package/docs/ContentTypeParser.md +2 -2
- package/docs/Ecosystem.md +3 -1
- package/docs/Getting-Started.md +76 -3
- package/docs/Guides/Index.md +6 -0
- package/docs/Hooks.md +42 -0
- package/docs/Lifecycle.md +1 -1
- package/docs/Recommendations.md +80 -1
- package/docs/Reply.md +2 -2
- package/docs/Request.md +4 -4
- package/docs/Server.md +82 -16
- package/docs/Validation-and-Serialization.md +47 -4
- package/fastify.js +11 -0
- package/lib/contentTypeParser.js +3 -5
- package/lib/decorate.js +33 -9
- package/lib/reply.js +17 -1
- package/lib/request.js +8 -0
- package/lib/route.js +4 -3
- package/lib/schema-controller.js +12 -7
- package/package.json +6 -4
- package/test/bundler/README.md +29 -0
- package/test/bundler/webpack/bundler-test.js +24 -0
- package/test/bundler/webpack/package.json +11 -0
- package/test/bundler/webpack/src/fail-plugin-version.js +14 -0
- package/test/bundler/webpack/src/index.js +9 -0
- package/test/bundler/webpack/webpack.config.js +13 -0
- package/test/custom-parser.test.js +111 -0
- package/test/decorator.test.js +27 -0
- package/test/diagnostics-channel.test.js +61 -0
- package/test/internals/decorator.test.js +1 -1
- package/test/reply-error.test.js +71 -0
- package/test/route.test.js +22 -0
- package/test/same-shape.test.js +124 -0
- package/test/schema-feature.test.js +1 -1
- package/test/schema-serialization.test.js +41 -0
- package/test/schema-special-usage.test.js +43 -2
- package/test/schema-validation.test.js +100 -0
- package/test/stream.test.js +37 -1
- package/test/types/instance.test-d.ts +10 -2
- package/test/types/plugin.test-d.ts +1 -1
- package/test/types/request.test-d.ts +4 -1
- package/types/.eslintrc.json +2 -1
- package/types/instance.d.ts +4 -3
- package/types/request.d.ts +1 -1
- package/types/schema.d.ts +1 -1
package/.taprc
CHANGED
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
<
|
|
2
|
+
<a href="https://fastify.io/">
|
|
3
|
+
<img src="https://github.com/fastify/graphics/raw/HEAD/fastify-landscape-outlined.svg" width="650" height="auto"/>
|
|
4
|
+
</a>
|
|
3
5
|
</div>
|
|
4
6
|
|
|
5
7
|
<div align="center">
|
|
@@ -28,6 +30,19 @@ Disclosure](https://img.shields.io/badge/Security-Responsible%20Disclosure-yello
|
|
|
28
30
|
An efficient server implies a lower cost of the infrastructure, a better responsiveness under load and happy users.
|
|
29
31
|
How can you efficiently handle the resources of your server, knowing that you are serving the highest number of requests as possible, without sacrificing security validations and handy development?
|
|
30
32
|
|
|
33
|
+
- [Quick start](./README.md#quick-start)
|
|
34
|
+
- [Install](./README.md#install)
|
|
35
|
+
- [Example](./README.md#example)
|
|
36
|
+
- [Fastify v1.x and v2.x](./README.md#fastify-v1x-and-v2x)
|
|
37
|
+
- [Core features](./README.md#core-features)
|
|
38
|
+
- [Benchmarks](./README.md#benchmarks)
|
|
39
|
+
- [Documentation](./README.md#documentation)
|
|
40
|
+
- [Ecosystem](./README.md#ecosystem)
|
|
41
|
+
- [Support](./README.md#support)
|
|
42
|
+
- [Team](./README.md#team)
|
|
43
|
+
- [Hosted by](./README.md#hosted-by)
|
|
44
|
+
- [License](./README.md#license)
|
|
45
|
+
|
|
31
46
|
Enter Fastify. Fastify is a web framework highly focused on providing the best developer experience with the least overhead and a powerful plugin architecture. It is inspired by Hapi and Express and as far as we know, it is one of the fastest web frameworks in town.
|
|
32
47
|
|
|
33
48
|
### Quick start
|
|
@@ -84,6 +99,13 @@ yarn add fastify
|
|
|
84
99
|
|
|
85
100
|
```js
|
|
86
101
|
// Require the framework and instantiate it
|
|
102
|
+
|
|
103
|
+
// ESM
|
|
104
|
+
import Fastify from 'fastify'
|
|
105
|
+
const fastify = Fastify({
|
|
106
|
+
logger: true
|
|
107
|
+
})
|
|
108
|
+
// CommonJs
|
|
87
109
|
const fastify = require('fastify')({
|
|
88
110
|
logger: true
|
|
89
111
|
})
|
|
@@ -103,6 +125,12 @@ fastify.listen(3000, (err, address) => {
|
|
|
103
125
|
with async-await:
|
|
104
126
|
|
|
105
127
|
```js
|
|
128
|
+
// ESM
|
|
129
|
+
import Fastify from 'fastify'
|
|
130
|
+
const fastify = Fastify({
|
|
131
|
+
logger: true
|
|
132
|
+
})
|
|
133
|
+
// CommonJs
|
|
106
134
|
const fastify = require('fastify')({
|
|
107
135
|
logger: true
|
|
108
136
|
})
|
|
@@ -162,6 +190,7 @@ matters to you.
|
|
|
162
190
|
|
|
163
191
|
## Documentation
|
|
164
192
|
* <a href="./docs/Getting-Started.md"><code><b>Getting Started</b></code></a>
|
|
193
|
+
* <a href="./docs/Guides/Index.md"><code><b>Guides</b></code></a>
|
|
165
194
|
* <a href="./docs/Server.md"><code><b>Server</b></code></a>
|
|
166
195
|
* <a href="./docs/Routes.md"><code><b>Routes</b></code></a>
|
|
167
196
|
* <a href="./docs/Encapsulation.md"><code><b>Encapsulation</b></code></a>
|
|
@@ -85,7 +85,7 @@ fastify.addContentTypeParser('text/xml', function (request, payload, done) {
|
|
|
85
85
|
})
|
|
86
86
|
|
|
87
87
|
// Removes the both built-in content type parsers so that only the content type parser for text/html is available
|
|
88
|
-
|
|
88
|
+
fastify.removeContentTypeParser(['application/json', 'text/plain'])
|
|
89
89
|
```
|
|
90
90
|
|
|
91
91
|
#### removeAllContentTypeParsers
|
|
@@ -97,7 +97,7 @@ Just like `removeContentTypeParser`, this API supports encapsulation. The API is
|
|
|
97
97
|
[catch-all content type parser](#Catch-All) that should be executed for every content type and the built-in parsers should be ignored as well.
|
|
98
98
|
|
|
99
99
|
```js
|
|
100
|
-
|
|
100
|
+
fastify.removeAllContentTypeParsers()
|
|
101
101
|
|
|
102
102
|
fastify.addContentTypeParser('text/xml', function (request, payload, done) {
|
|
103
103
|
xmlParser(payload, function (err, body) {
|
package/docs/Ecosystem.md
CHANGED
|
@@ -47,7 +47,7 @@ Plugins maintained by the Fastify team are listed under [Core](#core) while plug
|
|
|
47
47
|
- [`@fastify/session`](https://github.com/fastify/session) a session plugin for Fastify.
|
|
48
48
|
- [`fastify-static`](https://github.com/fastify/fastify-static) Plugin for serving static files as fast as possible.
|
|
49
49
|
- [`fastify-swagger`](https://github.com/fastify/fastify-swagger) Plugin for serving Swagger/OpenAPI documentation for Fastify, supporting dynamic generation.
|
|
50
|
-
- [`fastify-websocket`](https://github.com/fastify/fastify-websocket) WebSocket support for Fastify. Built upon [
|
|
50
|
+
- [`fastify-websocket`](https://github.com/fastify/fastify-websocket) WebSocket support for Fastify. Built upon [ws](https://github.com/websockets/ws).
|
|
51
51
|
- [`fastify-url-data`](https://github.com/fastify/fastify-url-data) Decorate the `Request` object with a method to access raw URL components.
|
|
52
52
|
- [`point-of-view`](https://github.com/fastify/point-of-view) Templates rendering (_ejs, pug, handlebars, marko_) plugin support for Fastify.
|
|
53
53
|
- [`under-pressure`](https://github.com/fastify/under-pressure) Measure process load with automatic handling of _"Service Unavailable"_ plugin for Fastify.
|
|
@@ -74,6 +74,7 @@ Plugins maintained by the Fastify team are listed under [Core](#core) while plug
|
|
|
74
74
|
- [`fastify-amqp`](https://github.com/RafaelGSS/fastify-amqp) Fastify AMQP connection plugin, to use with RabbitMQ or another connector. Just a wrapper to [`amqplib`](https://github.com/squaremo/amqp.node).
|
|
75
75
|
- [`fastify-angular-universal`](https://github.com/exequiel09/fastify-angular-universal) Angular server-side rendering support using [`@angular/platform-server`](https://github.com/angular/angular/tree/master/packages/platform-server) for Fastify
|
|
76
76
|
- [`fastify-api-key`](https://github.com/arkerone/fastify-api-key) Fastify plugin to authenticate HTTP requests based on api key and signature
|
|
77
|
+
- [`fastify-appwrite`](https://github.com/Dev-Manny/fastify-appwrite) Fastify Plugin for interacting with Appwrite server.
|
|
77
78
|
- [`fastify-auth0-verify`](https://github.com/nearform/fastify-auth0-verify): Auth0 verification plugin for Fastify, internally uses [fastify-jwt](https://npm.im/fastify-jwt) and [jsonwebtoken](https://npm.im/jsonwebtoken).
|
|
78
79
|
- [`fastify-autocrud`](https://github.com/paranoiasystem/fastify-autocrud) Plugin to auto-generate CRUD routes as fast as possible.
|
|
79
80
|
- [`fastify-autoroutes`](https://github.com/GiovanniCardamone/fastify-autoroutes) Plugin to scan and load routes based on filesystem path from a custom directory.
|
|
@@ -83,6 +84,7 @@ Plugins maintained by the Fastify team are listed under [Core](#core) while plug
|
|
|
83
84
|
- [`fastify-blipp`](https://github.com/PavelPolyakov/fastify-blipp) Prints your routes to the console, so you definitely know which endpoints are available.
|
|
84
85
|
- [`fastify-bookshelf`](https://github.com/butlerx/fastify-bookshelfjs) Fastify plugin to add [bookshelf.js](https://bookshelfjs.org/) ORM support.
|
|
85
86
|
- [`fastify-boom`](https://github.com/jeromemacias/fastify-boom) Fastify plugin to add [boom](https://github.com/hapijs/boom) support.
|
|
87
|
+
- [`fastify-bree`](https://github.com/climba03003/fastify-bree) Fastify plugin to add [bree](https://github.com/breejs/bree) support.
|
|
86
88
|
- [`fastify-casbin`](https://github.com/nearform/fastify-casbin) Casbin support for Fastify.
|
|
87
89
|
- [`fastify-casbin-rest`](https://github.com/nearform/fastify-casbin-rest) Casbin support for Fastify based on a RESTful model.
|
|
88
90
|
- [`fastify-casl`](https://github.com/Inlecom/fastify-casl) Fastify [CASL](https://github.com/stalniy/casl) plugin that supports ACL-like protection of endpoints via either a preSerialization & preHandler hook, sanitizing the inputs and outputs of your application based on user rights.
|
package/docs/Getting-Started.md
CHANGED
|
@@ -21,6 +21,13 @@ yarn add fastify
|
|
|
21
21
|
Let's write our first server:
|
|
22
22
|
```js
|
|
23
23
|
// Require the framework and instantiate it
|
|
24
|
+
|
|
25
|
+
// ESM
|
|
26
|
+
import Fastify from 'fastify'
|
|
27
|
+
const fastify = Fastify({
|
|
28
|
+
logger: true
|
|
29
|
+
})
|
|
30
|
+
// CommonJs
|
|
24
31
|
const fastify = require('fastify')({
|
|
25
32
|
logger: true
|
|
26
33
|
})
|
|
@@ -36,13 +43,19 @@ fastify.listen(3000, function (err, address) {
|
|
|
36
43
|
fastify.log.error(err)
|
|
37
44
|
process.exit(1)
|
|
38
45
|
}
|
|
39
|
-
|
|
46
|
+
// Server is now listening on ${address}
|
|
40
47
|
})
|
|
41
48
|
```
|
|
42
49
|
|
|
43
50
|
Do you prefer to use `async/await`? Fastify supports it out-of-the-box.<br>
|
|
44
51
|
*(We also suggest using [make-promises-safe](https://github.com/mcollina/make-promises-safe) to avoid file descriptor and memory leaks.)*
|
|
45
52
|
```js
|
|
53
|
+
// ESM
|
|
54
|
+
import Fastify from 'fastify'
|
|
55
|
+
const fastify = Fastify({
|
|
56
|
+
logger: true
|
|
57
|
+
})
|
|
58
|
+
// CommonJs
|
|
46
59
|
const fastify = require('fastify')({
|
|
47
60
|
logger: true
|
|
48
61
|
})
|
|
@@ -89,6 +102,26 @@ As with JavaScript, where everything is an object, with Fastify everything is a
|
|
|
89
102
|
Before digging into it, let's see how it works!<br>
|
|
90
103
|
Let's declare our basic server, but instead of declaring the route inside the entry point, we'll declare it in an external file (check out the [route declaration](Routes.md) docs).
|
|
91
104
|
```js
|
|
105
|
+
// ESM
|
|
106
|
+
import Fastify from 'fastify'
|
|
107
|
+
import firstRoute from './our-first-route'
|
|
108
|
+
const fastify = Fastify({
|
|
109
|
+
logger: true
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
fastify.register(firstRoute)
|
|
113
|
+
|
|
114
|
+
fastify.listen(3000, function (err, address) {
|
|
115
|
+
if (err) {
|
|
116
|
+
fastify.log.error(err)
|
|
117
|
+
process.exit(1)
|
|
118
|
+
}
|
|
119
|
+
// Server is now listening on ${address}
|
|
120
|
+
})
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
```js
|
|
124
|
+
// CommonJs
|
|
92
125
|
const fastify = require('fastify')({
|
|
93
126
|
logger: true
|
|
94
127
|
})
|
|
@@ -100,7 +133,7 @@ fastify.listen(3000, function (err, address) {
|
|
|
100
133
|
fastify.log.error(err)
|
|
101
134
|
process.exit(1)
|
|
102
135
|
}
|
|
103
|
-
|
|
136
|
+
// Server is now listening on ${address}
|
|
104
137
|
})
|
|
105
138
|
```
|
|
106
139
|
|
|
@@ -132,6 +165,28 @@ npm i --save fastify-plugin fastify-mongodb
|
|
|
132
165
|
|
|
133
166
|
**server.js**
|
|
134
167
|
```js
|
|
168
|
+
// ESM
|
|
169
|
+
import Fastify from 'fastify'
|
|
170
|
+
import dbConnector from './our-db-connector'
|
|
171
|
+
import firstRoute from './our-first-route'
|
|
172
|
+
|
|
173
|
+
const fastify = Fastify({
|
|
174
|
+
logger: true
|
|
175
|
+
})
|
|
176
|
+
fastify.register(dbConnector)
|
|
177
|
+
fastify.register(firstRoute)
|
|
178
|
+
|
|
179
|
+
fastify.listen(3000, function (err, address) {
|
|
180
|
+
if (err) {
|
|
181
|
+
fastify.log.error(err)
|
|
182
|
+
process.exit(1)
|
|
183
|
+
}
|
|
184
|
+
// Server is now listening on ${address}
|
|
185
|
+
})
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
// CommonJs
|
|
135
190
|
const fastify = require('fastify')({
|
|
136
191
|
logger: true
|
|
137
192
|
})
|
|
@@ -144,13 +199,31 @@ fastify.listen(3000, function (err, address) {
|
|
|
144
199
|
fastify.log.error(err)
|
|
145
200
|
process.exit(1)
|
|
146
201
|
}
|
|
147
|
-
|
|
202
|
+
// Server is now listening on ${address}
|
|
148
203
|
})
|
|
149
204
|
|
|
150
205
|
```
|
|
151
206
|
|
|
152
207
|
**our-db-connector.js**
|
|
153
208
|
```js
|
|
209
|
+
// ESM
|
|
210
|
+
import fastifyPlugin from 'fastify-plugin'
|
|
211
|
+
import fastifyMongo from 'fastify-mongodb'
|
|
212
|
+
|
|
213
|
+
async function dbConnector (fastify, options) {
|
|
214
|
+
fastify.register(fastifyMongo, {
|
|
215
|
+
url: 'mongodb://localhost:27017/test_database'
|
|
216
|
+
})
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Wrapping a plugin function with fastify-plugin exposes the decorators
|
|
220
|
+
// and hooks, declared inside the plugin to the parent scope.
|
|
221
|
+
module.exports = fastifyPlugin(dbConnector)
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
```js
|
|
226
|
+
// CommonJs
|
|
154
227
|
const fastifyPlugin = require('fastify-plugin')
|
|
155
228
|
|
|
156
229
|
async function dbConnector (fastify, options) {
|
package/docs/Hooks.md
CHANGED
|
@@ -564,3 +564,45 @@ fastify.route({
|
|
|
564
564
|
```
|
|
565
565
|
|
|
566
566
|
**Note**: both options also accept an array of functions.
|
|
567
|
+
|
|
568
|
+
## Diagnostics Channel Hooks
|
|
569
|
+
|
|
570
|
+
> **Note:** The `diagnostics_channel` is currently experimental on Node.js, so
|
|
571
|
+
> its API is subject to change even in semver-patch releases of Node.js. For
|
|
572
|
+
> versions of Node.js supported by Fastify where `diagnostics_channel` is
|
|
573
|
+
> unavailable, the hook will use the
|
|
574
|
+
> [polyfill](https://www.npmjs.com/package/diagnostics_channel) if it is
|
|
575
|
+
> available. Otherwise this feature will not be present.
|
|
576
|
+
|
|
577
|
+
Currently, one
|
|
578
|
+
[`diagnostics_channel`](https://nodejs.org/api/diagnostics_channel.html) publish
|
|
579
|
+
event, `'fastify.initialization'`, happens at initialization time. The Fastify
|
|
580
|
+
instance is passed into the hook as a property of the object passed in. At this
|
|
581
|
+
point, the instance can be interacted with to add hooks, plugins, routes or any
|
|
582
|
+
other sort of modification.
|
|
583
|
+
|
|
584
|
+
For example, a tracing package might do something like the following (which is,
|
|
585
|
+
of course, a simplification). This would be in a file loaded in the
|
|
586
|
+
initialization of the tracking package, in the typical "require instrumentation
|
|
587
|
+
tools first" fashion.
|
|
588
|
+
|
|
589
|
+
```js
|
|
590
|
+
const tracer = /* retrieved from elsehwere in the package */
|
|
591
|
+
const dc = require('diagnostics_channel')
|
|
592
|
+
const channel = dc.channel('fastify.initialization')
|
|
593
|
+
const spans = new WeakMap()
|
|
594
|
+
|
|
595
|
+
channel.subscribe(function ({ fastify }) {
|
|
596
|
+
fastify.addHook('onRequest', (request, reply, done) => {
|
|
597
|
+
const span = tracer.startSpan('fastify.request')
|
|
598
|
+
spans.set(request, span)
|
|
599
|
+
done()
|
|
600
|
+
})
|
|
601
|
+
|
|
602
|
+
fastify.addHook('onResponse', (request, reply, done) => {
|
|
603
|
+
const span = spans.get(request)
|
|
604
|
+
span.finish()
|
|
605
|
+
done()
|
|
606
|
+
})
|
|
607
|
+
})
|
|
608
|
+
```
|
package/docs/Lifecycle.md
CHANGED
package/docs/Recommendations.md
CHANGED
|
@@ -39,7 +39,9 @@ For a concrete example, consider the situation where:
|
|
|
39
39
|
|
|
40
40
|
There are many reverse proxy solutions available, and your environment may
|
|
41
41
|
dictate the solution to use, e.g. AWS or GCP. Given the above, we could use
|
|
42
|
-
[HAProxy][haproxy] to solve these requirements:
|
|
42
|
+
[HAProxy][haproxy] or [Nginx][nginx] to solve these requirements:
|
|
43
|
+
|
|
44
|
+
### HAProxy
|
|
43
45
|
|
|
44
46
|
```conf
|
|
45
47
|
# The global section defines base HAProxy (engine) instance configuration.
|
|
@@ -161,6 +163,83 @@ backend static-backend
|
|
|
161
163
|
[why-use]: https://web.archive.org/web/20190821102906/https://medium.com/intrinsic/why-should-i-use-a-reverse-proxy-if-node-js-is-production-ready-5a079408b2ca
|
|
162
164
|
[haproxy]: https://www.haproxy.org/
|
|
163
165
|
|
|
166
|
+
### Nginx
|
|
167
|
+
|
|
168
|
+
```nginx
|
|
169
|
+
upstream fastify_app {
|
|
170
|
+
# more info: http://nginx.org/en/docs/http/ngx_http_upstream_module.html
|
|
171
|
+
server 10.10.11.1:80;
|
|
172
|
+
server 10.10.11.2:80;
|
|
173
|
+
server 10.10.11.3:80 backup;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
server {
|
|
177
|
+
# default server
|
|
178
|
+
listen 80 default_server;
|
|
179
|
+
listen [::]:80 default_server;
|
|
180
|
+
|
|
181
|
+
# specify host
|
|
182
|
+
# listen 80;
|
|
183
|
+
# listen [::]:80;
|
|
184
|
+
# server_name example.tld;
|
|
185
|
+
|
|
186
|
+
location / {
|
|
187
|
+
return 301 https://$host$request_uri;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
server {
|
|
192
|
+
# default server
|
|
193
|
+
listen 443 ssl http2 default_server;
|
|
194
|
+
listen [::]:443 ssl http2 default_server;
|
|
195
|
+
|
|
196
|
+
# specify host
|
|
197
|
+
# listen 443 ssl http2;
|
|
198
|
+
# listen [::]:443 ssl http2;
|
|
199
|
+
# server_name example.tld;
|
|
200
|
+
|
|
201
|
+
# public private keys
|
|
202
|
+
ssl_certificate /path/to/fullchain.pem;
|
|
203
|
+
ssl_certificate_key /path/to/private.pem;
|
|
204
|
+
ssl_trusted_certificate /path/to/chain.pem;
|
|
205
|
+
|
|
206
|
+
# use https://ssl-config.mozilla.org/ for best practice configuration
|
|
207
|
+
ssl_session_timeout 1d;
|
|
208
|
+
ssl_session_cache shared:FastifyApp:10m;
|
|
209
|
+
ssl_session_tickets off;
|
|
210
|
+
|
|
211
|
+
# modern configuration
|
|
212
|
+
ssl_protocols TLSv1.3;
|
|
213
|
+
ssl_prefer_server_ciphers off;
|
|
214
|
+
|
|
215
|
+
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
|
|
216
|
+
add_header Strict-Transport-Security "max-age=63072000" always;
|
|
217
|
+
|
|
218
|
+
# OCSP stapling
|
|
219
|
+
ssl_stapling on;
|
|
220
|
+
ssl_stapling_verify on;
|
|
221
|
+
|
|
222
|
+
# custom resolver
|
|
223
|
+
# resolver 127.0.0.1;
|
|
224
|
+
|
|
225
|
+
location / {
|
|
226
|
+
# more info: http://nginx.org/en/docs/http/ngx_http_proxy_module.html
|
|
227
|
+
proxy_http_version 1.1;
|
|
228
|
+
proxy_cache_bypass $http_upgrade;
|
|
229
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
230
|
+
proxy_set_header Connection 'upgrade';
|
|
231
|
+
proxy_set_header Host $host;
|
|
232
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
233
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
234
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
235
|
+
|
|
236
|
+
proxy_pass http://fastify_app:3000;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
[nginx]: https://nginx.org/
|
|
242
|
+
|
|
164
243
|
## Kubernetes
|
|
165
244
|
<a id="kubernetes"></a>
|
|
166
245
|
|
package/docs/Reply.md
CHANGED
|
@@ -335,7 +335,7 @@ If you pass to *send* an object that is an instance of *Error*, Fastify will aut
|
|
|
335
335
|
}
|
|
336
336
|
```
|
|
337
337
|
|
|
338
|
-
You can add
|
|
338
|
+
You can add custom properties to the Error object, such as `headers`, that will be used to enhance the HTTP response.<br>
|
|
339
339
|
*Note: If you are passing an error to `send` and the statusCode is less than 400, Fastify will automatically set it at 500.*
|
|
340
340
|
|
|
341
341
|
Tip: you can simplify errors by using the [`http-errors`](https://npm.im/http-errors) module or [`fastify-sensible`](https://github.com/fastify/fastify-sensible) plugin to generate errors:
|
|
@@ -376,7 +376,7 @@ fastify.get('/', {
|
|
|
376
376
|
})
|
|
377
377
|
```
|
|
378
378
|
|
|
379
|
-
If you want to
|
|
379
|
+
If you want to customize error handling, check out [`setErrorHandler`](Server.md#seterrorhandler) API.<br>
|
|
380
380
|
*Note: you are responsible for logging when customizing the error handler*
|
|
381
381
|
|
|
382
382
|
API:
|
package/docs/Request.md
CHANGED
|
@@ -10,25 +10,25 @@ Request is a core Fastify object containing the following fields:
|
|
|
10
10
|
- `raw` - the incoming HTTP request from Node core
|
|
11
11
|
- `req` *(deprecated, use `.raw` instead)* - the incoming HTTP request from Node core
|
|
12
12
|
- `server` - The Fastify server instance, scoped to the current [encapsulation context](Encapsulation.md)
|
|
13
|
-
- `id` - the request
|
|
13
|
+
- `id` - the request ID
|
|
14
14
|
- `log` - the logger instance of the incoming request
|
|
15
15
|
- `ip` - the IP address of the incoming request
|
|
16
16
|
- `ips` - an array of the IP addresses, ordered from closest to furthest, in the `X-Forwarded-For` header of the incoming request (only when the [`trustProxy`](Server.md#factory-trust-proxy) option is enabled)
|
|
17
17
|
- `hostname` - the hostname of the incoming request (derived from `X-Forwarded-Host` header when the [`trustProxy`](Server.md#factory-trust-proxy) option is enabled)
|
|
18
18
|
- `protocol` - the protocol of the incoming request (`https` or `http`)
|
|
19
19
|
- `method` - the method of the incoming request
|
|
20
|
-
- `url` - the
|
|
20
|
+
- `url` - the URL of the incoming request
|
|
21
21
|
- `routerMethod` - the method defined for the router that is handling the request
|
|
22
22
|
- `routerPath` - the path pattern defined for the router that is handling the request
|
|
23
23
|
- `is404` - true if request is being handled by 404 handler, false if it is not
|
|
24
24
|
- `connection` - Deprecated, use `socket` instead. The underlying connection of the incoming request.
|
|
25
25
|
- `socket` - the underlying connection of the incoming request
|
|
26
|
-
- `context` - A Fastify internal object. You should not use it directly or modify it. It is
|
|
26
|
+
- `context` - A Fastify internal object. You should not use it directly or modify it. It is useful to access one special key:
|
|
27
27
|
- `context.config` - The route [`config`](Routes.md#routes-config) object.
|
|
28
28
|
|
|
29
29
|
### Headers
|
|
30
30
|
|
|
31
|
-
The `request.headers` is a getter that
|
|
31
|
+
The `request.headers` is a getter that returns an Object with the headers of the incoming request.
|
|
32
32
|
You can set custom headers like this:
|
|
33
33
|
|
|
34
34
|
```js
|
package/docs/Server.md
CHANGED
|
@@ -8,6 +8,38 @@ The Fastify module exports a factory function that is used to create new
|
|
|
8
8
|
an options object which is used to customize the resulting instance. This
|
|
9
9
|
document describes the properties available in that options object.
|
|
10
10
|
|
|
11
|
+
- [http2](./Server.md#http2)
|
|
12
|
+
- [https](./Server.md#https)
|
|
13
|
+
- [connectionTimeout](./Server.md#connectiontimeout)
|
|
14
|
+
- [keepAliveTimeout](./Server.md#keepalivetimeout)
|
|
15
|
+
- [ignoreTrailingSlash](./Server.md#ignoretrailingslash)
|
|
16
|
+
- [maxParamLength](./Server.md#maxparamlength)
|
|
17
|
+
- [onProtoPoisoning](./Server.md#onprotopoisoning)
|
|
18
|
+
- [onConstructorPoisoning](./Server.md#onconstructorpoisoning)
|
|
19
|
+
- [logger](./Server.md#logger)
|
|
20
|
+
- [serverFactory](./Server.md#serverfactory)
|
|
21
|
+
- [jsonShorthand](./Server.md#jsonshorthand)
|
|
22
|
+
- [caseSensitive](./Server.md#casesensitive)
|
|
23
|
+
- [requestIdHeader](./Server.md#requestidheader)
|
|
24
|
+
- [requestIdLogLabel](./Server.md#requestidloglabel)
|
|
25
|
+
- [genReqId](./Server.md#genreqid)
|
|
26
|
+
- [trustProxy](./Server.md#trustProxy)
|
|
27
|
+
- [pluginTimeout](./Server.md#plugintimeout)
|
|
28
|
+
- [querystringParser](./Server.md#querystringParser)
|
|
29
|
+
- [exposeHeadRoutes](./Server.md#exposeheadroutes)
|
|
30
|
+
- [constraints](./Server.md#constraints)
|
|
31
|
+
- [return503OnClosing](./Server.md#return503onclosing)
|
|
32
|
+
- [ajv](./Server.md#ajv)
|
|
33
|
+
- [serializerOpts](./Server.md#serializeropts)
|
|
34
|
+
- [http2SessionTimeout](./Server.md#http2sessiontimeout)
|
|
35
|
+
- [frameworkErrors](./Server.md#frameworkerrors)
|
|
36
|
+
- [clientErrorHandler](./Server.md#clienterrorhandler)
|
|
37
|
+
- [rewriteUrl](./Server.md#rewriteurl)
|
|
38
|
+
- [Instance](./Server.md#instance)
|
|
39
|
+
- [Server Methods](./Server.md#server-methods)
|
|
40
|
+
- [initialConfig](./Server.md#initialConfig)
|
|
41
|
+
|
|
42
|
+
|
|
11
43
|
<a name="factory-http2"></a>
|
|
12
44
|
### `http2`
|
|
13
45
|
|
|
@@ -78,7 +110,7 @@ fastify.get('/bar', function (req, reply) {
|
|
|
78
110
|
|
|
79
111
|
<a name="factory-max-param-length"></a>
|
|
80
112
|
### `maxParamLength`
|
|
81
|
-
You can set a custom length for parameters in parametric (standard, regex, and multi) routes by using `maxParamLength` option
|
|
113
|
+
You can set a custom length for parameters in parametric (standard, regex, and multi) routes by using `maxParamLength` option; the default value is 100 characters.<br>
|
|
82
114
|
This can be useful especially if you have some regex based route, protecting you against [DoS attacks](https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS).<br>
|
|
83
115
|
*If the maximum length limit is reached, the not found route will be invoked.*
|
|
84
116
|
|
|
@@ -135,7 +167,7 @@ are not present on the object, they will be added accordingly:
|
|
|
135
167
|
* `level`: the minimum logging level. If not set, it will be set to `'info'`.
|
|
136
168
|
* `serializers`: a hash of serialization functions. By default, serializers
|
|
137
169
|
are added for `req` (incoming request objects), `res` (outgoing response
|
|
138
|
-
|
|
170
|
+
objects), and `err` (standard `Error` objects). When a log method receives
|
|
139
171
|
an object with any of these properties then the respective serializer will
|
|
140
172
|
be used for that property. For example:
|
|
141
173
|
```js
|
|
@@ -196,7 +228,7 @@ Please note that this setting will also disable an error log written by the defa
|
|
|
196
228
|
<a name="custom-http-server"></a>
|
|
197
229
|
### `serverFactory`
|
|
198
230
|
You can pass a custom HTTP server to Fastify by using the `serverFactory` option.<br/>
|
|
199
|
-
`serverFactory` is a function that takes
|
|
231
|
+
`serverFactory` is a function that takes a `handler` parameter, which takes the `request` and `response` objects as parameters, and an options object, which is the same you have passed to Fastify.
|
|
200
232
|
|
|
201
233
|
```js
|
|
202
234
|
const serverFactory = (handler, opts) => {
|
|
@@ -223,7 +255,7 @@ Internally Fastify uses the API of Node core HTTP server, so if you are using a
|
|
|
223
255
|
|
|
224
256
|
+ Default: `true`
|
|
225
257
|
|
|
226
|
-
Internally, and by default, Fastify will automatically infer the root properties of JSON Schemas if it
|
|
258
|
+
Internally, and by default, Fastify will automatically infer the root properties of JSON Schemas if it does not find valid root properties according to the JSON Schema spec. If you wish to implement your own schema validation compiler, for example: to parse schemas as JTD instead of JSON Schema, then you can explicitly set this option to `false` to make sure the schemas you receive are unmodified and are not being treated internally as JSON Schema.
|
|
227
259
|
|
|
228
260
|
```js
|
|
229
261
|
const AjvJTD = require('ajv/dist/jtd'/* only valid for AJV v7+ */)
|
|
@@ -301,7 +333,7 @@ const fastify = require('fastify')({
|
|
|
301
333
|
<a name="factory-trust-proxy"></a>
|
|
302
334
|
### `trustProxy`
|
|
303
335
|
|
|
304
|
-
By enabling the `trustProxy` option, Fastify will
|
|
336
|
+
By enabling the `trustProxy` option, Fastify will know that it is sitting behind a proxy and that the `X-Forwarded-*` header fields may be trusted, which otherwise may be easily spoofed.
|
|
305
337
|
|
|
306
338
|
```js
|
|
307
339
|
const fastify = Fastify({ trustProxy: true })
|
|
@@ -402,7 +434,7 @@ If `false`, the server routes the incoming request as usual.
|
|
|
402
434
|
<a name="factory-ajv"></a>
|
|
403
435
|
### `ajv`
|
|
404
436
|
|
|
405
|
-
Configure the Ajv instance used by Fastify without providing a custom one.
|
|
437
|
+
Configure the Ajv v6 instance used by Fastify without providing a custom one.
|
|
406
438
|
|
|
407
439
|
+ Default:
|
|
408
440
|
|
|
@@ -426,8 +458,8 @@ const fastify = require('fastify')({
|
|
|
426
458
|
nullable: false // Refer to [ajv options](https://ajv.js.org/#options)
|
|
427
459
|
},
|
|
428
460
|
plugins: [
|
|
429
|
-
require('ajv-merge-patch')
|
|
430
|
-
[require('ajv-keywords'), 'instanceof']
|
|
461
|
+
require('ajv-merge-patch'),
|
|
462
|
+
[require('ajv-keywords'), 'instanceof']
|
|
431
463
|
// Usage: [plugin, pluginOptions] - Plugin with options
|
|
432
464
|
// Usage: plugin - Plugin without options
|
|
433
465
|
]
|
|
@@ -465,7 +497,7 @@ increased to fit the use case. Node core defaults this to `0`. `
|
|
|
465
497
|
+ Default: `null`
|
|
466
498
|
|
|
467
499
|
Fastify provides default error handlers for the most common use cases.
|
|
468
|
-
|
|
500
|
+
It is possible to override one or more of those handlers with custom code using this option.
|
|
469
501
|
|
|
470
502
|
*Note: Only `FST_ERR_BAD_URL` is implemented at the moment.*
|
|
471
503
|
|
|
@@ -487,7 +519,7 @@ const fastify = require('fastify')({
|
|
|
487
519
|
|
|
488
520
|
Set a [clientErrorHandler](https://nodejs.org/api/http.html#http_event_clienterror) that listens to `error` events emitted by client connections and responds with a `400`.
|
|
489
521
|
|
|
490
|
-
|
|
522
|
+
It is possible to override the default `clientErrorHandler` using this option.
|
|
491
523
|
|
|
492
524
|
+ Default:
|
|
493
525
|
```js
|
|
@@ -617,7 +649,7 @@ fastify.ready().then(() => {
|
|
|
617
649
|
|
|
618
650
|
<a name="listen"></a>
|
|
619
651
|
#### listen
|
|
620
|
-
Starts the server on the given port after all the plugins are loaded, internally waits for the `.ready()` event. The callback is the same as the Node core. By default, the server will listen on the address resolved by `localhost` when no specific address is provided (`127.0.0.1` or `::1` depending on the operating system). If listening on any available interface is desired, then specifying `0.0.0.0` for the address will listen on all IPv4
|
|
652
|
+
Starts the server on the given port after all the plugins are loaded, internally waits for the `.ready()` event. The callback is the same as the Node core. By default, the server will listen on the address resolved by `localhost` when no specific address is provided (`127.0.0.1` or `::1` depending on the operating system). If listening on any available interface is desired, then specifying `0.0.0.0` for the address will listen on all IPv4 addresses. Using `::` for the address will listen on all IPv6 addresses and, depending on OS, may also listen on all IPv4 addresses. Be careful when deciding to listen on all interfaces; it comes with inherent [security risks](https://web.archive.org/web/20170831174611/https://snyk.io/blog/mongodb-hack-and-secure-defaults/).
|
|
621
653
|
|
|
622
654
|
```js
|
|
623
655
|
fastify.listen(3000, (err, address) => {
|
|
@@ -895,6 +927,9 @@ It can be useful when your schemas are stored in another data structure that is
|
|
|
895
927
|
See [issue #2446](https://github.com/fastify/fastify/issues/2446) for an example of what
|
|
896
928
|
this property helps to resolve.
|
|
897
929
|
|
|
930
|
+
Another use case is to tweak all the schemas processing.
|
|
931
|
+
Doing so it is possible to use Ajv v8, instead of the default v6! We will see an example of this later.
|
|
932
|
+
|
|
898
933
|
```js
|
|
899
934
|
const fastify = Fastify({
|
|
900
935
|
schemaController: {
|
|
@@ -927,15 +962,15 @@ const fastify = Fastify({
|
|
|
927
962
|
},
|
|
928
963
|
|
|
929
964
|
/**
|
|
930
|
-
* The compilers factory let you
|
|
965
|
+
* The compilers factory let you fully control the validator and serializer
|
|
931
966
|
* in the Fastify's lifecycle, providing the encapsulation to your compilers.
|
|
932
967
|
*/
|
|
933
968
|
compilersFactory: {
|
|
934
969
|
/**
|
|
935
970
|
* This factory is called whenever a new validator instance is needed.
|
|
936
|
-
* It may be called whenever `fastify.register()` is called only if new schemas
|
|
971
|
+
* It may be called whenever `fastify.register()` is called only if new schemas have been added to the
|
|
937
972
|
* encapsulation context.
|
|
938
|
-
* It may receive as input the schemas of the parent context if some schemas
|
|
973
|
+
* It may receive as input the schemas of the parent context if some schemas have been added.
|
|
939
974
|
* @param {object} externalSchemas these schemas will be returned by the `bucket.getSchemas()`. Needed to resolve the external references $ref.
|
|
940
975
|
* @param {object} ajvServerOption the server `ajv` options to build your compilers accordingly
|
|
941
976
|
*/
|
|
@@ -950,9 +985,9 @@ const fastify = Fastify({
|
|
|
950
985
|
|
|
951
986
|
/**
|
|
952
987
|
* This factory is called whenever a new serializer instance is needed.
|
|
953
|
-
* It may be called whenever `fastify.register()` is called only if new schemas
|
|
988
|
+
* It may be called whenever `fastify.register()` is called only if new schemas have been added to the
|
|
954
989
|
* encapsulation context.
|
|
955
|
-
* It may receive as input the schemas of the parent context if some schemas
|
|
990
|
+
* It may receive as input the schemas of the parent context if some schemas have been added.
|
|
956
991
|
* @param {object} externalSchemas these schemas will be returned by the `bucket.getSchemas()`. Needed to resolve the external references $ref.
|
|
957
992
|
* @param {object} serializerOptsServerOption the server `serializerOpts` options to build your compilers accordingly
|
|
958
993
|
*/
|
|
@@ -968,6 +1003,37 @@ const fastify = Fastify({
|
|
|
968
1003
|
});
|
|
969
1004
|
```
|
|
970
1005
|
|
|
1006
|
+
##### Ajv 8 as default schema validator
|
|
1007
|
+
|
|
1008
|
+
Ajv 8 is the evolution of Ajv 6, and it has a lot of improvements and new features.
|
|
1009
|
+
To use the new Ajv 8 features such as JTD or the Standalone mode, refer to the [`@fastify/ajv-compiler` documentation](https://github.com/fastify/ajv-compiler#usage).
|
|
1010
|
+
|
|
1011
|
+
To use Ajv 8 as default schema validator, you can use the following code:
|
|
1012
|
+
|
|
1013
|
+
```js
|
|
1014
|
+
const AjvCompiler = require('@fastify/ajv-compiler') // It must be the v2.x.x version
|
|
1015
|
+
|
|
1016
|
+
// Note that the `format` schema's keyword is no longer supported on Ajv 8 by default.
|
|
1017
|
+
// So you need to add it manually.
|
|
1018
|
+
const ajvFormats = require('ajv-formats')
|
|
1019
|
+
|
|
1020
|
+
const app = fastify({
|
|
1021
|
+
ajv: {
|
|
1022
|
+
customOptions: {
|
|
1023
|
+
validateFormats: true
|
|
1024
|
+
},
|
|
1025
|
+
plugins: [ajvFormats]
|
|
1026
|
+
},
|
|
1027
|
+
schemaController: {
|
|
1028
|
+
compilersFactory: {
|
|
1029
|
+
buildValidator: AjvCompiler()
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
})
|
|
1033
|
+
|
|
1034
|
+
// Done! You can now use Ajv 8 options and keywords in your schemas!
|
|
1035
|
+
```
|
|
1036
|
+
|
|
971
1037
|
<a name="set-not-found-handler"></a>
|
|
972
1038
|
#### setNotFoundHandler
|
|
973
1039
|
|