fastify 3.24.0 → 3.25.2
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 +30 -29
- package/docs/{Benchmarking.md → Guides/Benchmarking.md} +14 -5
- package/docs/Guides/Ecosystem.md +513 -0
- package/docs/{Fluent-Schema.md → Guides/Fluent-Schema.md} +16 -7
- package/docs/{Getting-Started.md → Guides/Getting-Started.md} +180 -60
- package/docs/Guides/Index.md +30 -4
- package/docs/{Migration-Guide-V3.md → Guides/Migration-Guide-V3.md} +43 -37
- package/docs/{Plugins-Guide.md → Guides/Plugins-Guide.md} +196 -82
- package/docs/{Recommendations.md → Guides/Recommendations.md} +17 -10
- package/docs/{Serverless.md → Guides/Serverless.md} +200 -42
- package/docs/Guides/Style-Guide.md +246 -0
- package/docs/{Testing.md → Guides/Testing.md} +26 -12
- package/docs/Guides/Write-Plugin.md +102 -0
- package/docs/{ContentTypeParser.md → Reference/ContentTypeParser.md} +68 -30
- package/docs/{Decorators.md → Reference/Decorators.md} +52 -47
- package/docs/{Encapsulation.md → Reference/Encapsulation.md} +3 -3
- package/docs/{Errors.md → Reference/Errors.md} +77 -47
- package/docs/{HTTP2.md → Reference/HTTP2.md} +13 -13
- package/docs/{Hooks.md → Reference/Hooks.md} +157 -70
- package/docs/Reference/Index.md +71 -0
- package/docs/{LTS.md → Reference/LTS.md} +31 -32
- package/docs/{Lifecycle.md → Reference/Lifecycle.md} +15 -7
- package/docs/{Logging.md → Reference/Logging.md} +68 -28
- package/docs/Reference/Middleware.md +78 -0
- package/docs/{Plugins.md → Reference/Plugins.md} +91 -34
- package/docs/{Reply.md → Reference/Reply.md} +205 -94
- package/docs/{Request.md → Reference/Request.md} +32 -16
- package/docs/{Routes.md → Reference/Routes.md} +243 -113
- package/docs/{Server.md → Reference/Server.md} +516 -267
- package/docs/{TypeScript.md → Reference/TypeScript.md} +451 -191
- package/docs/{Validation-and-Serialization.md → Reference/Validation-and-Serialization.md} +178 -86
- package/docs/index.md +24 -0
- package/examples/typescript-server.ts +1 -1
- package/fastify.js +2 -3
- package/lib/contentTypeParser.js +11 -6
- package/lib/decorate.js +6 -3
- package/lib/logger.js +1 -1
- package/lib/route.js +1 -1
- package/lib/server.js +9 -8
- package/package.json +9 -4
- package/test/als.test.js +74 -0
- package/test/constrained-routes.test.js +220 -0
- package/test/custom-parser.test.js +11 -2
- package/test/decorator.test.js +38 -0
- package/test/handler-context.test.js +11 -4
- package/test/http2/closing.test.js +14 -5
- package/test/http2/constraint.test.js +91 -0
- package/test/listen.test.js +36 -22
- package/test/logger.test.js +16 -0
- package/test/maxRequestsPerSocket.test.js +10 -0
- package/test/request-error.test.js +2 -8
- package/test/requestTimeout.test.js +4 -1
- package/test/router-options.test.js +10 -1
- package/test/schema-feature.test.js +146 -0
- package/test/stream.test.js +14 -3
- package/test/trust-proxy.test.js +15 -7
- package/test/types/instance.test-d.ts +52 -1
- package/test/types/request.test-d.ts +7 -1
- package/test/types/route.test-d.ts +21 -0
- package/types/hooks.d.ts +12 -1
- package/types/instance.d.ts +16 -6
- package/types/request.d.ts +4 -1
- package/types/route.d.ts +1 -1
- package/docs/Ecosystem.md +0 -211
- package/docs/Middleware.md +0 -53
- package/docs/Style-Guide.md +0 -185
- package/docs/Write-Plugin.md +0 -58
|
@@ -3,46 +3,77 @@
|
|
|
3
3
|
# The hitchhiker's guide to plugins
|
|
4
4
|
First of all, `DON'T PANIC`!
|
|
5
5
|
|
|
6
|
-
Fastify was built from the beginning to be an extremely modular system. We built
|
|
6
|
+
Fastify was built from the beginning to be an extremely modular system. We built
|
|
7
|
+
a powerful API that allows you to add methods and utilities to Fastify by
|
|
8
|
+
creating a namespace. We built a system that creates an encapsulation model,
|
|
9
|
+
which allows you to split your application into multiple microservices at any
|
|
10
|
+
moment, without the need to refactor the entire application.
|
|
7
11
|
|
|
8
12
|
**Table of contents**
|
|
9
|
-
- [
|
|
10
|
-
- [
|
|
11
|
-
- [
|
|
12
|
-
- [
|
|
13
|
-
- [
|
|
14
|
-
|
|
15
|
-
- [
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
- [The hitchhiker's guide to plugins](#the-hitchhikers-guide-to-plugins)
|
|
14
|
+
- [Register](#register)
|
|
15
|
+
- [Decorators](#decorators)
|
|
16
|
+
- [Hooks](#hooks)
|
|
17
|
+
- [How to handle encapsulation and
|
|
18
|
+
distribution](#how-to-handle-encapsulation-and-distribution)
|
|
19
|
+
- [ESM support](#esm-support)
|
|
20
|
+
- [Handle errors](#handle-errors)
|
|
21
|
+
- [Custom errors](#custom-errors)
|
|
22
|
+
- [Emit Warnings](#emit-warnings)
|
|
23
|
+
- [Let's start!](#lets-start)
|
|
24
|
+
|
|
20
25
|
## Register
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
<a id="register"></a>
|
|
27
|
+
|
|
28
|
+
As with JavaScript, where everything is an object, in Fastify everything is a
|
|
29
|
+
plugin.
|
|
30
|
+
|
|
31
|
+
Your routes, your utilities, and so on are all plugins. To add a new plugin,
|
|
32
|
+
whatever its functionality may be, in Fastify you have a nice and unique API:
|
|
33
|
+
[`register`](../Reference/Plugins.md).
|
|
23
34
|
```js
|
|
24
35
|
fastify.register(
|
|
25
36
|
require('./my-plugin'),
|
|
26
37
|
{ options }
|
|
27
38
|
)
|
|
28
39
|
```
|
|
29
|
-
`register` creates a new Fastify context, which means that if you perform any
|
|
40
|
+
`register` creates a new Fastify context, which means that if you perform any
|
|
41
|
+
changes on the Fastify instance, those changes will not be reflected in the
|
|
42
|
+
context's ancestors. In other words, encapsulation!
|
|
43
|
+
|
|
44
|
+
*Why is encapsulation important?*
|
|
45
|
+
|
|
46
|
+
Well, let's say you are creating a new disruptive startup, what do you do? You
|
|
47
|
+
create an API server with all your stuff, everything in the same place, a
|
|
48
|
+
monolith!
|
|
49
|
+
|
|
50
|
+
Ok, you are growing very fast and you want to change your architecture and try
|
|
51
|
+
microservices. Usually, this implies a huge amount of work, because of cross
|
|
52
|
+
dependencies and a lack of separation of concerns in the codebase.
|
|
53
|
+
|
|
54
|
+
Fastify helps you in that regard. Thanks to the encapsulation model, it will
|
|
55
|
+
completely avoid cross dependencies and will help you structure your code into
|
|
56
|
+
cohesive blocks.
|
|
30
57
|
|
|
31
|
-
*
|
|
32
|
-
Well, let's say you are creating a new disruptive startup, what do you do? You create an API server with all your stuff, everything in the same place, a monolith!<br>
|
|
33
|
-
Ok, you are growing very fast and you want to change your architecture and try microservices. Usually, this implies a huge amount of work, because of cross dependencies and a lack of separation of concerns in the codebase.<br>
|
|
34
|
-
Fastify helps you in that regard. Thanks to the encapsulation model, it will completely avoid cross dependencies and will help you structure your code into cohesive blocks.
|
|
58
|
+
*Let's return to how to correctly use `register`.*
|
|
35
59
|
|
|
36
|
-
|
|
37
|
-
|
|
60
|
+
As you probably know, the required plugins must expose a single function with
|
|
61
|
+
the following signature
|
|
38
62
|
```js
|
|
39
63
|
module.exports = function (fastify, options, done) {}
|
|
40
64
|
```
|
|
41
|
-
Where `fastify` is the encapsulated Fastify instance, `options` is the options
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
65
|
+
Where `fastify` is the encapsulated Fastify instance, `options` is the options
|
|
66
|
+
object, and `done` is the function you **must** call when your plugin is ready.
|
|
67
|
+
|
|
68
|
+
Fastify's plugin model is fully reentrant and graph-based, it handles
|
|
69
|
+
asynchronous code without any problems and it enforces both the load and close
|
|
70
|
+
order of plugins. *How?* Glad you asked, check out
|
|
71
|
+
[`avvio`](https://github.com/mcollina/avvio)! Fastify starts loading the plugin
|
|
72
|
+
__after__ `.listen()`, `.inject()` or `.ready()` are called.
|
|
73
|
+
|
|
74
|
+
Inside a plugin you can do whatever you want, register routes, utilities (we
|
|
75
|
+
will see this in a moment) and do nested registers, just remember to call `done`
|
|
76
|
+
when everything is set up!
|
|
46
77
|
```js
|
|
47
78
|
module.exports = function (fastify, options, done) {
|
|
48
79
|
fastify.get('/plugin', (request, reply) => {
|
|
@@ -53,11 +84,16 @@ module.exports = function (fastify, options, done) {
|
|
|
53
84
|
}
|
|
54
85
|
```
|
|
55
86
|
|
|
56
|
-
Well, now you know how to use the `register` API and how it works, but how do we
|
|
87
|
+
Well, now you know how to use the `register` API and how it works, but how do we
|
|
88
|
+
add new functionality to Fastify and even better, share them with other
|
|
89
|
+
developers?
|
|
57
90
|
|
|
58
|
-
<a name="decorators"></a>
|
|
59
91
|
## Decorators
|
|
60
|
-
|
|
92
|
+
<a id="decorators"></a>
|
|
93
|
+
|
|
94
|
+
Okay, let's say that you wrote a utility that is so good that you decided to
|
|
95
|
+
make it available along with all your code. How would you do it? Probably
|
|
96
|
+
something like the following:
|
|
61
97
|
```js
|
|
62
98
|
// your-awesome-utility.js
|
|
63
99
|
module.exports = function (a, b) {
|
|
@@ -68,15 +104,21 @@ module.exports = function (a, b) {
|
|
|
68
104
|
const util = require('./your-awesome-utility')
|
|
69
105
|
console.log(util('that is ', 'awesome'))
|
|
70
106
|
```
|
|
71
|
-
Now you will import your utility in every file you need it in. (And do not
|
|
107
|
+
Now you will import your utility in every file you need it in. (And do not
|
|
108
|
+
forget that you will probably also need it in your tests).
|
|
72
109
|
|
|
73
110
|
Fastify offers you a more elegant and comfortable way to do this, *decorators*.
|
|
74
|
-
Creating a decorator is extremely easy, just use the
|
|
111
|
+
Creating a decorator is extremely easy, just use the
|
|
112
|
+
[`decorate`](../Reference/Decorators.md) API:
|
|
75
113
|
```js
|
|
76
114
|
fastify.decorate('util', (a, b) => a + b)
|
|
77
115
|
```
|
|
78
|
-
Now you can access your utility just by calling `fastify.util` whenever you need
|
|
79
|
-
|
|
116
|
+
Now you can access your utility just by calling `fastify.util` whenever you need
|
|
117
|
+
it - even inside your test.
|
|
118
|
+
|
|
119
|
+
And here starts the magic; do you remember how just now we were talking about
|
|
120
|
+
encapsulation? Well, using `register` and `decorate` in conjunction enable
|
|
121
|
+
exactly that, let me show you an example to clarify this:
|
|
80
122
|
```js
|
|
81
123
|
fastify.register((instance, opts, done) => {
|
|
82
124
|
instance.decorate('util', (a, b) => a + b)
|
|
@@ -91,10 +133,15 @@ fastify.register((instance, opts, done) => {
|
|
|
91
133
|
done()
|
|
92
134
|
})
|
|
93
135
|
```
|
|
94
|
-
Inside the second register call `instance.util` will throw an error because
|
|
95
|
-
|
|
136
|
+
Inside the second register call `instance.util` will throw an error because
|
|
137
|
+
`util` exists only inside the first register context.
|
|
138
|
+
|
|
139
|
+
Let's step back for a moment and dig deeper into this: every time you use the
|
|
140
|
+
`register` API, a new context is created which avoids the negative situations
|
|
141
|
+
mentioned above.
|
|
96
142
|
|
|
97
|
-
Do note that encapsulation applies to the ancestors and siblings, but not the
|
|
143
|
+
Do note that encapsulation applies to the ancestors and siblings, but not the
|
|
144
|
+
children.
|
|
98
145
|
```js
|
|
99
146
|
fastify.register((instance, opts, done) => {
|
|
100
147
|
instance.decorate('util', (a, b) => a + b)
|
|
@@ -114,12 +161,19 @@ fastify.register((instance, opts, done) => {
|
|
|
114
161
|
done()
|
|
115
162
|
})
|
|
116
163
|
```
|
|
117
|
-
*Take home message: if you need a utility that is available in every part of
|
|
164
|
+
*Take home message: if you need a utility that is available in every part of
|
|
165
|
+
your application, take care that it is declared in the root scope of your
|
|
166
|
+
application. If that is not an option, you can use the `fastify-plugin` utility
|
|
167
|
+
as described [here](#distribution).*
|
|
168
|
+
|
|
169
|
+
`decorate` is not the only API that you can use to extend the server
|
|
170
|
+
functionality, you can also use `decorateRequest` and `decorateReply`.
|
|
118
171
|
|
|
119
|
-
`
|
|
172
|
+
*`decorateRequest` and `decorateReply`? Why do we need them if we already have
|
|
173
|
+
`decorate`?*
|
|
120
174
|
|
|
121
|
-
|
|
122
|
-
|
|
175
|
+
Good question, we added them to make Fastify more developer-friendly. Let's see
|
|
176
|
+
an example:
|
|
123
177
|
```js
|
|
124
178
|
fastify.decorate('html', payload => {
|
|
125
179
|
return generateHtml(payload)
|
|
@@ -176,11 +230,16 @@ fastify.get('/happiness', (request, reply) => {
|
|
|
176
230
|
})
|
|
177
231
|
```
|
|
178
232
|
|
|
179
|
-
We have seen how to extend server functionality and how to handle the
|
|
233
|
+
We have seen how to extend server functionality and how to handle the
|
|
234
|
+
encapsulation system, but what if you need to add a function that must be
|
|
235
|
+
executed every time when the server "[emits](../Reference/Lifecycle.md)" an
|
|
236
|
+
event?
|
|
180
237
|
|
|
181
|
-
<a name="hooks"></a>
|
|
182
238
|
## Hooks
|
|
183
|
-
|
|
239
|
+
<a id="hooks"></a>
|
|
240
|
+
|
|
241
|
+
You just built an amazing utility, but now you need to execute that for every
|
|
242
|
+
request, this is what you will likely do:
|
|
184
243
|
```js
|
|
185
244
|
fastify.decorate('util', (request, key, value) => { request[key] = value })
|
|
186
245
|
|
|
@@ -194,9 +253,12 @@ fastify.get('/plugin2', (request, reply) => {
|
|
|
194
253
|
reply.send(request)
|
|
195
254
|
})
|
|
196
255
|
```
|
|
197
|
-
I think we all agree that this is terrible. Repeated code, awful readability and
|
|
256
|
+
I think we all agree that this is terrible. Repeated code, awful readability and
|
|
257
|
+
it cannot scale.
|
|
258
|
+
|
|
259
|
+
So what can you do to avoid this annoying issue? Yes, you are right, use a
|
|
260
|
+
[hook](../Reference/Hooks.md)!
|
|
198
261
|
|
|
199
|
-
So what can you do to avoid this annoying issue? Yes, you are right, use a [hook](Hooks.md)!<br>
|
|
200
262
|
```js
|
|
201
263
|
fastify.decorate('util', (request, key, value) => { request[key] = value })
|
|
202
264
|
|
|
@@ -213,8 +275,11 @@ fastify.get('/plugin2', (request, reply) => {
|
|
|
213
275
|
reply.send(request)
|
|
214
276
|
})
|
|
215
277
|
```
|
|
216
|
-
Now for every request, you will run your utility. You can register as many hooks
|
|
217
|
-
|
|
278
|
+
Now for every request, you will run your utility. You can register as many hooks
|
|
279
|
+
as you need.
|
|
280
|
+
|
|
281
|
+
Sometimes you want a hook that should be executed for just a subset of routes,
|
|
282
|
+
how can you do that? Yep, encapsulation!
|
|
218
283
|
|
|
219
284
|
```js
|
|
220
285
|
fastify.register((instance, opts, done) => {
|
|
@@ -238,16 +303,28 @@ fastify.get('/plugin2', (request, reply) => {
|
|
|
238
303
|
```
|
|
239
304
|
Now your hook will run just for the first route!
|
|
240
305
|
|
|
241
|
-
As you probably noticed by now, `request` and `reply` are not the standard
|
|
306
|
+
As you probably noticed by now, `request` and `reply` are not the standard
|
|
307
|
+
Nodejs *request* and *response* objects, but Fastify's objects.
|
|
308
|
+
|
|
242
309
|
|
|
243
|
-
<a name="distribution"></a>
|
|
244
310
|
## How to handle encapsulation and distribution
|
|
245
|
-
|
|
311
|
+
<a id="distribution"></a>
|
|
246
312
|
|
|
247
|
-
|
|
313
|
+
Perfect, now you know (almost) all of the tools that you can use to extend
|
|
314
|
+
Fastify. Nevertheless, chances are that you came across one big issue: how is
|
|
315
|
+
distribution handled?
|
|
248
316
|
|
|
249
|
-
|
|
250
|
-
|
|
317
|
+
The preferred way to distribute a utility is to wrap all your code inside a
|
|
318
|
+
`register`. Using this, your plugin can support asynchronous bootstrapping
|
|
319
|
+
*(since `decorate` is a synchronous API)*, in the case of a database connection
|
|
320
|
+
for example.
|
|
321
|
+
|
|
322
|
+
*Wait, what? Didn't you tell me that `register` creates an encapsulation and
|
|
323
|
+
that the stuff I create inside will not be available outside?*
|
|
324
|
+
|
|
325
|
+
Yes, I said that. However, what I didn't tell you is that you can tell Fastify
|
|
326
|
+
to avoid this behavior with the
|
|
327
|
+
[`fastify-plugin`](https://github.com/fastify/fastify-plugin) module.
|
|
251
328
|
```js
|
|
252
329
|
const fp = require('fastify-plugin')
|
|
253
330
|
const dbClient = require('db-client')
|
|
@@ -261,11 +338,19 @@ function dbPlugin (fastify, opts, done) {
|
|
|
261
338
|
|
|
262
339
|
module.exports = fp(dbPlugin)
|
|
263
340
|
```
|
|
264
|
-
You can also tell `fastify-plugin` to check the installed version of Fastify, in
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
341
|
+
You can also tell `fastify-plugin` to check the installed version of Fastify, in
|
|
342
|
+
case you need a specific API.
|
|
343
|
+
|
|
344
|
+
As we mentioned earlier, Fastify starts loading its plugins __after__
|
|
345
|
+
`.listen()`, `.inject()` or `.ready()` are called and as such, __after__ they
|
|
346
|
+
have been declared. This means that, even though the plugin may inject variables
|
|
347
|
+
to the external Fastify instance via [`decorate`](../Reference/Decorators.md),
|
|
348
|
+
the decorated variables will not be accessible before calling `.listen()`,
|
|
349
|
+
`.inject()` or `.ready()`.
|
|
350
|
+
|
|
351
|
+
In case you rely on a variable injected by a preceding plugin and want to pass
|
|
352
|
+
that in the `options` argument of `register`, you can do so by using a function
|
|
353
|
+
instead of an object:
|
|
269
354
|
```js
|
|
270
355
|
const fastify = require('fastify')()
|
|
271
356
|
const fp = require('fastify-plugin')
|
|
@@ -283,12 +368,17 @@ fastify.register(require('your-plugin'), parent => {
|
|
|
283
368
|
return { connection: parent.db, otherOption: 'foo-bar' }
|
|
284
369
|
})
|
|
285
370
|
```
|
|
286
|
-
In the above example, the `parent` variable of the function passed in as the
|
|
371
|
+
In the above example, the `parent` variable of the function passed in as the
|
|
372
|
+
second argument of `register` is a copy of the **external Fastify instance**
|
|
373
|
+
that the plugin was registered at. This means that we are able to access any
|
|
374
|
+
variables that were injected by preceding plugins in the order of declaration.
|
|
287
375
|
|
|
288
|
-
<a name="esm-support"></a>
|
|
289
376
|
## ESM support
|
|
377
|
+
<a id="esm-support"></a>
|
|
290
378
|
|
|
291
|
-
ESM is supported as well from [Node.js
|
|
379
|
+
ESM is supported as well from [Node.js
|
|
380
|
+
`v13.3.0`](https://nodejs.org/api/esm.html) and above! Just export your plugin
|
|
381
|
+
as ESM module and you are good to go!
|
|
292
382
|
|
|
293
383
|
```js
|
|
294
384
|
// plugin.mjs
|
|
@@ -300,7 +390,8 @@ async function plugin (fastify, opts) {
|
|
|
300
390
|
|
|
301
391
|
export default plugin
|
|
302
392
|
```
|
|
303
|
-
__Note__: Fastify does not support named imports within an ESM context. Instead,
|
|
393
|
+
__Note__: Fastify does not support named imports within an ESM context. Instead,
|
|
394
|
+
the `default` export is available.
|
|
304
395
|
|
|
305
396
|
```js
|
|
306
397
|
// server.mjs
|
|
@@ -318,16 +409,27 @@ fastify.listen(3000, (err, address) => {
|
|
|
318
409
|
})
|
|
319
410
|
```
|
|
320
411
|
|
|
321
|
-
<a name="handle-errors"></a>
|
|
322
412
|
## Handle errors
|
|
323
|
-
|
|
324
|
-
|
|
413
|
+
<a id="handle-errors"></a>
|
|
414
|
+
|
|
415
|
+
It can happen that one of your plugins fails during startup. Maybe you expect it
|
|
416
|
+
and you have a custom logic that will be triggered in that case. How can you
|
|
417
|
+
implement this? The `after` API is what you need. `after` simply registers a
|
|
418
|
+
callback that will be executed just after a register, and it can take up to
|
|
419
|
+
three parameters.
|
|
420
|
+
|
|
325
421
|
The callback changes based on the parameters you are giving:
|
|
326
422
|
|
|
327
|
-
1. If no parameter is given to the callback and there is an error, that error
|
|
328
|
-
|
|
329
|
-
1. If
|
|
330
|
-
|
|
423
|
+
1. If no parameter is given to the callback and there is an error, that error
|
|
424
|
+
will be passed to the next error handler.
|
|
425
|
+
1. If one parameter is given to the callback, that parameter will be the error
|
|
426
|
+
object.
|
|
427
|
+
1. If two parameters are given to the callback, the first will be the error
|
|
428
|
+
object; the second will be the done callback.
|
|
429
|
+
1. If three parameters are given to the callback, the first will be the error
|
|
430
|
+
object, the second will be the top-level context unless you have specified
|
|
431
|
+
both server and override, in that case, the context will be what the override
|
|
432
|
+
returns, and the third the done callback.
|
|
331
433
|
|
|
332
434
|
Let's see how to use it:
|
|
333
435
|
```js
|
|
@@ -338,9 +440,12 @@ fastify
|
|
|
338
440
|
})
|
|
339
441
|
```
|
|
340
442
|
|
|
341
|
-
<a name="custom-errors"></a>
|
|
342
443
|
## Custom errors
|
|
343
|
-
|
|
444
|
+
<a id="custom-errors"></a>
|
|
445
|
+
|
|
446
|
+
If your plugin needs to expose custom errors, you can easily generate consistent
|
|
447
|
+
error objects across your codebase and plugins with the
|
|
448
|
+
[`fastify-error`](https://github.com/fastify/fastify-error) module.
|
|
344
449
|
|
|
345
450
|
```js
|
|
346
451
|
const createError = require('fastify-error')
|
|
@@ -348,9 +453,12 @@ const CustomError = createError('ERROR_CODE', 'message')
|
|
|
348
453
|
console.log(new CustomError())
|
|
349
454
|
```
|
|
350
455
|
|
|
351
|
-
<a name="emit-warnings"></a>
|
|
352
456
|
## Emit Warnings
|
|
353
|
-
|
|
457
|
+
<a id="emit-warnings"></a>
|
|
458
|
+
|
|
459
|
+
If you want to deprecate an API, or you want to warn the user about a specific
|
|
460
|
+
use case, you can use the
|
|
461
|
+
[`fastify-warning`](https://github.com/fastify/fastify-warning) module.
|
|
354
462
|
|
|
355
463
|
```js
|
|
356
464
|
const warning = require('fastify-warning')()
|
|
@@ -358,18 +466,24 @@ warning.create('FastifyDeprecation', 'FST_ERROR_CODE', 'message')
|
|
|
358
466
|
warning.emit('FST_ERROR_CODE')
|
|
359
467
|
```
|
|
360
468
|
|
|
361
|
-
<a name="start"></a>
|
|
362
469
|
## Let's start!
|
|
363
|
-
|
|
470
|
+
<a id="start"></a>
|
|
471
|
+
|
|
472
|
+
Awesome, now you know everything you need to know about Fastify and its plugin
|
|
473
|
+
system to start building your first plugin, and please if you do, tell us! We
|
|
474
|
+
will add it to the [*ecosystem*](https://github.com/fastify/fastify#ecosystem)
|
|
475
|
+
section of our documentation!
|
|
364
476
|
|
|
365
477
|
If you want to see some real-world examples, check out:
|
|
366
|
-
- [`point-of-view`](https://github.com/fastify/point-of-view)
|
|
367
|
-
|
|
368
|
-
- [`fastify-mongodb`](https://github.com/fastify/fastify-mongodb)
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
478
|
+
- [`point-of-view`](https://github.com/fastify/point-of-view) Templates
|
|
479
|
+
rendering (*ejs, pug, handlebars, marko*) plugin support for Fastify.
|
|
480
|
+
- [`fastify-mongodb`](https://github.com/fastify/fastify-mongodb) Fastify
|
|
481
|
+
MongoDB connection plugin, with this you can share the same MongoDB connection
|
|
482
|
+
pool in every part of your server.
|
|
483
|
+
- [`fastify-multipart`](https://github.com/fastify/fastify-multipart) Multipart
|
|
484
|
+
support for Fastify
|
|
485
|
+
- [`fastify-helmet`](https://github.com/fastify/fastify-helmet) Important
|
|
486
|
+
security headers for Fastify
|
|
373
487
|
|
|
374
488
|
|
|
375
489
|
*Do you feel like something is missing here? Let us know! :)*
|
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
This document contains a set of recommendations when using Fastify.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
- [Use A Reverse Proxy](#use-a-reverse-proxy)
|
|
8
|
+
- [HAProxy](#haproxy)
|
|
9
|
+
- [Nginx](#nginx)
|
|
10
|
+
- [Kubernetes](#kubernetes)
|
|
9
11
|
|
|
10
12
|
## Use A Reverse Proxy
|
|
11
13
|
<a id="reverseproxy"></a>
|
|
@@ -14,11 +16,11 @@ Node.js is an early adopter of frameworks shipping with an easy-to-use web
|
|
|
14
16
|
server within the standard library. Previously, with languages like PHP or
|
|
15
17
|
Python, one would need either a web server with specific support for the
|
|
16
18
|
language or the ability to set up some sort of [CGI gateway][cgi] that works
|
|
17
|
-
with the language. With Node.js, one can write an application that
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
with the language. With Node.js, one can write an application that _directly_
|
|
20
|
+
handles HTTP requests. As a result, the temptation is to write applications that
|
|
21
|
+
handle requests for multiple domains, listen on multiple ports (i.e. HTTP _and_
|
|
22
|
+
HTTPS), and then expose these applications directly to the Internet to handle
|
|
23
|
+
requests.
|
|
22
24
|
|
|
23
25
|
The Fastify team **strongly** considers this to be an anti-pattern and extremely
|
|
24
26
|
bad practice:
|
|
@@ -178,7 +180,7 @@ upstream fastify_app {
|
|
|
178
180
|
}
|
|
179
181
|
|
|
180
182
|
# This server block asks NGINX to respond with a redirect when
|
|
181
|
-
# an incoming request from port 80 (typically plain HTTP), to
|
|
183
|
+
# an incoming request from port 80 (typically plain HTTP), to
|
|
182
184
|
# the same request URL but with HTTPS as protocol.
|
|
183
185
|
# This block is optional, and usually used if you are handling
|
|
184
186
|
# SSL termination in NGINX, like in the example here.
|
|
@@ -188,7 +190,7 @@ server {
|
|
|
188
190
|
# which in this case is any address and port 80
|
|
189
191
|
listen 80 default_server;
|
|
190
192
|
listen [::]:80 default_server;
|
|
191
|
-
|
|
193
|
+
|
|
192
194
|
# With a server_name directive you can also ask NGINX to
|
|
193
195
|
# use this server block only with matching server name(s)
|
|
194
196
|
# listen 80;
|
|
@@ -279,7 +281,12 @@ server {
|
|
|
279
281
|
## Kubernetes
|
|
280
282
|
<a id="kubernetes"></a>
|
|
281
283
|
|
|
282
|
-
The `readinessProbe` uses [(by
|
|
284
|
+
The `readinessProbe` uses [(by
|
|
285
|
+
default](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes))
|
|
286
|
+
the pod IP as the hostname. Fastify listens on `127.0.0.1` by default. The probe
|
|
287
|
+
will not be able to reach the application in this case. In order to make it
|
|
288
|
+
work, the application must listen on `0.0.0.0` or specify a custom hostname in
|
|
289
|
+
the `readinessProbe.httpGet` spec, as per the following example:
|
|
283
290
|
|
|
284
291
|
```yaml
|
|
285
292
|
readinessProbe:
|