fastify 3.22.1 → 3.24.1
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/build/build-validation.js +2 -0
- package/build/sync-version.js +11 -0
- package/docs/Ecosystem.md +2 -0
- package/docs/Getting-Started.md +32 -0
- package/docs/Hooks.md +1 -1
- package/docs/Logging.md +23 -1
- package/docs/Plugins.md +1 -1
- package/docs/Reply.md +16 -3
- package/docs/Request.md +1 -1
- package/docs/Routes.md +2 -0
- package/docs/Server.md +13 -1
- package/docs/Serverless.md +123 -0
- package/docs/Validation-and-Serialization.md +10 -2
- package/examples/typescript-server.ts +1 -1
- package/fastify.d.ts +2 -0
- package/fastify.js +5 -23
- package/lib/configValidator.js +455 -423
- package/lib/logger.js +2 -2
- package/lib/pluginUtils.js +1 -3
- package/lib/reply.js +4 -1
- package/lib/request.js +9 -3
- package/lib/schema-controller.js +11 -2
- package/lib/server.js +10 -8
- package/lib/symbols.js +1 -0
- package/package.json +5 -4
- package/test/bundler/README.md +7 -7
- package/test/bundler/webpack/bundler-test.js +2 -6
- package/test/internals/initialConfig.test.js +2 -0
- package/test/internals/logger.test.js +20 -0
- package/test/internals/reply.test.js +42 -0
- package/test/internals/request.test.js +47 -0
- package/test/internals/version.test.js +6 -34
- package/test/logger.test.js +16 -0
- package/test/maxRequestsPerSocket.test.js +10 -0
- package/test/requestTimeout.test.js +53 -0
- package/test/route-hooks.test.js +55 -0
- package/test/schema-feature.test.js +461 -0
- package/test/types/content-type-parser.test-d.ts +1 -1
- package/test/types/instance.test-d.ts +7 -1
- package/test/types/logger.test-d.ts +1 -1
- package/test/types/request.test-d.ts +7 -1
- package/test/types/route.test-d.ts +21 -0
- package/types/instance.d.ts +5 -5
- package/types/request.d.ts +4 -1
- package/types/route.d.ts +1 -1
|
@@ -16,6 +16,7 @@ const defaultInitOptions = {
|
|
|
16
16
|
connectionTimeout: 0, // 0 sec
|
|
17
17
|
keepAliveTimeout: 5000, // 5 sec
|
|
18
18
|
maxRequestsPerSocket: 0, // no limit
|
|
19
|
+
requestTimeout: 0, // no limit
|
|
19
20
|
bodyLimit: 1024 * 1024, // 1 MiB
|
|
20
21
|
caseSensitive: true,
|
|
21
22
|
disableRequestLogging: false,
|
|
@@ -49,6 +50,7 @@ const schema = {
|
|
|
49
50
|
connectionTimeout: { type: 'integer', default: defaultInitOptions.connectionTimeout },
|
|
50
51
|
keepAliveTimeout: { type: 'integer', default: defaultInitOptions.keepAliveTimeout },
|
|
51
52
|
maxRequestsPerSocket: { type: 'integer', default: defaultInitOptions.maxRequestsPerSocket, nullable: true },
|
|
53
|
+
requestTimeout: { type: 'integer', default: defaultInitOptions.requestTimeout },
|
|
52
54
|
bodyLimit: { type: 'integer', default: defaultInitOptions.bodyLimit },
|
|
53
55
|
caseSensitive: { type: 'boolean', default: defaultInitOptions.caseSensitive },
|
|
54
56
|
http2: { type: 'boolean' },
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
|
|
6
|
+
// package.json:version -> fastify.js:VERSION
|
|
7
|
+
const { version } = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json')).toString('utf8'))
|
|
8
|
+
|
|
9
|
+
const fastifyJs = path.join(__dirname, '..', 'fastify.js')
|
|
10
|
+
|
|
11
|
+
fs.writeFileSync(fastifyJs, fs.readFileSync(fastifyJs).toString('utf8').replace(/const\s*VERSION\s*=.*/, `const VERSION = '${version}'`))
|
package/docs/Ecosystem.md
CHANGED
|
@@ -91,6 +91,7 @@ Plugins maintained by the Fastify team are listed under [Core](#core) while plug
|
|
|
91
91
|
- [`fastify-cloudevents`](https://github.com/smartiniOnGitHub/fastify-cloudevents) Fastify plugin to generate and forward Fastify events in the Cloudevents format.
|
|
92
92
|
- [`fastify-cockroachdb`](https://github.com/alex-ppg/fastify-cockroachdb) Fastify plugin to connect to a CockroachDB PostgreSQL instance via the Sequelize ORM.
|
|
93
93
|
- [`fastify-couchdb`](https://github.com/nigelhanlon/fastify-couchdb) Fastify plugin to add CouchDB support via [nano](https://github.com/apache/nano).
|
|
94
|
+
- [`fastify-crud-generator`](https://github.com/heply/fastify-crud-generator) A plugin to rapidly generate CRUD routes for any entity.
|
|
94
95
|
- [`fastify-custom-healthcheck`](https://github.com/gkampitakis/fastify-custom-healthcheck) Fastify plugin to add health route in your server that asserts custom functions.
|
|
95
96
|
- [`fastify-decorators`](https://github.com/L2jLiga/fastify-decorators) Fastify plugin that provides the set of TypeScript decorators.
|
|
96
97
|
- [`fastify-disablecache`](https://github.com/Fdawgs/fastify-disablecache) Fastify plugin to disable client-side caching, inspired by [nocache](https://github.com/helmetjs/nocache).
|
|
@@ -158,6 +159,7 @@ Plugins maintained by the Fastify team are listed under [Core](#core) while plug
|
|
|
158
159
|
- [`fastify-orientdb`](https://github.com/mahmed8003/fastify-orientdb) Fastify OrientDB connection plugin, with which you can share the OrientDB connection across every part of your server.
|
|
159
160
|
- [`fastify-piscina`](https://github.com/piscinajs/fastify-piscina) A worker thread pool plugin using [Piscina](https://github.com/piscinajs/piscina).
|
|
160
161
|
- [`fastify-peekaboo`](https://github.com/simone-sanfratello/fastify-peekaboo) Fastify plugin for memoize responses by expressive settings.
|
|
162
|
+
- [`fastify-polyglot`](https://github.com/heply/fastify-polyglot) A plugin to handle i18n using [node-polyglot](https://www.npmjs.com/package/node-polyglot).
|
|
161
163
|
- [`fastify-postgraphile`](https://github.com/alemagio/fastify-postgraphile) Plugin to integrate [PostGraphile](https://www.graphile.org/postgraphile/) in a Fastify project.
|
|
162
164
|
- [`fastify-prettier`](https://github.com/hsynlms/fastify-prettier) A Fastify plugin that uses [prettier](https://github.com/prettier/prettier) under the hood to beautify outgoing responses and/or other things in the Fastify server.
|
|
163
165
|
- [`fastify-print-routes`](https://github.com/ShogunPanda/fastify-print-routes) A Fastify plugin that prints all available routes.
|
package/docs/Getting-Started.md
CHANGED
|
@@ -262,6 +262,24 @@ async function routes (fastify, options) {
|
|
|
262
262
|
}
|
|
263
263
|
return result
|
|
264
264
|
})
|
|
265
|
+
|
|
266
|
+
const animalBodyJsonSchema = {
|
|
267
|
+
type: 'object',
|
|
268
|
+
required: ['animal'],
|
|
269
|
+
properties: {
|
|
270
|
+
animal: { type: 'string' },
|
|
271
|
+
},
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const schema = {
|
|
275
|
+
body: animalBodyJsonSchema,
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
fastify.post('/animals', { schema }, async (request, reply) => {
|
|
279
|
+
// we can use the `request.body` object to get the data sent by the client
|
|
280
|
+
const result = await collection.insertOne({ animal: request.body.animal })
|
|
281
|
+
return result
|
|
282
|
+
})
|
|
265
283
|
}
|
|
266
284
|
|
|
267
285
|
module.exports = routes
|
|
@@ -363,6 +381,20 @@ fastify.get('/', opts, async (request, reply) => {
|
|
|
363
381
|
By specifying a schema as shown, you can speed up serialization by a factor of 2-3. This also helps to protect against leakage of potentially sensitive data, since Fastify will serialize only the data present in the response schema.
|
|
364
382
|
Read [Validation and Serialization](Validation-and-Serialization.md) to learn more.
|
|
365
383
|
|
|
384
|
+
<a name="request-payload"></a>
|
|
385
|
+
### Parsing request payloads
|
|
386
|
+
Fastify parses `'application/json'` and `'text/plain'` request payloads natively, with the result accessible from the [Fastify request](Request.md) object at `request.body`.<br>
|
|
387
|
+
The following example returns the parsed body of a request back to the client:
|
|
388
|
+
|
|
389
|
+
```js
|
|
390
|
+
const opts = {}
|
|
391
|
+
fastify.post('/', opts, async (request, reply) => {
|
|
392
|
+
return request.body
|
|
393
|
+
})
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
Read [Content Type Parser](ContentTypeParser.md) to learn more about Fastify's default parsing functionality and how to support other content types.
|
|
397
|
+
|
|
366
398
|
<a name="extend-server"></a>
|
|
367
399
|
### Extend your server
|
|
368
400
|
Fastify is built to be extremely extensible and minimal, we believe that a bare-bones framework is all that is necessary to make great applications possible.<br>
|
package/docs/Hooks.md
CHANGED
|
@@ -222,7 +222,7 @@ fastify.addHook('onTimeout', async (request, reply) => {
|
|
|
222
222
|
await asyncMethod()
|
|
223
223
|
})
|
|
224
224
|
```
|
|
225
|
-
`onTimeout` is useful if you need to monitor the request timed out in your service (if the `connectionTimeout` property is set on the Fastify instance). The `onTimeout` hook is executed when a request is timed out and the HTTP socket has been hanged up. Therefore
|
|
225
|
+
`onTimeout` is useful if you need to monitor the request timed out in your service (if the `connectionTimeout` property is set on the Fastify instance). The `onTimeout` hook is executed when a request is timed out and the HTTP socket has been hanged up. Therefore, you will not be able to send data to the client.
|
|
226
226
|
|
|
227
227
|
|
|
228
228
|
### Manage Errors from a hook
|
package/docs/Logging.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Logging
|
|
4
4
|
|
|
5
|
+
### Enable logging
|
|
5
6
|
Logging is disabled by default, and you can enable it by passing
|
|
6
7
|
`{ logger: true }` or `{ logger: { level: 'info' } }` when you create
|
|
7
8
|
a fastify instance. Note that if the logger is disabled, it is impossible to
|
|
@@ -11,13 +12,34 @@ this purpose.
|
|
|
11
12
|
|
|
12
13
|
As Fastify is focused on performance, it uses [pino](https://github.com/pinojs/pino) as its logger, with the default log level, when enabled, set to `'info'`.
|
|
13
14
|
|
|
14
|
-
Enabling the
|
|
15
|
+
Enabling the production JSON logger:
|
|
15
16
|
|
|
16
17
|
```js
|
|
17
18
|
const fastify = require('fastify')({
|
|
18
19
|
logger: true
|
|
19
20
|
})
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Enabling the logger with appropriate configuration for both local development and production environment requires bit more configuration:
|
|
24
|
+
```js
|
|
25
|
+
const fastify = require('fastify')({
|
|
26
|
+
logger: {
|
|
27
|
+
prettyPrint:
|
|
28
|
+
environment === 'development'
|
|
29
|
+
? {
|
|
30
|
+
translateTime: 'HH:MM:ss Z',
|
|
31
|
+
ignore: 'pid,hostname'
|
|
32
|
+
}
|
|
33
|
+
: false
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
```
|
|
37
|
+
⚠️ `pino-pretty` needs to be installed as a dev dependency, it is not included by default for performance reasons.
|
|
20
38
|
|
|
39
|
+
### Usage
|
|
40
|
+
You can use the logger like this in your route handlers:
|
|
41
|
+
|
|
42
|
+
```js
|
|
21
43
|
fastify.get('/', options, function (request, reply) {
|
|
22
44
|
request.log.info('Some info about the current request')
|
|
23
45
|
reply.send({ hello: 'world' })
|
package/docs/Plugins.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
Fastify allows the user to extend its functionalities with plugins.
|
|
5
5
|
A plugin can be a set of routes, a server [decorator](Decorators.md), or whatever. The API that you will need to use one or more plugins, is `register`.<br>
|
|
6
6
|
|
|
7
|
-
By default, `register` creates a *new scope*, this means that if you make some changes to the Fastify instance (via `decorate`), this change will not be reflected by the current context ancestors, but only to its
|
|
7
|
+
By default, `register` creates a *new scope*, this means that if you make some changes to the Fastify instance (via `decorate`), this change will not be reflected by the current context ancestors, but only to its descendants. This feature allows us to achieve plugin *encapsulation* and *inheritance*, in this way we create a *direct acyclic graph* (DAG) and we will not have issues caused by cross dependencies.
|
|
8
8
|
|
|
9
9
|
You already see in the [getting started](Getting-Started.md#register) section how using this API is pretty straightforward.
|
|
10
10
|
```
|
package/docs/Reply.md
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
- [.statusCode](#statusCode)
|
|
8
8
|
- [.server](#server)
|
|
9
9
|
- [.header(key, value)](#headerkey-value)
|
|
10
|
+
- [set-cookie](#set-cookie)
|
|
10
11
|
- [.headers(object)](#headersobject)
|
|
11
12
|
- [.getHeader(key)](#getheaderkey)
|
|
12
13
|
- [.getHeaders()](#getheaders)
|
|
@@ -106,11 +107,23 @@ fastify.get('/', async function (req, rep) {
|
|
|
106
107
|
|
|
107
108
|
<a name="header"></a>
|
|
108
109
|
### .header(key, value)
|
|
109
|
-
Sets a response header. If the value is omitted or undefined, it is coerced
|
|
110
|
-
to `''`.
|
|
111
|
-
|
|
110
|
+
Sets a response header. If the value is omitted or undefined, it is coerced to `''`.
|
|
112
111
|
For more information, see [`http.ServerResponse#setHeader`](https://nodejs.org/dist/latest-v14.x/docs/api/http.html#http_response_setheader_name_value).
|
|
113
112
|
|
|
113
|
+
<a name="set-cookie"></a>
|
|
114
|
+
- ### set-cookie
|
|
115
|
+
- When sending different values as a cookie with `set-cookie` as the key, every value will be sent as a cookie instead of replacing the previous value.
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
reply.header('set-cookie', 'foo');
|
|
119
|
+
reply.header('set-cookie', 'bar');
|
|
120
|
+
```
|
|
121
|
+
- The browser will only consider the latest reference of a key for the `set-cookie` header. This is done to avoid parsing the `set-cookie` header when added to a reply and speeds up the serialization of the reply.
|
|
122
|
+
|
|
123
|
+
- To reset the `set-cookie` header, you need to make an explicit call to `reply.removeHeader('set-cookie')`, read more about `.removeHeader(key)` [here](#removeheaderkey).
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
114
127
|
<a name="headers"></a>
|
|
115
128
|
### .headers(object)
|
|
116
129
|
Sets all the keys of the object as response headers. [`.header`](#headerkey-value) will be called under the hood.
|
package/docs/Request.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
The first parameter of the handler function is `Request`.<br>
|
|
5
5
|
Request is a core Fastify object containing the following fields:
|
|
6
6
|
- `query` - the parsed querystring, its format is specified by [`querystringParser`](Server.md#querystringparser)
|
|
7
|
-
- `body` - the
|
|
7
|
+
- `body` - the request payload, see [Content Type Parser](ContentTypeParser.md) for details on what request payloads Fastify natively parses and how to support other content types
|
|
8
8
|
- `params` - the params matching the URL
|
|
9
9
|
- [`headers`](#headers) - the headers getter and setter
|
|
10
10
|
- `raw` - the incoming HTTP request from Node core
|
package/docs/Routes.md
CHANGED
|
@@ -50,6 +50,8 @@ They need to be in
|
|
|
50
50
|
* `preSerialization(request, reply, payload, done)`: a [function](Hooks.md#preserialization) called just before the serialization, it could also be an array of functions.
|
|
51
51
|
* `onSend(request, reply, payload, done)`: a [function](Hooks.md#route-hooks) called right before a response is sent, it could also be an array of functions.
|
|
52
52
|
* `onResponse(request, reply, done)`: a [function](Hooks.md#onresponse) called when a response has been sent, so you will not be able to send more data to the client. It could also be an array of functions.
|
|
53
|
+
* `onTimeout(request, reply, done)`: a [function](Hooks.md#ontimeout) called when a request is timed out and the HTTP socket has been hanged up.
|
|
54
|
+
* `onError(request, reply, error, done)`: a [function](Hooks.md#onerror) called when an Error is thrown or send to the client by the route handler.
|
|
53
55
|
* `handler(request, reply)`: the function that will handle this request. The [Fastify server](Server.md) will be bound to `this` when the handler is called. Note: using an arrow function will break the binding of `this`.
|
|
54
56
|
* `errorHandler(error, request, reply)`: a custom error handler for the scope of the request. Overrides the default error global handler, and anything set by [`setErrorHandler`](Server.md#setErrorHandler), for requests to the route. To access the default handler, you can access `instance.errorHandler`. Note that this will point to fastify's default `errorHandler` only if a plugin hasn't overridden it already.
|
|
55
57
|
* `validatorCompiler({ schema, method, url, httpPart })`: function that builds schemas for request validations. See the [Validation and Serialization](Validation-and-Serialization.md#schema-validator) documentation.
|
package/docs/Server.md
CHANGED
|
@@ -13,6 +13,7 @@ document describes the properties available in that options object.
|
|
|
13
13
|
- [connectionTimeout](./Server.md#connectiontimeout)
|
|
14
14
|
- [keepAliveTimeout](./Server.md#keepalivetimeout)
|
|
15
15
|
- [maxRequestsPerSocket](./Server.md#maxRequestsPerSocket)
|
|
16
|
+
- [requestTimeout](./Server.md#requestTimeout)
|
|
16
17
|
- [ignoreTrailingSlash](./Server.md#ignoretrailingslash)
|
|
17
18
|
- [maxParamLength](./Server.md#maxparamlength)
|
|
18
19
|
- [onProtoPoisoning](./Server.md#onprotopoisoning)
|
|
@@ -94,6 +95,17 @@ is in use. Also, when `serverFactory` option is specified, this option is ignore
|
|
|
94
95
|
|
|
95
96
|
+ Default: `0` (no limit)
|
|
96
97
|
|
|
98
|
+
<a name="factory-request-timeout"></a>
|
|
99
|
+
### `requestTimeout`
|
|
100
|
+
|
|
101
|
+
Defines the maximum number of milliseconds for receiving the entire request from the client.
|
|
102
|
+
[`server.requestTimeout` property](https://nodejs.org/dist/latest/docs/api/http.html#http_server_requesttimeout)
|
|
103
|
+
to understand the effect of this option. Also, when `serverFactory` option is specified, this option is ignored.
|
|
104
|
+
It must be set to a non-zero value (e.g. 120 seconds) to protect against potential Denial-of-Service attacks in case the server is deployed without a reverse proxy in front.
|
|
105
|
+
> At the time of this writing, only node version greater or equal to 14.11.0 support this option. Check the Node.js documentation for availability in the version you are running.
|
|
106
|
+
|
|
107
|
+
+ Default: `0` (no limit)
|
|
108
|
+
|
|
97
109
|
<a name="factory-ignore-slash"></a>
|
|
98
110
|
### `ignoreTrailingSlash`
|
|
99
111
|
|
|
@@ -480,7 +492,7 @@ Configure the Ajv v6 instance used by Fastify without providing a custom one.
|
|
|
480
492
|
const fastify = require('fastify')({
|
|
481
493
|
ajv: {
|
|
482
494
|
customOptions: {
|
|
483
|
-
nullable: false // Refer to [ajv options](https://ajv
|
|
495
|
+
nullable: false // Refer to [ajv options](https://github.com/ajv-validator/ajv/tree/v6#options)
|
|
484
496
|
},
|
|
485
497
|
plugins: [
|
|
486
498
|
require('ajv-merge-patch'),
|
package/docs/Serverless.md
CHANGED
|
@@ -22,6 +22,7 @@ choice with an additional snippet of code.
|
|
|
22
22
|
### Contents
|
|
23
23
|
|
|
24
24
|
- [AWS Lambda](#aws-lambda)
|
|
25
|
+
- [Google Cloud Functions](#google-cloud-functions)
|
|
25
26
|
- [Google Cloud Run](#google-cloud-run)
|
|
26
27
|
- [Netlify Lambda](#netlify-lambda)
|
|
27
28
|
- [Vercel](#vercel)
|
|
@@ -100,6 +101,128 @@ An example deployable with [claudia.js](https://claudiajs.com/tutorials/serverle
|
|
|
100
101
|
- API Gateway does not support streams yet, so you are not able to handle [streams](https://www.fastify.io/docs/latest/Reply/#streams).
|
|
101
102
|
- API Gateway has a timeout of 29 seconds, so it is important to provide a reply during this time.
|
|
102
103
|
|
|
104
|
+
## Google Cloud Functions
|
|
105
|
+
|
|
106
|
+
### Creation of Fastify instance
|
|
107
|
+
```js
|
|
108
|
+
const fastify = require("fastify")({
|
|
109
|
+
logger: true // you can also define the level passing an object configuration to logger: {level: 'debug'}
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Add Custom `contentTypeParser` to Fastify instance
|
|
114
|
+
|
|
115
|
+
As explained [in issue #946](https://github.com/fastify/fastify/issues/946#issuecomment-766319521), since the Google Cloud Functions platform parses the body of the request before it arrives into Fastify instance, troubling the body request in case of `POST` and `PATCH` methods, you need to add a custom [`ContentTypeParser`](https://www.fastify.io/docs/latest/ContentTypeParser/) to mitigate this behavior.
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
fastify.addContentTypeParser('application/json', {}, (req, body, done) => {
|
|
119
|
+
done(null, body.body);
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Define your endpoint (examples)
|
|
124
|
+
|
|
125
|
+
A simple `GET` endpoint:
|
|
126
|
+
```js
|
|
127
|
+
fastify.get('/', async (request, reply) => {
|
|
128
|
+
reply.send({message: 'Hello World!'})
|
|
129
|
+
})
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Or a more complete `POST` endpoint with schema validation:
|
|
133
|
+
```js
|
|
134
|
+
fastify.route({
|
|
135
|
+
method: 'POST',
|
|
136
|
+
url: '/hello',
|
|
137
|
+
schema: {
|
|
138
|
+
body: {
|
|
139
|
+
type: 'object',
|
|
140
|
+
properties: {
|
|
141
|
+
name: { type: 'string'}
|
|
142
|
+
},
|
|
143
|
+
required: ['name']
|
|
144
|
+
},
|
|
145
|
+
response: {
|
|
146
|
+
200: {
|
|
147
|
+
type: 'object',
|
|
148
|
+
properties: {
|
|
149
|
+
message: {type: 'string'}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
handler: async (request, reply) => {
|
|
155
|
+
const { name } = request.body;
|
|
156
|
+
reply.code(200).send({
|
|
157
|
+
message: `Hello ${name}!`
|
|
158
|
+
})
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Implement and export the function
|
|
164
|
+
|
|
165
|
+
Final step, implement the function to handle the request and pass it to Fastify by emitting `request` event to `fastify.server`:
|
|
166
|
+
|
|
167
|
+
```js
|
|
168
|
+
const fastifyFunction = async (request, reply) => {
|
|
169
|
+
await fastify.ready();
|
|
170
|
+
fastify.server.emit('request', request, reply)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export.fastifyFunction = fastifyFunction;
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Local test
|
|
177
|
+
|
|
178
|
+
Install [Google Functions Framework for Node.js](https://github.com/GoogleCloudPlatform/functions-framework-nodejs).
|
|
179
|
+
|
|
180
|
+
You can install it globally:
|
|
181
|
+
```bash
|
|
182
|
+
npm i -g @google-cloud/functions-framework
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Or as a development library:
|
|
186
|
+
```bash
|
|
187
|
+
npm i --save-dev @google-cloud/functions-framework
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Than you can run your function locally with Functions Framework:
|
|
191
|
+
``` bash
|
|
192
|
+
npx @google-cloud/functions-framework --target=fastifyFunction
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Or add this command to your `package.json` scripts:
|
|
196
|
+
```json
|
|
197
|
+
"scripts": {
|
|
198
|
+
...
|
|
199
|
+
"dev": "npx @google-cloud/functions-framework --target=fastifyFunction"
|
|
200
|
+
...
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
and run it with `npm run dev`.
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
### Deploy
|
|
207
|
+
```bash
|
|
208
|
+
gcloud functions deploy fastifyFunction \
|
|
209
|
+
--runtime nodejs14 --trigger-http --region $GOOGLE_REGION --allow-unauthenticated
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
#### Read logs
|
|
213
|
+
```bash
|
|
214
|
+
gcloud functions logs read
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
#### Example request to `/hello` endpoint
|
|
218
|
+
```bash
|
|
219
|
+
curl -X POST https://$GOOGLE_REGION-$GOOGLE_PROJECT.cloudfunctions.net/me -H "Content-Type: application/json" -d '{ "name": "Fastify" }'
|
|
220
|
+
{"message":"Hello Fastify!"}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### References
|
|
224
|
+
- [Google Cloud Functions - Node.js Quickstart ](https://cloud.google.com/functions/docs/quickstart-nodejs)
|
|
225
|
+
|
|
103
226
|
## Google Cloud Run
|
|
104
227
|
|
|
105
228
|
Unlike AWS Lambda or Google Cloud Functions, Google Cloud Run is a serverless **container** environment. Its primary purpose is to provide an infrastructure-abstracted environment to run arbitrary containers. As a result, Fastify can be deployed to Google Cloud Run with little-to-no code changes from the way you would write your Fastify app normally.
|
|
@@ -10,6 +10,10 @@ Fastify uses a schema-based approach, and even if it is not mandatory we recomme
|
|
|
10
10
|
> user-provided schemas. See [Ajv](https://npm.im/ajv) and
|
|
11
11
|
> [fast-json-stringify](https://npm.im/fast-json-stringify) for more
|
|
12
12
|
> details.
|
|
13
|
+
>
|
|
14
|
+
> Moreover, the [`$async` Ajv feature](https://ajv.js.org/guide/async-validation.html) should not be used as part of the first validation strategy.
|
|
15
|
+
> This option is used to access Databases and reading them during the validation process may lead to Denial of Service Attacks to your
|
|
16
|
+
> application. If you need to run `async` tasks, use [Fastify's hooks](./Hooks.md) instead after validation completes, such as `preHandler`.
|
|
13
17
|
|
|
14
18
|
|
|
15
19
|
### Core concepts
|
|
@@ -545,7 +549,7 @@ fastify.post('/the/url', { schema }, handler)
|
|
|
545
549
|
<a name="schema-serializer"></a>
|
|
546
550
|
#### Serializer Compiler
|
|
547
551
|
|
|
548
|
-
The `serializerCompiler` is a function that returns a function that must return a string from an input object.
|
|
552
|
+
The `serializerCompiler` is a function that returns a function that must return a string from an input object. When you define a response JSON Schema, you can change the default serialization method by providing a function to serialize every route where you do.
|
|
549
553
|
|
|
550
554
|
```js
|
|
551
555
|
fastify.setSerializerCompiler(({ schema, method, url, httpStatus }) => {
|
|
@@ -642,6 +646,7 @@ fastify.setErrorHandler(function (error, request, reply) {
|
|
|
642
646
|
```
|
|
643
647
|
|
|
644
648
|
If you want custom error response in schema without headaches and quickly, you can take a look at [`ajv-errors`](https://github.com/epoberezkin/ajv-errors). Check out the [example](https://github.com/fastify/example/blob/HEAD/validation-messages/custom-errors-messages.js) usage.
|
|
649
|
+
> Make sure to install version 1.0.1 of `ajv-errors`, because later versions of it are not compatible with AJV v6 (the version shipped by Fastify v3).
|
|
645
650
|
|
|
646
651
|
Below is an example showing how to add **custom error messages for each property** of a schema by supplying custom AJV options.
|
|
647
652
|
Inline comments in the schema below describe how to configure it to show a different error message for each case:
|
|
@@ -649,7 +654,10 @@ Inline comments in the schema below describe how to configure it to show a diffe
|
|
|
649
654
|
```js
|
|
650
655
|
const fastify = Fastify({
|
|
651
656
|
ajv: {
|
|
652
|
-
customOptions: {
|
|
657
|
+
customOptions: {
|
|
658
|
+
jsonPointers: true,
|
|
659
|
+
allErrors: true // Warning: Enabling this option may lead to this security issue https://www.cvedetails.com/cve/CVE-2020-8192/
|
|
660
|
+
},
|
|
653
661
|
plugins: [
|
|
654
662
|
require('ajv-errors')
|
|
655
663
|
]
|
package/fastify.d.ts
CHANGED
|
@@ -97,6 +97,8 @@ export type FastifyServerOptions<
|
|
|
97
97
|
ignoreTrailingSlash?: boolean,
|
|
98
98
|
connectionTimeout?: number,
|
|
99
99
|
keepAliveTimeout?: number,
|
|
100
|
+
maxRequestsPerSocket?: number,
|
|
101
|
+
requestTimeout?: number,
|
|
100
102
|
pluginTimeout?: number,
|
|
101
103
|
bodyLimit?: number,
|
|
102
104
|
maxParamLength?: number,
|
package/fastify.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const VERSION = '3.24.1'
|
|
4
|
+
|
|
3
5
|
const Avvio = require('avvio')
|
|
4
6
|
const http = require('http')
|
|
5
7
|
const querystring = require('querystring')
|
|
6
8
|
let lightMyRequest
|
|
7
|
-
let version
|
|
8
|
-
let versionLoaded = false
|
|
9
9
|
|
|
10
10
|
const {
|
|
11
11
|
kAvvioBoot,
|
|
@@ -133,6 +133,7 @@ function fastify (options) {
|
|
|
133
133
|
options.connectionTimeout = options.connectionTimeout || defaultInitOptions.connectionTimeout
|
|
134
134
|
options.keepAliveTimeout = options.keepAliveTimeout || defaultInitOptions.keepAliveTimeout
|
|
135
135
|
options.maxRequestsPerSocket = options.maxRequestsPerSocket || defaultInitOptions.maxRequestsPerSocket
|
|
136
|
+
options.requestTimeout = options.requestTimeout || defaultInitOptions.requestTimeout
|
|
136
137
|
options.logger = logger
|
|
137
138
|
options.genReqId = genReqId
|
|
138
139
|
options.requestIdHeader = requestIdHeader
|
|
@@ -325,12 +326,7 @@ function fastify (options) {
|
|
|
325
326
|
get () { return this[kSchemaController].getSerializerCompiler() }
|
|
326
327
|
},
|
|
327
328
|
version: {
|
|
328
|
-
get () {
|
|
329
|
-
if (versionLoaded === false) {
|
|
330
|
-
version = loadVersion()
|
|
331
|
-
}
|
|
332
|
-
return version
|
|
333
|
-
}
|
|
329
|
+
get () { return VERSION }
|
|
334
330
|
},
|
|
335
331
|
errorHandler: {
|
|
336
332
|
get () {
|
|
@@ -635,7 +631,7 @@ function fastify (options) {
|
|
|
635
631
|
function setSchemaController (schemaControllerOpts) {
|
|
636
632
|
throwIfAlreadyStarted('Cannot call "setSchemaController" when fastify instance is already started!')
|
|
637
633
|
const old = this[kSchemaController]
|
|
638
|
-
const schemaController = SchemaController.buildSchemaController(old
|
|
634
|
+
const schemaController = SchemaController.buildSchemaController(old, Object.assign({}, old.opts, schemaControllerOpts))
|
|
639
635
|
this[kSchemaController] = schemaController
|
|
640
636
|
this.getSchema = schemaController.getSchema.bind(schemaController)
|
|
641
637
|
this.getSchemas = schemaController.getSchemas.bind(schemaController)
|
|
@@ -691,20 +687,6 @@ function wrapRouting (httpHandler, { rewriteUrl, logger }) {
|
|
|
691
687
|
}
|
|
692
688
|
}
|
|
693
689
|
|
|
694
|
-
function loadVersion () {
|
|
695
|
-
versionLoaded = true
|
|
696
|
-
const fs = require('fs')
|
|
697
|
-
const path = require('path')
|
|
698
|
-
try {
|
|
699
|
-
const pkgPath = path.join(__dirname, 'package.json')
|
|
700
|
-
fs.accessSync(pkgPath, fs.constants.R_OK)
|
|
701
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath))
|
|
702
|
-
return pkg.name === 'fastify' ? pkg.version : undefined
|
|
703
|
-
} catch (e) {
|
|
704
|
-
return undefined
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
|
|
708
690
|
/**
|
|
709
691
|
* These export configurations enable JS and TS developers
|
|
710
692
|
* to consumer fastify in whatever way best suits their needs.
|