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
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
<h1 align="center">Fastify</h1>
|
|
2
|
+
|
|
3
|
+
# How to write a good plugin
|
|
4
|
+
First, thank you for deciding to write a plugin for Fastify. Fastify is a
|
|
5
|
+
minimal framework and plugins are its strength, so thank you.
|
|
6
|
+
|
|
7
|
+
The core principles of Fastify are performance, low overhead, and providing a
|
|
8
|
+
good experience to our users. When writing a plugin, it is important to keep
|
|
9
|
+
these principles in mind. Therefore, in this document, we will analyze what
|
|
10
|
+
characterizes a quality plugin.
|
|
11
|
+
|
|
12
|
+
*Need some inspiration? You can use the label ["plugin
|
|
13
|
+
suggestion"](https://github.com/fastify/fastify/issues?q=is%3Aissue+is%3Aopen+label%3A%22plugin+suggestion%22)
|
|
14
|
+
in our issue tracker!*
|
|
15
|
+
|
|
16
|
+
## Code
|
|
17
|
+
Fastify uses different techniques to optimize its code, many of them are
|
|
18
|
+
documented in our Guides. We highly recommend you read [the hitchhiker's guide
|
|
19
|
+
to plugins](./Plugins-Guide.md) to discover all the APIs you can use to build
|
|
20
|
+
your plugin and learn how to use them.
|
|
21
|
+
|
|
22
|
+
Do you have a question or need some advice? We are more than happy to help you!
|
|
23
|
+
Just open an issue in our [help repository](https://github.com/fastify/help).
|
|
24
|
+
|
|
25
|
+
Once you submit a plugin to our [ecosystem list](./Ecosystem.md), we will review
|
|
26
|
+
your code and help you improve it if necessary.
|
|
27
|
+
|
|
28
|
+
## Documentation
|
|
29
|
+
Documentation is extremely important. If your plugin is not well documented we
|
|
30
|
+
will not accept it to the ecosystem list. Lack of quality documentation makes it
|
|
31
|
+
more difficult for people to use your plugin, and will likely result in it going
|
|
32
|
+
unused.
|
|
33
|
+
|
|
34
|
+
If you want to see some good examples on how to document a plugin take a look
|
|
35
|
+
at:
|
|
36
|
+
- [`fastify-caching`](https://github.com/fastify/fastify-caching)
|
|
37
|
+
- [`fastify-compress`](https://github.com/fastify/fastify-compress)
|
|
38
|
+
- [`fastify-cookie`](https://github.com/fastify/fastify-cookie)
|
|
39
|
+
- [`point-of-view`](https://github.com/fastify/point-of-view)
|
|
40
|
+
- [`under-pressure`](https://github.com/fastify/under-pressure)
|
|
41
|
+
|
|
42
|
+
## License
|
|
43
|
+
You can license your plugin as you prefer, we do not enforce any kind of
|
|
44
|
+
license.
|
|
45
|
+
|
|
46
|
+
We prefer the [MIT license](https://choosealicense.com/licenses/mit/) because we
|
|
47
|
+
think it allows more people to use the code freely. For a list of alternative
|
|
48
|
+
licenses see the [OSI list](https://opensource.org/licenses) or GitHub's
|
|
49
|
+
[choosealicense.com](https://choosealicense.com/).
|
|
50
|
+
|
|
51
|
+
## Examples
|
|
52
|
+
Always put an example file in your repository. Examples are very helpful for
|
|
53
|
+
users and give a very fast way to test your plugin. Your users will be grateful.
|
|
54
|
+
|
|
55
|
+
## Test
|
|
56
|
+
It is extremely important that a plugin is thoroughly tested to verify that is
|
|
57
|
+
working properly.
|
|
58
|
+
|
|
59
|
+
A plugin without tests will not be accepted to the ecosystem list. A lack of
|
|
60
|
+
tests does not inspire trust nor guarantee that the code will continue to work
|
|
61
|
+
among different versions of its dependencies.
|
|
62
|
+
|
|
63
|
+
We do not enforce any testing library. We use [`tap`](https://www.node-tap.org/)
|
|
64
|
+
since it offers out-of-the-box parallel testing and code coverage, but it is up
|
|
65
|
+
to you to choose your library of preference.
|
|
66
|
+
|
|
67
|
+
## Code Linter
|
|
68
|
+
It is not mandatory, but we highly recommend you use a code linter in your
|
|
69
|
+
plugin. It will ensure a consistent code style and help you to avoid many
|
|
70
|
+
errors.
|
|
71
|
+
|
|
72
|
+
We use [`standard`](https://standardjs.com/) since it works without the need to
|
|
73
|
+
configure it and is very easy to integrate into a test suite.
|
|
74
|
+
|
|
75
|
+
## Continuous Integration
|
|
76
|
+
It is not mandatory, but if you release your code as open source, it helps to
|
|
77
|
+
use Continuous Integration to ensure contributions do not break your plugin and
|
|
78
|
+
to show that the plugin works as intended. Both
|
|
79
|
+
[CircleCI](https://circleci.com/) and [GitHub
|
|
80
|
+
Actions](https://github.com/features/actions) are free for open source projects
|
|
81
|
+
and easy to set up.
|
|
82
|
+
|
|
83
|
+
In addition, you can enable services like [Dependabot](https://dependabot.com/)
|
|
84
|
+
or [Snyk](https://snyk.io/), which will help you keep your dependencies up to
|
|
85
|
+
date and discover if a new release of Fastify has some issues with your plugin.
|
|
86
|
+
|
|
87
|
+
## Let's start!
|
|
88
|
+
Awesome, now you know everything you need to know about how to write a good
|
|
89
|
+
plugin for Fastify! After you have built one (or more!) let us know! We will add
|
|
90
|
+
it to the [ecosystem](https://github.com/fastify/fastify#ecosystem) section of
|
|
91
|
+
our documentation!
|
|
92
|
+
|
|
93
|
+
If you want to see some real world examples, check out:
|
|
94
|
+
- [`point-of-view`](https://github.com/fastify/point-of-view) Templates
|
|
95
|
+
rendering (*ejs, pug, handlebars, marko*) plugin support for Fastify.
|
|
96
|
+
- [`fastify-mongodb`](https://github.com/fastify/fastify-mongodb) Fastify
|
|
97
|
+
MongoDB connection plugin, with this you can share the same MongoDB connection
|
|
98
|
+
pool in every part of your server.
|
|
99
|
+
- [`fastify-multipart`](https://github.com/fastify/fastify-multipart) Multipart
|
|
100
|
+
support for Fastify.
|
|
101
|
+
- [`fastify-helmet`](https://github.com/fastify/fastify-helmet) Important
|
|
102
|
+
security headers for Fastify.
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
<h1 align="center">Fastify</h1>
|
|
2
2
|
|
|
3
3
|
## `Content-Type` Parser
|
|
4
|
-
Natively, Fastify only supports `'application/json'` and `'text/plain'` content
|
|
4
|
+
Natively, Fastify only supports `'application/json'` and `'text/plain'` content
|
|
5
|
+
types. The default charset is `utf-8`. If you need to support different content
|
|
6
|
+
types, you can use the `addContentTypeParser` API. *The default JSON and/or
|
|
7
|
+
plain text parser can be changed or removed.*
|
|
5
8
|
|
|
6
|
-
*Note: If you decide to specify your own content type with the `Content-Type`
|
|
9
|
+
*Note: If you decide to specify your own content type with the `Content-Type`
|
|
10
|
+
header, UTF-8 will not be the default. Be sure to include UTF-8 like this
|
|
11
|
+
`text/html; charset=utf-8`.*
|
|
7
12
|
|
|
8
|
-
As with the other APIs, `addContentTypeParser` is encapsulated in the scope in
|
|
13
|
+
As with the other APIs, `addContentTypeParser` is encapsulated in the scope in
|
|
14
|
+
which it is declared. This means that if you declare it in the root scope it
|
|
15
|
+
will be available everywhere, while if you declare it inside a plugin it will be
|
|
16
|
+
available only in that scope and its children.
|
|
9
17
|
|
|
10
|
-
Fastify automatically adds the parsed request payload to the [Fastify
|
|
18
|
+
Fastify automatically adds the parsed request payload to the [Fastify
|
|
19
|
+
request](./Request.md) object which you can access with `request.body`.
|
|
11
20
|
|
|
12
21
|
### Usage
|
|
13
22
|
```js
|
|
@@ -31,7 +40,7 @@ fastify.addContentTypeParser('application/jsoff', async function (request, paylo
|
|
|
31
40
|
return res
|
|
32
41
|
})
|
|
33
42
|
|
|
34
|
-
// Handle all content types that matches RegExp
|
|
43
|
+
// Handle all content types that matches RegExp
|
|
35
44
|
fastify.addContentTypeParser(/^image\/.*/, function (request, payload, done) {
|
|
36
45
|
imageParser(payload, function (err, body) {
|
|
37
46
|
done(err, body)
|
|
@@ -42,25 +51,31 @@ fastify.addContentTypeParser(/^image\/.*/, function (request, payload, done) {
|
|
|
42
51
|
fastify.addContentTypeParser('text/json', { parseAs: 'string' }, fastify.getDefaultJsonParser('ignore', 'ignore'))
|
|
43
52
|
```
|
|
44
53
|
|
|
45
|
-
Fastify first tries to match a content-type parser with a `string` value before
|
|
46
|
-
|
|
47
|
-
|
|
54
|
+
Fastify first tries to match a content-type parser with a `string` value before
|
|
55
|
+
trying to find a matching `RegExp`. If you provide overlapping content types,
|
|
56
|
+
Fastify tries to find a matching content type by starting with the last one
|
|
57
|
+
passed and ending with the first one. So if you want to specify a general
|
|
58
|
+
content type more precisely, first specify the general content type and then the
|
|
59
|
+
more specific one, like in the example below.
|
|
48
60
|
|
|
49
61
|
```js
|
|
50
62
|
// Here only the second content type parser is called because its value also matches the first one
|
|
51
63
|
fastify.addContentTypeParser('application/vnd.custom+xml', (request, body, done) => {} )
|
|
52
64
|
fastify.addContentTypeParser('application/vnd.custom', (request, body, done) => {} )
|
|
53
65
|
|
|
54
|
-
// Here the desired behavior is achieved because fastify first tries to match the `application/vnd.custom+xml` content type parser
|
|
66
|
+
// Here the desired behavior is achieved because fastify first tries to match the `application/vnd.custom+xml` content type parser
|
|
55
67
|
fastify.addContentTypeParser('application/vnd.custom', (request, body, done) => {} )
|
|
56
68
|
fastify.addContentTypeParser('application/vnd.custom+xml', (request, body, done) => {} )
|
|
57
69
|
```
|
|
58
70
|
|
|
59
|
-
Besides the `addContentTypeParser` API there are further APIs that can be used.
|
|
71
|
+
Besides the `addContentTypeParser` API there are further APIs that can be used.
|
|
72
|
+
These are `hasContentTypeParser`, `removeContentTypeParser` and
|
|
73
|
+
`removeAllContentTypeParsers`.
|
|
60
74
|
|
|
61
75
|
#### hasContentTypeParser
|
|
62
76
|
|
|
63
|
-
You can use the `hasContentTypeParser` API to find if a specific content type
|
|
77
|
+
You can use the `hasContentTypeParser` API to find if a specific content type
|
|
78
|
+
parser already exists.
|
|
64
79
|
|
|
65
80
|
```js
|
|
66
81
|
if (!fastify.hasContentTypeParser('application/jsoff')){
|
|
@@ -74,8 +89,8 @@ if (!fastify.hasContentTypeParser('application/jsoff')){
|
|
|
74
89
|
|
|
75
90
|
#### removeContentTypeParser
|
|
76
91
|
|
|
77
|
-
With `removeContentTypeParser` a single or an array of content types can be
|
|
78
|
-
`RegExp` content types.
|
|
92
|
+
With `removeContentTypeParser` a single or an array of content types can be
|
|
93
|
+
removed. The method supports `string` and `RegExp` content types.
|
|
79
94
|
|
|
80
95
|
```js
|
|
81
96
|
fastify.addContentTypeParser('text/xml', function (request, payload, done) {
|
|
@@ -90,11 +105,15 @@ fastify.removeContentTypeParser(['application/json', 'text/plain'])
|
|
|
90
105
|
|
|
91
106
|
#### removeAllContentTypeParsers
|
|
92
107
|
|
|
93
|
-
In the example from just above, it is noticeable that we need to specify each
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
108
|
+
In the example from just above, it is noticeable that we need to specify each
|
|
109
|
+
content type that we want to remove. To solve this problem Fastify provides the
|
|
110
|
+
`removeAllContentTypeParsers` API. This can be used to remove all currently
|
|
111
|
+
existing content type parsers. In the example below we achieve exactly the same
|
|
112
|
+
as in the example above except that we do not need to specify each content type
|
|
113
|
+
to delete. Just like `removeContentTypeParser`, this API supports encapsulation.
|
|
114
|
+
The API is especially useful if you want to register a [catch-all content type
|
|
115
|
+
parser](#catch-all) that should be executed for every content type and the
|
|
116
|
+
built-in parsers should be ignored as well.
|
|
98
117
|
|
|
99
118
|
```js
|
|
100
119
|
fastify.removeAllContentTypeParsers()
|
|
@@ -106,10 +125,18 @@ fastify.addContentTypeParser('text/xml', function (request, payload, done) {
|
|
|
106
125
|
})
|
|
107
126
|
```
|
|
108
127
|
|
|
109
|
-
**Notice**: The old syntaxes `function(req, done)` and `async function(req)` for
|
|
128
|
+
**Notice**: The old syntaxes `function(req, done)` and `async function(req)` for
|
|
129
|
+
the parser are still supported but they are deprecated.
|
|
110
130
|
|
|
111
131
|
#### Body Parser
|
|
112
|
-
You can parse the body of a request in two ways. The first one is shown above:
|
|
132
|
+
You can parse the body of a request in two ways. The first one is shown above:
|
|
133
|
+
you add a custom content type parser and handle the request stream. In the
|
|
134
|
+
second one, you should pass a `parseAs` option to the `addContentTypeParser`
|
|
135
|
+
API, where you declare how you want to get the body. It could be of type
|
|
136
|
+
`'string'` or `'buffer'`. If you use the `parseAs` option, Fastify will
|
|
137
|
+
internally handle the stream and perform some checks, such as the [maximum
|
|
138
|
+
size](./Server.md#factory-body-limit) of the body and the content length. If the
|
|
139
|
+
limit is exceeded the custom parser will not be invoked.
|
|
113
140
|
```js
|
|
114
141
|
fastify.addContentTypeParser('application/json', { parseAs: 'string' }, function (req, body, done) {
|
|
115
142
|
try {
|
|
@@ -122,14 +149,20 @@ fastify.addContentTypeParser('application/json', { parseAs: 'string' }, function
|
|
|
122
149
|
})
|
|
123
150
|
```
|
|
124
151
|
|
|
125
|
-
See
|
|
152
|
+
See
|
|
153
|
+
[`example/parser.js`](https://github.com/fastify/fastify/blob/main/examples/parser.js)
|
|
154
|
+
for an example.
|
|
126
155
|
|
|
127
156
|
##### Custom Parser Options
|
|
128
|
-
+ `parseAs` (string): Either `'string'` or `'buffer'` to designate how the
|
|
129
|
-
|
|
157
|
+
+ `parseAs` (string): Either `'string'` or `'buffer'` to designate how the
|
|
158
|
+
incoming data should be collected. Default: `'buffer'`.
|
|
159
|
+
+ `bodyLimit` (number): The maximum payload size, in bytes, that the custom
|
|
160
|
+
parser will accept. Defaults to the global body limit passed to the [`Fastify
|
|
161
|
+
factory function`](./Server.md#bodylimit).
|
|
130
162
|
|
|
131
163
|
#### Catch-All
|
|
132
|
-
There are some cases where you need to catch all requests regardless of their
|
|
164
|
+
There are some cases where you need to catch all requests regardless of their
|
|
165
|
+
content type. With Fastify, you can just use the `'*'` content type.
|
|
133
166
|
```js
|
|
134
167
|
fastify.addContentTypeParser('*', function (request, payload, done) {
|
|
135
168
|
var data = ''
|
|
@@ -140,9 +173,11 @@ fastify.addContentTypeParser('*', function (request, payload, done) {
|
|
|
140
173
|
})
|
|
141
174
|
```
|
|
142
175
|
|
|
143
|
-
Using this, all requests that do not have a corresponding content type parser
|
|
176
|
+
Using this, all requests that do not have a corresponding content type parser
|
|
177
|
+
will be handled by the specified function.
|
|
144
178
|
|
|
145
|
-
This is also useful for piping the request stream. You can define a content
|
|
179
|
+
This is also useful for piping the request stream. You can define a content
|
|
180
|
+
parser like:
|
|
146
181
|
|
|
147
182
|
```js
|
|
148
183
|
fastify.addContentTypeParser('*', function (request, payload, done) {
|
|
@@ -158,7 +193,8 @@ app.post('/hello', (request, reply) => {
|
|
|
158
193
|
})
|
|
159
194
|
```
|
|
160
195
|
|
|
161
|
-
Here is a complete example that logs incoming [json
|
|
196
|
+
Here is a complete example that logs incoming [json
|
|
197
|
+
line](https://jsonlines.org/) objects:
|
|
162
198
|
|
|
163
199
|
```js
|
|
164
200
|
const split2 = require('split2')
|
|
@@ -177,10 +213,12 @@ fastify.route({
|
|
|
177
213
|
})
|
|
178
214
|
```
|
|
179
215
|
|
|
180
|
-
For piping file uploads you may want to check out [this
|
|
216
|
+
For piping file uploads you may want to check out [this
|
|
217
|
+
plugin](https://github.com/fastify/fastify-multipart).
|
|
181
218
|
|
|
182
|
-
If you really want the content type parser to be executed on all content types
|
|
183
|
-
specific one, you should call the
|
|
219
|
+
If you really want the content type parser to be executed on all content types
|
|
220
|
+
and not only on those that don't have a specific one, you should call the
|
|
221
|
+
`removeAllContentTypeParsers` method first.
|
|
184
222
|
|
|
185
223
|
```js
|
|
186
224
|
// Without this call, the request body with the content type application/json would be processed by the built in json parser
|
|
@@ -2,20 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
## Decorators
|
|
4
4
|
|
|
5
|
-
The decorators API allows customization of the core Fastify objects, such as
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
This API is *synchronous*. Attempting to define a decoration
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
to optimize the handling of server, request, and reply objects. This is
|
|
5
|
+
The decorators API allows customization of the core Fastify objects, such as the
|
|
6
|
+
server instance itself and any request and reply objects used during the HTTP
|
|
7
|
+
request lifecycle. The decorators API can be used to attach any type of property
|
|
8
|
+
to the core objects, e.g. functions, plain objects, or native types.
|
|
9
|
+
|
|
10
|
+
This API is *synchronous*. Attempting to define a decoration asynchronously
|
|
11
|
+
could result in the Fastify instance booting before the decoration completes its
|
|
12
|
+
initialization. To avoid this issue, and register an asynchronous decoration,
|
|
13
|
+
the `register` API, in combination with `fastify-plugin`, must be used instead.
|
|
14
|
+
To learn more, see the [Plugins](./Plugins.md) documentation.
|
|
15
|
+
|
|
16
|
+
Decorating core objects with this API allows the underlying JavaScript engine to
|
|
17
|
+
optimize the handling of server, request, and reply objects. This is
|
|
19
18
|
accomplished by defining the shape of all such object instances before they are
|
|
20
19
|
instantiated and used. As an example, the following is not recommended because
|
|
21
20
|
it will change the shape of objects during their lifecycle:
|
|
@@ -36,8 +35,8 @@ fastify.get('/', function (req, reply) {
|
|
|
36
35
|
})
|
|
37
36
|
```
|
|
38
37
|
|
|
39
|
-
Since the above example mutates the request object after it has already
|
|
40
|
-
|
|
38
|
+
Since the above example mutates the request object after it has already been
|
|
39
|
+
instantiated, the JavaScript engine must deoptimize access to the request
|
|
41
40
|
object. By using the decoration API this deoptimization is avoided:
|
|
42
41
|
|
|
43
42
|
```js
|
|
@@ -55,22 +54,26 @@ fastify.get('/', (req, reply) => {
|
|
|
55
54
|
})
|
|
56
55
|
```
|
|
57
56
|
|
|
58
|
-
Note that it is important to keep the initial shape of a decorated field as
|
|
57
|
+
Note that it is important to keep the initial shape of a decorated field as
|
|
58
|
+
close as possible to the value intended to be set dynamically in the future.
|
|
59
|
+
Initialize a decorator as a `''` if the intended value is a string, and as
|
|
60
|
+
`null` if it will be an object or a function.
|
|
59
61
|
|
|
60
|
-
Remember this example works only with value types as reference types will be
|
|
61
|
-
See [decorateRequest](#decorate-request).
|
|
62
|
+
Remember this example works only with value types as reference types will be
|
|
63
|
+
shared amongst all requests. See [decorateRequest](#decorate-request).
|
|
62
64
|
|
|
63
|
-
See
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
See [JavaScript engine fundamentals: Shapes and Inline
|
|
66
|
+
Caches](https://mathiasbynens.be/notes/shapes-ics) for more information on this
|
|
67
|
+
topic.
|
|
66
68
|
|
|
67
69
|
### Usage
|
|
68
|
-
<a
|
|
70
|
+
<a id="usage"></a>
|
|
69
71
|
|
|
70
72
|
#### `decorate(name, value, [dependencies])`
|
|
71
|
-
<a
|
|
73
|
+
<a id="decorate"></a>
|
|
72
74
|
|
|
73
|
-
This method is used to customize the Fastify [server](Server.md)
|
|
75
|
+
This method is used to customize the Fastify [server](./Server.md)
|
|
76
|
+
instance.
|
|
74
77
|
|
|
75
78
|
For example, to attach a new method to the server instance:
|
|
76
79
|
|
|
@@ -89,8 +92,7 @@ fastify.decorate('conf', {
|
|
|
89
92
|
})
|
|
90
93
|
```
|
|
91
94
|
|
|
92
|
-
To access decorated properties, use the name provided to the
|
|
93
|
-
decoration API:
|
|
95
|
+
To access decorated properties, use the name provided to the decoration API:
|
|
94
96
|
|
|
95
97
|
```js
|
|
96
98
|
fastify.utility()
|
|
@@ -98,7 +100,8 @@ fastify.utility()
|
|
|
98
100
|
console.log(fastify.conf.db)
|
|
99
101
|
```
|
|
100
102
|
|
|
101
|
-
The decorated [Fastify server](Server.md) is bound to `this` in
|
|
103
|
+
The decorated [Fastify server](./Server.md) is bound to `this` in
|
|
104
|
+
route [route](./Routes.md) handlers:
|
|
102
105
|
|
|
103
106
|
```js
|
|
104
107
|
fastify.decorate('db', new DbConnection())
|
|
@@ -121,11 +124,11 @@ Note: using an arrow function will break the binding of `this` to the
|
|
|
121
124
|
`FastifyInstance`.
|
|
122
125
|
|
|
123
126
|
If a dependency is not satisfied, the `decorate` method will throw an exception.
|
|
124
|
-
The dependency check is performed before the server instance is booted. Thus,
|
|
125
|
-
|
|
127
|
+
The dependency check is performed before the server instance is booted. Thus, it
|
|
128
|
+
cannot occur during runtime.
|
|
126
129
|
|
|
127
130
|
#### `decorateReply(name, value, [dependencies])`
|
|
128
|
-
<a
|
|
131
|
+
<a id="decorate-reply"></a>
|
|
129
132
|
|
|
130
133
|
As the name suggests, this API is used to add new methods/properties to the core
|
|
131
134
|
`Reply` object:
|
|
@@ -145,10 +148,11 @@ Note: using `decorateReply` will emit a warning if used with a reference type:
|
|
|
145
148
|
// Don't do this
|
|
146
149
|
fastify.decorateReply('foo', { bar: 'fizz'})
|
|
147
150
|
```
|
|
148
|
-
In this example, the reference of the object is shared with all the requests:
|
|
149
|
-
mutation will impact all requests, potentially creating security
|
|
150
|
-
To achieve proper encapsulation across
|
|
151
|
-
in the [`'onRequest'`
|
|
151
|
+
In this example, the reference of the object is shared with all the requests:
|
|
152
|
+
**any mutation will impact all requests, potentially creating security
|
|
153
|
+
vulnerabilities or memory leaks**. To achieve proper encapsulation across
|
|
154
|
+
requests configure a new value for each incoming request in the [`'onRequest'`
|
|
155
|
+
hook](./Hooks.md#onrequest). Example:
|
|
152
156
|
|
|
153
157
|
```js
|
|
154
158
|
const fp = require('fastify-plugin')
|
|
@@ -157,7 +161,7 @@ async function myPlugin (app) {
|
|
|
157
161
|
app.decorateRequest('foo', null)
|
|
158
162
|
app.addHook('onRequest', async (req, reply) => {
|
|
159
163
|
req.foo = { bar: 42 }
|
|
160
|
-
})
|
|
164
|
+
})
|
|
161
165
|
}
|
|
162
166
|
|
|
163
167
|
module.exports = fp(myPlugin)
|
|
@@ -166,7 +170,7 @@ module.exports = fp(myPlugin)
|
|
|
166
170
|
See [`decorate`](#decorate) for information about the `dependencies` parameter.
|
|
167
171
|
|
|
168
172
|
#### `decorateRequest(name, value, [dependencies])`
|
|
169
|
-
<a
|
|
173
|
+
<a id="decorate-request"></a>
|
|
170
174
|
|
|
171
175
|
As above with [`decorateReply`](#decorate-reply), this API is used add new
|
|
172
176
|
methods/properties to the core `Request` object:
|
|
@@ -186,11 +190,12 @@ Note: using `decorateRequest` will emit a warning if used with a reference type:
|
|
|
186
190
|
// Don't do this
|
|
187
191
|
fastify.decorateRequest('foo', { bar: 'fizz'})
|
|
188
192
|
```
|
|
189
|
-
In this example, the reference of the object is shared with all the requests:
|
|
190
|
-
mutation will impact all requests, potentially creating security
|
|
193
|
+
In this example, the reference of the object is shared with all the requests:
|
|
194
|
+
**any mutation will impact all requests, potentially creating security
|
|
195
|
+
vulnerabilities or memory leaks**.
|
|
191
196
|
|
|
192
|
-
To achieve proper encapsulation across requests configure a new value for each
|
|
193
|
-
in the [`'onRequest'` hook](Hooks.md#onrequest). Example:
|
|
197
|
+
To achieve proper encapsulation across requests configure a new value for each
|
|
198
|
+
incoming request in the [`'onRequest'` hook](./Hooks.md#onrequest). Example:
|
|
194
199
|
|
|
195
200
|
```js
|
|
196
201
|
const fp = require('fastify-plugin')
|
|
@@ -199,7 +204,7 @@ async function myPlugin (app) {
|
|
|
199
204
|
app.decorateRequest('foo', null)
|
|
200
205
|
app.addHook('onRequest', async (req, reply) => {
|
|
201
206
|
req.foo = { bar: 42 }
|
|
202
|
-
})
|
|
207
|
+
})
|
|
203
208
|
}
|
|
204
209
|
|
|
205
210
|
module.exports = fp(myPlugin)
|
|
@@ -208,7 +213,7 @@ module.exports = fp(myPlugin)
|
|
|
208
213
|
See [`decorate`](#decorate) for information about the `dependencies` parameter.
|
|
209
214
|
|
|
210
215
|
#### `hasDecorator(name)`
|
|
211
|
-
<a
|
|
216
|
+
<a id="has-decorator"></a>
|
|
212
217
|
|
|
213
218
|
Used to check for the existence of a server instance decoration:
|
|
214
219
|
|
|
@@ -217,7 +222,7 @@ fastify.hasDecorator('utility')
|
|
|
217
222
|
```
|
|
218
223
|
|
|
219
224
|
#### hasRequestDecorator
|
|
220
|
-
<a
|
|
225
|
+
<a id="has-request-decorator"></a>
|
|
221
226
|
|
|
222
227
|
Used to check for the existence of a Request decoration:
|
|
223
228
|
|
|
@@ -226,7 +231,7 @@ fastify.hasRequestDecorator('utility')
|
|
|
226
231
|
```
|
|
227
232
|
|
|
228
233
|
#### hasReplyDecorator
|
|
229
|
-
<a
|
|
234
|
+
<a id="has-reply-decorator"></a>
|
|
230
235
|
|
|
231
236
|
Used to check for the existence of a Reply decoration:
|
|
232
237
|
|
|
@@ -235,7 +240,7 @@ fastify.hasReplyDecorator('utility')
|
|
|
235
240
|
```
|
|
236
241
|
|
|
237
242
|
### Decorators and Encapsulation
|
|
238
|
-
<a
|
|
243
|
+
<a id="decorators-encapsulation"></a>
|
|
239
244
|
|
|
240
245
|
Defining a decorator (using `decorate`, `decorateRequest`, or `decorateReply`)
|
|
241
246
|
with the same name more than once in the same **encapsulated** context will
|
|
@@ -290,7 +295,7 @@ server.listen(3000)
|
|
|
290
295
|
```
|
|
291
296
|
|
|
292
297
|
### Getters and Setters
|
|
293
|
-
<a
|
|
298
|
+
<a id="getters-setters"></a>
|
|
294
299
|
|
|
295
300
|
Decorators accept special "getter/setter" objects. These objects have functions
|
|
296
301
|
named `getter` and `setter` (though the `setter` function is optional). This
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<h1 align="center">Fastify</h1>
|
|
2
2
|
|
|
3
|
-
<a id="encapsulation"></a>
|
|
4
3
|
## Encapsulation
|
|
4
|
+
<a id="encapsulation"></a>
|
|
5
5
|
|
|
6
6
|
A fundamental feature of Fastify is the "encapsulation context." The
|
|
7
7
|
encapsulation context governs which [decorators](./Decorators.md), registered
|
|
@@ -9,7 +9,7 @@ encapsulation context governs which [decorators](./Decorators.md), registered
|
|
|
9
9
|
[routes](./Routes.md). A visual representation of the encapsulation context
|
|
10
10
|
is shown in the following figure:
|
|
11
11
|
|
|
12
|
-

|
|
13
13
|
|
|
14
14
|
In the above figure, there are several entities:
|
|
15
15
|
|
|
@@ -122,8 +122,8 @@ To see this, start the server and issue requests:
|
|
|
122
122
|
|
|
123
123
|
[bearer]: https://github.com/fastify/fastify-bearer-auth
|
|
124
124
|
|
|
125
|
-
<a id="shared-context"></a>
|
|
126
125
|
## Sharing Between Contexts
|
|
126
|
+
<a id="shared-context"></a>
|
|
127
127
|
|
|
128
128
|
Notice that each context in the prior example inherits _only_ from the parent
|
|
129
129
|
contexts. Parent contexts cannot access any entities within their descendent
|