fastify 2.7.1 → 2.11.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 +15 -4
- package/build/build-validation.js +8 -0
- package/docs/Benchmarking.md +2 -2
- package/docs/ContentTypeParser.md +12 -10
- package/docs/Decorators.md +14 -14
- package/docs/Ecosystem.md +7 -1
- package/docs/Errors.md +13 -8
- package/docs/Fluent-Schema.md +9 -12
- package/docs/Getting-Started.md +29 -25
- package/docs/HTTP2.md +1 -1
- package/docs/Hooks.md +201 -186
- package/docs/LTS.md +6 -7
- package/docs/Logging.md +10 -10
- package/docs/Middleware.md +59 -0
- package/docs/Plugins-Guide.md +52 -52
- package/docs/Plugins.md +3 -0
- package/docs/Reply.md +47 -3
- package/docs/Routes.md +120 -8
- package/docs/Server.md +69 -3
- package/docs/Serverless.md +76 -4
- package/docs/TypeScript.md +33 -10
- package/docs/Validation-and-Serialization.md +137 -1
- package/examples/typescript-server.ts +1 -1
- package/fastify.d.ts +52 -13
- package/fastify.js +68 -7
- package/lib/configValidator.js +99 -52
- package/lib/contentTypeParser.js +4 -4
- package/lib/context.js +2 -1
- package/lib/errors.js +21 -18
- package/lib/fourOhFour.js +10 -10
- package/lib/handleRequest.js +1 -2
- package/lib/logger.js +2 -2
- package/lib/pluginUtils.js +32 -0
- package/lib/reply.js +41 -6
- package/lib/route.js +37 -9
- package/lib/schemas.js +23 -12
- package/lib/symbols.js +4 -1
- package/lib/validation.js +15 -9
- package/lib/wrapThenable.js +1 -1
- package/package.json +34 -26
- package/test/404s.test.js +41 -1
- package/test/async-await.js +66 -0
- package/test/custom-parser.test.js +1 -1
- package/test/custom-querystring-parser.test.js +1 -1
- package/test/decorator.test.js +48 -0
- package/test/emit-warning.test.js +3 -3
- package/test/fastify-instance.test.js +29 -0
- package/test/helper.js +7 -7
- package/test/hooks-async.js +4 -3
- package/test/hooks.test.js +27 -8
- package/test/input-validation.test.js +126 -0
- package/test/internals/errors.test.js +9 -1
- package/test/internals/initialConfig.test.js +4 -2
- package/test/internals/plugin.test.js +4 -4
- package/test/internals/reply.test.js +78 -6
- package/test/internals/schemas.test.js +30 -0
- package/test/internals/validation.test.js +18 -0
- package/test/listen.test.js +1 -1
- package/test/logger.test.js +314 -1
- package/test/plugin.test.js +171 -0
- package/test/promises.test.js +55 -0
- package/test/proto-poisoning.test.js +76 -0
- package/test/route-hooks.test.js +109 -91
- package/test/route-prefix.test.js +1 -1
- package/test/schemas.test.js +450 -0
- package/test/shared-schemas.test.js +2 -2
- package/test/stream.test.js +10 -6
- package/test/throw.test.js +48 -2
- package/test/types/index.ts +86 -1
- package/test/validation-error-handling.test.js +3 -3
- package/test/versioned-routes.test.js +1 -1
- package/docs/Middlewares.md +0 -59
package/docs/Routes.md
CHANGED
|
@@ -1,14 +1,34 @@
|
|
|
1
1
|
<h1 align="center">Fastify</h1>
|
|
2
2
|
|
|
3
3
|
## Routes
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
The routes methods will configure the endpoints of your application.
|
|
6
|
+
You have two ways to declare a route with Fastify, the shorthand method and the full declaration.
|
|
7
|
+
|
|
8
|
+
- [Full Declaration](#full-declaration)
|
|
9
|
+
- [Route Options](#options)
|
|
10
|
+
- [Shorthand Declaration](#shorthand-declaration)
|
|
11
|
+
- [URL Parameters](#url-building)
|
|
12
|
+
- [Use `async`/`await`](#async-await)
|
|
13
|
+
- [Promise resolution](#promise-resolution)
|
|
14
|
+
- [Route Prefixing](#route-prefixing)
|
|
15
|
+
- Logs
|
|
16
|
+
- [Custom Log Level](#custom-log-level)
|
|
17
|
+
- [Custom Log Serializer](#custom-log-serializer)
|
|
18
|
+
- [Route handler configuration](#routes-config)
|
|
19
|
+
- [Route's Versioning](#version)
|
|
20
|
+
|
|
5
21
|
<a name="full-declaration"></a>
|
|
6
22
|
### Full declaration
|
|
23
|
+
|
|
7
24
|
```js
|
|
8
25
|
fastify.route(options)
|
|
9
26
|
```
|
|
10
|
-
* `method`: currently it supports `'DELETE'`, `'GET'`, `'HEAD'`, `'PATCH'`, `'POST'`, `'PUT'` and `'OPTIONS'`. It could also be an array of methods.
|
|
11
27
|
|
|
28
|
+
<a name="options"></a>
|
|
29
|
+
### Routes option
|
|
30
|
+
|
|
31
|
+
* `method`: currently it supports `'DELETE'`, `'GET'`, `'HEAD'`, `'PATCH'`, `'POST'`, `'PUT'` and `'OPTIONS'`. It could also be an array of methods.
|
|
12
32
|
* `url`: the path of the url to match this route (alias: `path`).
|
|
13
33
|
* `schema`: an object containing the schemas for the request and response.
|
|
14
34
|
They need to be in
|
|
@@ -23,14 +43,18 @@ They need to be in
|
|
|
23
43
|
* `response`: filter and generate a schema for the response, setting a
|
|
24
44
|
schema allows us to have 10-20% more throughput.
|
|
25
45
|
* `attachValidation`: attach `validationError` to request, if there is a schema validation error, instead of sending the error to the error handler.
|
|
26
|
-
* `onRequest(request, reply, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#
|
|
27
|
-
* `
|
|
28
|
-
* `
|
|
29
|
-
* `
|
|
46
|
+
* `onRequest(request, reply, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#onrequest) as soon that a request is received, it could also be an array of functions.
|
|
47
|
+
* `preParsing(request, reply, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#preparsing) called before parsing the request, it could also be an array of functions.
|
|
48
|
+
* `preValidation(request, reply, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#prevalidation) called after the shared `preValidation` hooks, useful if you need to perform authentication at route level for example, it could also be an array of functions.
|
|
49
|
+
* `preHandler(request, reply, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#prehandler) called just before the request handler, it could also be an array of functions.
|
|
50
|
+
* `preSerialization(request, reply, payload, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#preserialization) called just before the serialization, it could also be an array of functions.
|
|
51
|
+
* `onSend(request, reply, payload, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/Hooks.md#route-hooks) called right before a response is sent, it could also be an array of functions.
|
|
52
|
+
* `onResponse(request, reply, payload, done)`: a [function](https://github.com/fastify/fastify/blob/master/docs/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.
|
|
30
53
|
* `handler(request, reply)`: the function that will handle this request.
|
|
31
54
|
* `schemaCompiler(schema)`: the function that build the schema for the validations. See [here](https://github.com/fastify/fastify/blob/master/docs/Validation-and-Serialization.md#schema-compiler)
|
|
32
55
|
* `bodyLimit`: prevents the default JSON body parser from parsing request bodies larger than this number of bytes. Must be an integer. You may also set this option globally when first creating the Fastify instance with `fastify(options)`. Defaults to `1048576` (1 MiB).
|
|
33
56
|
* `logLevel`: set log level for this route. See below.
|
|
57
|
+
* `logSerializers`: set serializers to log for this route.
|
|
34
58
|
* `config`: object used to store custom configuration.
|
|
35
59
|
* `version`: a [semver](http://semver.org/) compatible string that defined the version of the endpoint. [Example](https://github.com/fastify/fastify/blob/master/docs/Routes.md#version).
|
|
36
60
|
* `prefixTrailingSlash`: string used to determine how to handle passing `/` as a route with a prefix.
|
|
@@ -168,7 +192,6 @@ fastify.get('/', options, async function (request, reply) {
|
|
|
168
192
|
return processed
|
|
169
193
|
})
|
|
170
194
|
```
|
|
171
|
-
**Warning:** You can't return `undefined`. For more details read [promise-resolution](#promise-resolution).
|
|
172
195
|
|
|
173
196
|
As you can see we are not calling `reply.send` to send back the data to the user. You just need to return the body and you are done!
|
|
174
197
|
|
|
@@ -180,8 +203,32 @@ fastify.get('/', options, async function (request, reply) {
|
|
|
180
203
|
reply.send(processed)
|
|
181
204
|
})
|
|
182
205
|
```
|
|
206
|
+
|
|
207
|
+
If the route is wrapping a callback-based API that will call
|
|
208
|
+
`reply.send()` outside of the promise chain, it is possible to `await reply`:
|
|
209
|
+
|
|
210
|
+
```js
|
|
211
|
+
fastify.get('/', options, async function (request, reply) {
|
|
212
|
+
setImmediate(() => {
|
|
213
|
+
reply.send({ hello: 'world' })
|
|
214
|
+
})
|
|
215
|
+
await reply
|
|
216
|
+
})
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Returning reply also works:
|
|
220
|
+
|
|
221
|
+
```js
|
|
222
|
+
fastify.get('/', options, async function (request, reply) {
|
|
223
|
+
setImmediate(() => {
|
|
224
|
+
reply.send({ hello: 'world' })
|
|
225
|
+
})
|
|
226
|
+
return reply
|
|
227
|
+
})
|
|
228
|
+
```
|
|
229
|
+
|
|
183
230
|
**Warning:**
|
|
184
|
-
*
|
|
231
|
+
* When using both `return value` and `reply.send(value)` at the same time, the first one that happens takes precedence, the second value will be discarded, and a *warn* log will also be emitted because you tried to send a response twice.
|
|
185
232
|
* You can't return `undefined`. For more details read [promise-resolution](#promise-resolution).
|
|
186
233
|
|
|
187
234
|
<a name="promise-resolution"></a>
|
|
@@ -214,6 +261,7 @@ fastify.register(require('./routes/v2/users'), { prefix: '/v2' })
|
|
|
214
261
|
|
|
215
262
|
fastify.listen(3000)
|
|
216
263
|
```
|
|
264
|
+
|
|
217
265
|
```js
|
|
218
266
|
// routes/v1/users.js
|
|
219
267
|
module.exports = function (fastify, opts, done) {
|
|
@@ -221,6 +269,7 @@ module.exports = function (fastify, opts, done) {
|
|
|
221
269
|
done()
|
|
222
270
|
}
|
|
223
271
|
```
|
|
272
|
+
|
|
224
273
|
```js
|
|
225
274
|
// routes/v2/users.js
|
|
226
275
|
module.exports = function (fastify, opts, done) {
|
|
@@ -263,6 +312,7 @@ fastify.register(require('./routes/events'), { logLevel: 'debug' })
|
|
|
263
312
|
|
|
264
313
|
fastify.listen(3000)
|
|
265
314
|
```
|
|
315
|
+
|
|
266
316
|
Or you can directly pass it to a route:
|
|
267
317
|
```js
|
|
268
318
|
fastify.get('/', { logLevel: 'warn' }, (request, reply) => {
|
|
@@ -271,6 +321,64 @@ fastify.get('/', { logLevel: 'warn' }, (request, reply) => {
|
|
|
271
321
|
```
|
|
272
322
|
*Remember that the custom log level is applied only to the routes, and not to the global Fastify Logger, accessible with `fastify.log`*
|
|
273
323
|
|
|
324
|
+
<a name="custom-log-serializer"></a>
|
|
325
|
+
### Custom Log Serializer
|
|
326
|
+
|
|
327
|
+
In some context, you may need to log a large object but it could be a waste of resources for some routes. In this case, you can define some [`serializer`](https://github.com/pinojs/pino/blob/master/docs/api.md#bindingsserializers-object) and attach them in the right context!
|
|
328
|
+
|
|
329
|
+
```js
|
|
330
|
+
const fastify = require('fastify')({ logger: true })
|
|
331
|
+
|
|
332
|
+
fastify.register(require('./routes/user'), {
|
|
333
|
+
logSerializers: {
|
|
334
|
+
user: (value) => `My serializer one - ${value.name}`
|
|
335
|
+
}
|
|
336
|
+
})
|
|
337
|
+
fastify.register(require('./routes/events'), {
|
|
338
|
+
logSerializers: {
|
|
339
|
+
user: (value) => `My serializer two - ${value.name} ${value.surname}`
|
|
340
|
+
}
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
fastify.listen(3000)
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
You can inherit serializers by context:
|
|
347
|
+
|
|
348
|
+
```js
|
|
349
|
+
const fastify = Fastify({
|
|
350
|
+
logger: {
|
|
351
|
+
level: 'info',
|
|
352
|
+
serializers: {
|
|
353
|
+
user (req) {
|
|
354
|
+
return {
|
|
355
|
+
method: req.method,
|
|
356
|
+
url: req.url,
|
|
357
|
+
headers: req.headers,
|
|
358
|
+
hostname: req.hostname,
|
|
359
|
+
remoteAddress: req.ip,
|
|
360
|
+
remotePort: req.connection.remotePort
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
fastify.register(context1, {
|
|
368
|
+
logSerializers: {
|
|
369
|
+
user: value => `My serializer father - ${value}`
|
|
370
|
+
}
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
async function context1 (fastify, opts) {
|
|
374
|
+
fastify.get('/', (req, reply) => {
|
|
375
|
+
req.log.info({ user: 'call father serializer', key: 'another key' }) // shows: { user: 'My serializer father - call father serializer', key: 'another key' }
|
|
376
|
+
reply.send({})
|
|
377
|
+
})
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
fastify.listen(3000)
|
|
381
|
+
```
|
|
274
382
|
|
|
275
383
|
<a name="routes-config"></a>
|
|
276
384
|
### Config
|
|
@@ -292,10 +400,12 @@ fastify.listen(3000)
|
|
|
292
400
|
|
|
293
401
|
<a name="version"></a>
|
|
294
402
|
### Version
|
|
403
|
+
|
|
295
404
|
#### Default
|
|
296
405
|
If needed you can provide a version option, which will allow you to declare multiple versions of the same route. The versioning should follow the [semver](http://semver.org/) specification.<br/>
|
|
297
406
|
Fastify will automatically detect the `Accept-Version` header and route the request accordingly (advanced ranges and pre-releases currently are not supported).<br/>
|
|
298
407
|
*Be aware that using this feature will cause a degradation of the overall performances of the router.*
|
|
408
|
+
|
|
299
409
|
```js
|
|
300
410
|
fastify.route({
|
|
301
411
|
method: 'GET',
|
|
@@ -316,7 +426,9 @@ fastify.inject({
|
|
|
316
426
|
// { hello: 'world' }
|
|
317
427
|
})
|
|
318
428
|
```
|
|
429
|
+
|
|
319
430
|
If you declare multiple versions with the same major or minor, Fastify will always choose the highest compatible with the `Accept-Version` header value.<br/>
|
|
320
431
|
If the request will not have the `Accept-Version` header, a 404 error will be returned.
|
|
432
|
+
|
|
321
433
|
#### Custom
|
|
322
434
|
It's possible to define a custom versioning logic. This can be done through the [`versioning`](https://github.com/fastify/fastify/blob/master/docs/Server.md#versioning) configuration, when creating a fastify server instance.
|
package/docs/Server.md
CHANGED
|
@@ -75,7 +75,7 @@ Defines the maximum payload, in bytes, the server is allowed to accept.
|
|
|
75
75
|
|
|
76
76
|
Defines what action the framework must take when parsing a JSON object
|
|
77
77
|
with `__proto__`. This functionality is provided by
|
|
78
|
-
[
|
|
78
|
+
[secure-json-parse](https://github.com/fastify/secure-json-parse).
|
|
79
79
|
See https://hueniverse.com/a-tale-of-prototype-poisoning-2610fa170061
|
|
80
80
|
for more details about prototype poisoning attacks.
|
|
81
81
|
|
|
@@ -83,6 +83,19 @@ Possible values are `'error'`, `'remove'` and `'ignore'`.
|
|
|
83
83
|
|
|
84
84
|
+ Default: `'error'`
|
|
85
85
|
|
|
86
|
+
<a name="factory-on-constructor-poisoning"></a>
|
|
87
|
+
### `onConstructorPoisoning`
|
|
88
|
+
|
|
89
|
+
Defines what action the framework must take when parsing a JSON object
|
|
90
|
+
with `constructor`. This functionality is provided by
|
|
91
|
+
[secure-json-parse](https://github.com/fastify/secure-json-parse).
|
|
92
|
+
See https://hueniverse.com/a-tale-of-prototype-poisoning-2610fa170061
|
|
93
|
+
for more details about prototype poisoning attacks.
|
|
94
|
+
|
|
95
|
+
Possible values are `'error'`, `'remove'` and `'ignore'`.
|
|
96
|
+
|
|
97
|
+
+ Default: `'ignore'`
|
|
98
|
+
|
|
86
99
|
<a name="factory-logger"></a>
|
|
87
100
|
### `logger`
|
|
88
101
|
|
|
@@ -104,7 +117,7 @@ are not present on the object, they will be added accordingly:
|
|
|
104
117
|
for incoming requests. The default function generates sequential identifiers.
|
|
105
118
|
* `level`: the minimum logging level. If not set, it will be set to `'info'`.
|
|
106
119
|
* `serializers`: a hash of serialization functions. By default, serializers
|
|
107
|
-
are added for `req` (incoming request objects), `res` (outgoing
|
|
120
|
+
are added for `req` (incoming request objects), `res` (outgoing response
|
|
108
121
|
objets), and `err` (standard `Error` objects). When a log method receives
|
|
109
122
|
an object with any of these properties then the respective serializer will
|
|
110
123
|
be used for that property. For example:
|
|
@@ -360,6 +373,42 @@ If `false`, the server routes the incoming request as usual.
|
|
|
360
373
|
|
|
361
374
|
+ Default: `true`
|
|
362
375
|
|
|
376
|
+
<a name="factory-ajv"></a>
|
|
377
|
+
### `ajv`
|
|
378
|
+
|
|
379
|
+
Configure the ajv instance used by Fastify without providing a custom one.
|
|
380
|
+
|
|
381
|
+
+ Default:
|
|
382
|
+
|
|
383
|
+
```js
|
|
384
|
+
{
|
|
385
|
+
customOptions: {
|
|
386
|
+
removeAdditional: true,
|
|
387
|
+
useDefaults: true,
|
|
388
|
+
coerceTypes: true,
|
|
389
|
+
allErrors: true,
|
|
390
|
+
nullable: true
|
|
391
|
+
},
|
|
392
|
+
plugins: []
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
```js
|
|
397
|
+
const fastify = require('fastify')({
|
|
398
|
+
ajv: {
|
|
399
|
+
customOptions: {
|
|
400
|
+
nullable: false // Refer to [ajv options](https://ajv.js.org/#options)
|
|
401
|
+
},
|
|
402
|
+
plugins: [
|
|
403
|
+
require('ajv-merge-patch')
|
|
404
|
+
[require('ajv-keywords'), 'instanceof'];
|
|
405
|
+
// Usage: [plugin, pluginOptions] - Plugin with options
|
|
406
|
+
// Usage: plugin - Plugin without options
|
|
407
|
+
]
|
|
408
|
+
}
|
|
409
|
+
})
|
|
410
|
+
```
|
|
411
|
+
|
|
363
412
|
## Instance
|
|
364
413
|
|
|
365
414
|
### Server Methods
|
|
@@ -547,7 +596,7 @@ A plugin can be a set of routes, a server decorator or whatever, check [here](ht
|
|
|
547
596
|
|
|
548
597
|
<a name="use"></a>
|
|
549
598
|
#### use
|
|
550
|
-
Function to add middlewares to Fastify, check [here](https://github.com/fastify/fastify/blob/master/docs/
|
|
599
|
+
Function to add middlewares to Fastify, check [here](https://github.com/fastify/fastify/blob/master/docs/Middleware.md).
|
|
551
600
|
|
|
552
601
|
<a name="addHook"></a>
|
|
553
602
|
#### addHook
|
|
@@ -581,6 +630,18 @@ fastify.register(function (instance, opts, done) {
|
|
|
581
630
|
}, { prefix: '/v1' })
|
|
582
631
|
```
|
|
583
632
|
|
|
633
|
+
<a name="pluginName"></a>
|
|
634
|
+
#### pluginName
|
|
635
|
+
Name of the current plugin. There are three ways to define a name (in order).
|
|
636
|
+
|
|
637
|
+
1. If you use [fastify-plugin](https://github.com/fastify/fastify-plugin) the metadata `name` is used.
|
|
638
|
+
2. If you `module.exports` a plugin the filename is used.
|
|
639
|
+
3. If you use a regular [function declaration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#Defining_functions) the function name is used.
|
|
640
|
+
|
|
641
|
+
*Fallback*: The first two lines of your plugin will represent the plugin name. Newlines are replaced by ` -- `. This will help to indentify the root cause when you deal with many plugins.
|
|
642
|
+
|
|
643
|
+
Important: If you have to deal with nested plugins the name differs with the usage of the [fastify-plugin](https://github.com/fastify/fastify-plugin) because no new scope is created and therefore we have no place to attach contextual data. In that case the plugin name will represent the boot order of all involved plugins in the format of `plugin-A -> plugin-B`.
|
|
644
|
+
|
|
584
645
|
<a name="log"></a>
|
|
585
646
|
#### log
|
|
586
647
|
The logger instance, check [here](https://github.com/fastify/fastify/blob/master/docs/Logging.md).
|
|
@@ -610,6 +671,11 @@ fastify.setReplySerializer(function (payload, statusCode){
|
|
|
610
671
|
#### setSchemaCompiler
|
|
611
672
|
Set the schema compiler for all routes [here](https://github.com/fastify/fastify/blob/master/docs/Validation-and-Serialization.md#schema-compiler).
|
|
612
673
|
|
|
674
|
+
<a name="set-schema-resolver"></a>
|
|
675
|
+
#### setSchemaResolver
|
|
676
|
+
Set the schema `$ref` resolver for all routes [here](https://github.com/fastify/fastify/blob/master/docs/Validation-and-Serialization.md#schema-resolver).
|
|
677
|
+
|
|
678
|
+
|
|
613
679
|
<a name="schema-compiler"></a>
|
|
614
680
|
#### schemaCompiler
|
|
615
681
|
This property can be used to set the schema compiler, it is a shortcut for the `setSchemaCompiler` method, and get the schema compiler back for all routes.
|
package/docs/Serverless.md
CHANGED
|
@@ -6,6 +6,7 @@ Run serverless applications and REST APIs using your existing Fastify applicatio
|
|
|
6
6
|
|
|
7
7
|
- [AWS Lambda](#aws-lambda)
|
|
8
8
|
- [Google Cloud Run](#google-cloud-run)
|
|
9
|
+
- [Zeit Now](#zeit-now)
|
|
9
10
|
|
|
10
11
|
### Attention Readers:
|
|
11
12
|
> Fastify is not designed to run on serverless environments.
|
|
@@ -35,7 +36,7 @@ function init() {
|
|
|
35
36
|
return app;
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
if (require.main
|
|
39
|
+
if (require.main === module) {
|
|
39
40
|
// called directly i.e. "node app"
|
|
40
41
|
init().listen(3000, (err) => {
|
|
41
42
|
if (err) console.error(err);
|
|
@@ -93,9 +94,9 @@ An example deployable with [claudia.js](https://claudiajs.com/tutorials/serverle
|
|
|
93
94
|
|
|
94
95
|
## Google Cloud Run
|
|
95
96
|
|
|
96
|
-
Unlike AWS Lambda or Google Cloud Functions, Google Cloud Run is a serverless **container** environment. It's primary purpose is to provide an
|
|
97
|
+
Unlike AWS Lambda or Google Cloud Functions, Google Cloud Run is a serverless **container** environment. It's 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.
|
|
97
98
|
|
|
98
|
-
*Follow the steps below to deploy to Google Cloud Run if you are already familiar with gcloud or just follow their [quickstart](https://cloud.google.com/run/docs/quickstarts/build-and-deploy)
|
|
99
|
+
*Follow the steps below to deploy to Google Cloud Run if you are already familiar with gcloud or just follow their [quickstart](https://cloud.google.com/run/docs/quickstarts/build-and-deploy)*.
|
|
99
100
|
|
|
100
101
|
### Adjust Fastfiy server
|
|
101
102
|
|
|
@@ -175,7 +176,7 @@ npm-debug.log
|
|
|
175
176
|
|
|
176
177
|
### Submit build
|
|
177
178
|
|
|
178
|
-
Next, submit your app to be built into a Docker image by running the following command (replacing `PROJECT-ID` and `APP-NAME` with your GCP project id and an app name:
|
|
179
|
+
Next, submit your app to be built into a Docker image by running the following command (replacing `PROJECT-ID` and `APP-NAME` with your GCP project id and an app name):
|
|
179
180
|
|
|
180
181
|
```bash
|
|
181
182
|
gcloud builds submit --tag gcr.io/PROJECT-ID/APP-NAME
|
|
@@ -190,3 +191,74 @@ gcloud beta run deploy --image gcr.io/PROJECT-ID/APP-NAME --platform managed
|
|
|
190
191
|
```
|
|
191
192
|
|
|
192
193
|
Your app will be accessible from the URL GCP provides.
|
|
194
|
+
|
|
195
|
+
## Zeit Now
|
|
196
|
+
|
|
197
|
+
[now](https://zeit.co/home) provides zero configuration deployment for
|
|
198
|
+
Node.js applications. In order to use now, it is as simple as
|
|
199
|
+
configuring your `now.json` file like the following:
|
|
200
|
+
|
|
201
|
+
```json
|
|
202
|
+
{
|
|
203
|
+
"version": 2,
|
|
204
|
+
"builds": [
|
|
205
|
+
{
|
|
206
|
+
"src": "api/serverless.js",
|
|
207
|
+
"use": "@now/node",
|
|
208
|
+
"config": {
|
|
209
|
+
"helpers": false
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
],
|
|
213
|
+
"routes": [
|
|
214
|
+
{ "src": "/.*", "dest": "/api/serverless.js"}
|
|
215
|
+
]
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Then, write a `api/serverless.js` like so:
|
|
220
|
+
|
|
221
|
+
```js
|
|
222
|
+
'use strict'
|
|
223
|
+
|
|
224
|
+
const build = require('./index')
|
|
225
|
+
|
|
226
|
+
const app = build()
|
|
227
|
+
|
|
228
|
+
module.exports = async function (req, res) {
|
|
229
|
+
await app.ready()
|
|
230
|
+
app.server.emit('request', req, res)
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
And a `api/index.js` file:
|
|
235
|
+
|
|
236
|
+
```js
|
|
237
|
+
'use strict'
|
|
238
|
+
|
|
239
|
+
const fastify = require('fastify')
|
|
240
|
+
|
|
241
|
+
function build () {
|
|
242
|
+
const app = fastify({
|
|
243
|
+
logger: true
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
app.get('/', async (req, res) => {
|
|
247
|
+
const { name = 'World' } = req.query
|
|
248
|
+
req.log.info({ name }, 'hello world!')
|
|
249
|
+
return `Hello ${name}!`
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
return app
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
module.exports = build
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Note that you'll need to use Node 10 by setting it in `package.json`:
|
|
259
|
+
|
|
260
|
+
```js
|
|
261
|
+
"engines": {
|
|
262
|
+
"node": "10.x"
|
|
263
|
+
},
|
|
264
|
+
```
|
package/docs/TypeScript.md
CHANGED
|
@@ -7,7 +7,7 @@ Fastify is shipped with a typings file, but you may need to install `@types/node
|
|
|
7
7
|
## Types support
|
|
8
8
|
We do care about the TypeScript community, and one of our core team members is currently reworking all types.
|
|
9
9
|
We do our best to have the typings updated with the latest version of the API, but *it can happen* that the typings are not in sync.<br/>
|
|
10
|
-
|
|
10
|
+
Luckily this is Open Source and you can contribute to fix them, we will be very happy to accept the fix and release it as soon as possible as a patch release. Checkout the [contributing](#contributing) rules!
|
|
11
11
|
|
|
12
12
|
Plugins may or may not include typings. See [Plugin Types](#plugin-types) for more information.
|
|
13
13
|
|
|
@@ -21,6 +21,7 @@ import { Server, IncomingMessage, ServerResponse } from 'http'
|
|
|
21
21
|
// Create a http server. We pass the relevant typings for our http version used.
|
|
22
22
|
// By passing types we get correctly typed access to the underlying http objects in routes.
|
|
23
23
|
// If using http2 we'd pass <http2.Http2Server, http2.Http2ServerRequest, http2.Http2ServerResponse>
|
|
24
|
+
// For https pass http2.Http2SecureServer or http.SecureServer instead of Server.
|
|
24
25
|
const server: fastify.FastifyInstance<Server, IncomingMessage, ServerResponse> = fastify({})
|
|
25
26
|
|
|
26
27
|
const opts: fastify.RouteShorthandOptions = {
|
|
@@ -106,7 +107,7 @@ const opts: fastify.RouteShorthandOptions = {
|
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
server.get<Query, Params,
|
|
110
|
+
server.get<Query, Params, Headers, Body>('/ping/:bar', opts, (request, reply) => {
|
|
110
111
|
console.log(request.query) // this is of type Query!
|
|
111
112
|
console.log(request.params) // this is of type Params!
|
|
112
113
|
console.log(request.body) // this is of type Body!
|
|
@@ -204,7 +205,7 @@ When updating core types you should make a PR to this repository. Ensure you:
|
|
|
204
205
|
<a id="plugin-types"></a>
|
|
205
206
|
### Plugin Types
|
|
206
207
|
|
|
207
|
-
Plugins maintained by and
|
|
208
|
+
Plugins maintained by and organized under the fastify organization on GitHub should ship with typings just like fastify itself does.
|
|
208
209
|
Some plugins already include typings but many do not. We are happy to accept contributions to those plugins without any typings, see [fastify-cors](https://github.com/fastify/fastify-cors) for an example of a plugin that comes with it's own typings.
|
|
209
210
|
|
|
210
211
|
Typings for third-party-plugins may either be included with the plugin or hosted on DefinitelyTyped. Remember, if you author a plugin to either include typings or publish them on DefinitelyTyped! Information of how to install typings from DefinitelyTyped can be found [here](https://github.com/DefinitelyTyped/DefinitelyTyped#npm).
|
|
@@ -218,26 +219,43 @@ Typings for many plugins that extend the `FastifyRequest`, `FastifyReply` or `Fa
|
|
|
218
219
|
This code shows the typings for the `fastify-static` plugin.
|
|
219
220
|
|
|
220
221
|
```ts
|
|
222
|
+
/// <reference types="node" />
|
|
223
|
+
|
|
221
224
|
// require fastify typings
|
|
222
|
-
import fastify
|
|
223
|
-
|
|
225
|
+
import * as fastify from 'fastify';
|
|
226
|
+
|
|
227
|
+
// require necessary http, http2, https typings
|
|
224
228
|
import { Server, IncomingMessage, ServerResponse } from "http";
|
|
229
|
+
import { Http2SecureServer, Http2Server, Http2ServerRequest, Http2ServerResponse } from "http2";
|
|
230
|
+
import * as https from "https";
|
|
231
|
+
|
|
232
|
+
type HttpServer = Server | Http2Server | Http2SecureServer | https.Server;
|
|
233
|
+
type HttpRequest = IncomingMessage | Http2ServerRequest;
|
|
234
|
+
type HttpResponse = ServerResponse | Http2ServerResponse;
|
|
225
235
|
|
|
226
236
|
// extend fastify typings
|
|
227
237
|
declare module "fastify" {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
238
|
+
interface FastifyReply<HttpResponse> {
|
|
239
|
+
sendFile(filename: string): FastifyReply<HttpResponse>;
|
|
240
|
+
}
|
|
231
241
|
}
|
|
232
242
|
|
|
233
243
|
// declare plugin type using fastify.Plugin
|
|
234
|
-
declare
|
|
244
|
+
declare function fastifyStatic(): fastify.Plugin<
|
|
245
|
+
Server,
|
|
246
|
+
IncomingMessage,
|
|
247
|
+
ServerResponse,
|
|
248
|
+
{
|
|
235
249
|
root: string;
|
|
236
250
|
prefix?: string;
|
|
237
251
|
serve?: boolean;
|
|
238
252
|
decorateReply?: boolean;
|
|
239
253
|
schemaHide?: boolean;
|
|
240
254
|
setHeaders?: (...args: any[]) => void;
|
|
255
|
+
redirect?: boolean;
|
|
256
|
+
wildcard?: boolean | string;
|
|
257
|
+
|
|
258
|
+
// Passed on to `send`
|
|
241
259
|
acceptRanges?: boolean;
|
|
242
260
|
cacheControl?: boolean;
|
|
243
261
|
dotfiles?: boolean;
|
|
@@ -247,7 +265,12 @@ declare const fastifyStatic: fastify.Plugin<Server, IncomingMessage, ServerRespo
|
|
|
247
265
|
index?: string[];
|
|
248
266
|
lastModified?: boolean;
|
|
249
267
|
maxAge?: string | number;
|
|
250
|
-
}
|
|
268
|
+
}
|
|
269
|
+
>;
|
|
270
|
+
|
|
271
|
+
declare namespace fastifyStatic {
|
|
272
|
+
interface FastifyStaticOptions {}
|
|
273
|
+
}
|
|
251
274
|
|
|
252
275
|
// export plugin type
|
|
253
276
|
export = fastifyStatic;
|