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
|
@@ -2,80 +2,127 @@
|
|
|
2
2
|
|
|
3
3
|
## Routes
|
|
4
4
|
|
|
5
|
-
The routes methods will configure the endpoints of your application.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- [
|
|
10
|
-
- [
|
|
11
|
-
- [
|
|
12
|
-
- [
|
|
5
|
+
The routes methods will configure the endpoints of your application. You have
|
|
6
|
+
two ways to declare a route with Fastify, the shorthand method and the full
|
|
7
|
+
declaration.
|
|
8
|
+
|
|
9
|
+
- [Full declaration](#full-declaration)
|
|
10
|
+
- [Routes options](#routes-options)
|
|
11
|
+
- [Shorthand declaration](#shorthand-declaration)
|
|
12
|
+
- [Url building](#url-building)
|
|
13
|
+
- [Async Await](#async-await)
|
|
13
14
|
- [Promise resolution](#promise-resolution)
|
|
14
15
|
- [Route Prefixing](#route-prefixing)
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- [
|
|
19
|
-
- [
|
|
16
|
+
- [Handling of / route inside prefixed
|
|
17
|
+
plugins](#handling-of--route-inside-prefixed-plugins)
|
|
18
|
+
- [Custom Log Level](#custom-log-level)
|
|
19
|
+
- [Custom Log Serializer](#custom-log-serializer)
|
|
20
|
+
- [Config](#config)
|
|
21
|
+
- [Constraints](#constraints)
|
|
22
|
+
- [Version Constraints](#version-constraints)
|
|
23
|
+
- [Host Constraints](#host-constraints)
|
|
20
24
|
|
|
21
|
-
<a name="full-declaration"></a>
|
|
22
25
|
### Full declaration
|
|
26
|
+
<a id="full-declaration"></a>
|
|
23
27
|
|
|
24
28
|
```js
|
|
25
29
|
fastify.route(options)
|
|
26
30
|
```
|
|
27
31
|
|
|
28
|
-
<a name="options"></a>
|
|
29
32
|
### Routes options
|
|
33
|
+
<a id="options"></a>
|
|
30
34
|
|
|
31
|
-
* `method`: currently it supports `'DELETE'`, `'GET'`, `'HEAD'`, `'PATCH'`,
|
|
35
|
+
* `method`: currently it supports `'DELETE'`, `'GET'`, `'HEAD'`, `'PATCH'`,
|
|
36
|
+
`'POST'`, `'PUT'` and `'OPTIONS'`. It could also be an array of methods.
|
|
32
37
|
* `url`: the path of the URL to match this route (alias: `path`).
|
|
33
|
-
* `schema`: an object containing the schemas for the request and response.
|
|
34
|
-
|
|
35
|
-
[
|
|
36
|
-
|
|
37
|
-
* `body`: validates the body of the request if it is a POST, PUT, or PATCH
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
* `schema`: an object containing the schemas for the request and response. They
|
|
39
|
+
need to be in [JSON Schema](https://json-schema.org/) format, check
|
|
40
|
+
[here](./Validation-and-Serialization.md) for more info.
|
|
41
|
+
|
|
42
|
+
* `body`: validates the body of the request if it is a POST, PUT, or PATCH
|
|
43
|
+
method.
|
|
44
|
+
* `querystring` or `query`: validates the querystring. This can be a complete
|
|
45
|
+
JSON Schema object, with the property `type` of `object` and `properties`
|
|
46
|
+
object of parameters, or simply the values of what would be contained in the
|
|
47
|
+
`properties` object as shown below.
|
|
41
48
|
* `params`: validates the params.
|
|
42
|
-
* `response`: filter and generate a schema for the response, setting a
|
|
43
|
-
|
|
44
|
-
* `exposeHeadRoute`: creates a sibling `HEAD` route for any `GET` routes.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
* `
|
|
49
|
-
|
|
50
|
-
* `
|
|
51
|
-
|
|
52
|
-
* `
|
|
53
|
-
|
|
54
|
-
* `
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
* `
|
|
59
|
-
|
|
60
|
-
* `
|
|
49
|
+
* `response`: filter and generate a schema for the response, setting a schema
|
|
50
|
+
allows us to have 10-20% more throughput.
|
|
51
|
+
* `exposeHeadRoute`: creates a sibling `HEAD` route for any `GET` routes.
|
|
52
|
+
Defaults to the value of [`exposeHeadRoutes`](./Server.md#exposeHeadRoutes)
|
|
53
|
+
instance option. If you want a custom `HEAD` handler without disabling this
|
|
54
|
+
option, make sure to define it before the `GET` route.
|
|
55
|
+
* `attachValidation`: attach `validationError` to request, if there is a schema
|
|
56
|
+
validation error, instead of sending the error to the error handler.
|
|
57
|
+
* `onRequest(request, reply, done)`: a [function](./Hooks.md#onrequest) as soon
|
|
58
|
+
that a request is received, it could also be an array of functions.
|
|
59
|
+
* `preParsing(request, reply, done)`: a [function](./Hooks.md#preparsing) called
|
|
60
|
+
before parsing the request, it could also be an array of functions.
|
|
61
|
+
* `preValidation(request, reply, done)`: a [function](./Hooks.md#prevalidation)
|
|
62
|
+
called after the shared `preValidation` hooks, useful if you need to perform
|
|
63
|
+
authentication at route level for example, it could also be an array of
|
|
64
|
+
functions.
|
|
65
|
+
* `preHandler(request, reply, done)`: a [function](./Hooks.md#prehandler) called
|
|
66
|
+
just before the request handler, it could also be an array of functions.
|
|
67
|
+
* `preSerialization(request, reply, payload, done)`: a
|
|
68
|
+
[function](./Hooks.md#preserialization) called just before the serialization,
|
|
69
|
+
it could also be an array of functions.
|
|
70
|
+
* `onSend(request, reply, payload, done)`: a [function](./Hooks.md#route-hooks)
|
|
71
|
+
called right before a response is sent, it could also be an array of
|
|
72
|
+
functions.
|
|
73
|
+
* `onResponse(request, reply, done)`: a [function](./Hooks.md#onresponse) called
|
|
74
|
+
when a response has been sent, so you will not be able to send more data to
|
|
75
|
+
the client. It could also be an array of functions.
|
|
76
|
+
* `onTimeout(request, reply, done)`: a [function](./Hooks.md#ontimeout) called
|
|
77
|
+
when a request is timed out and the HTTP socket has been hanged up.
|
|
78
|
+
* `onError(request, reply, error, done)`: a [function](./Hooks.md#onerror)
|
|
79
|
+
called when an Error is thrown or send to the client by the route handler.
|
|
80
|
+
* `handler(request, reply)`: the function that will handle this request. The
|
|
81
|
+
[Fastify server](./Server.md) will be bound to `this` when the handler is
|
|
82
|
+
called. Note: using an arrow function will break the binding of `this`.
|
|
83
|
+
* `errorHandler(error, request, reply)`: a custom error handler for the scope of
|
|
84
|
+
the request. Overrides the default error global handler, and anything set by
|
|
85
|
+
[`setErrorHandler`](./Server.md#seterrorhandler), for requests to the route.
|
|
86
|
+
To access the default handler, you can access `instance.errorHandler`. Note
|
|
87
|
+
that this will point to fastify's default `errorHandler` only if a plugin
|
|
88
|
+
hasn't overridden it already.
|
|
89
|
+
* `validatorCompiler({ schema, method, url, httpPart })`: function that builds
|
|
90
|
+
schemas for request validations. See the [Validation and
|
|
91
|
+
Serialization](./Validation-and-Serialization.md#schema-validator)
|
|
92
|
+
documentation.
|
|
93
|
+
* `serializerCompiler({ { schema, method, url, httpStatus } })`: function that
|
|
94
|
+
builds schemas for response serialization. See the [Validation and
|
|
95
|
+
Serialization](./Validation-and-Serialization.md#schema-serializer)
|
|
96
|
+
documentation.
|
|
97
|
+
* `schemaErrorFormatter(errors, dataVar)`: function that formats the errors from
|
|
98
|
+
the validation compiler. See the [Validation and
|
|
99
|
+
Serialization](./Validation-and-Serialization.md#error-handling)
|
|
100
|
+
documentation. Overrides the global schema error formatter handler, and
|
|
101
|
+
anything set by `setSchemaErrorFormatter`, for requests to the route.
|
|
102
|
+
* `bodyLimit`: prevents the default JSON body parser from parsing request bodies
|
|
103
|
+
larger than this number of bytes. Must be an integer. You may also set this
|
|
104
|
+
option globally when first creating the Fastify instance with
|
|
105
|
+
`fastify(options)`. Defaults to `1048576` (1 MiB).
|
|
61
106
|
* `logLevel`: set log level for this route. See below.
|
|
62
107
|
* `logSerializers`: set serializers to log for this route.
|
|
63
108
|
* `config`: object used to store custom configuration.
|
|
64
|
-
* `version`: a [semver](https://semver.org/) compatible string that defined the
|
|
65
|
-
|
|
109
|
+
* `version`: a [semver](https://semver.org/) compatible string that defined the
|
|
110
|
+
version of the endpoint. [Example](#version-constraints).
|
|
111
|
+
* `prefixTrailingSlash`: string used to determine how to handle passing `/` as a
|
|
112
|
+
route with a prefix.
|
|
66
113
|
* `both` (default): Will register both `/prefix` and `/prefix/`.
|
|
67
114
|
* `slash`: Will register only `/prefix/`.
|
|
68
115
|
* `no-slash`: Will register only `/prefix`.
|
|
69
116
|
|
|
70
|
-
`request` is defined in [Request](Request.md).
|
|
117
|
+
`request` is defined in [Request](./Request.md).
|
|
71
118
|
|
|
72
|
-
`reply` is defined in [Reply](Reply.md).
|
|
119
|
+
`reply` is defined in [Reply](./Reply.md).
|
|
73
120
|
|
|
74
121
|
**Notice:** The documentation of `onRequest`, `preParsing`, `preValidation`,
|
|
75
122
|
`preHandler`, `preSerialization`, `onSend`, and `onResponse` are described in
|
|
76
|
-
more detail in [Hooks](Hooks.md). Additionally, to send a response before the
|
|
77
|
-
request is handled by the `handler` please refer to
|
|
78
|
-
|
|
123
|
+
more detail in [Hooks](./Hooks.md). Additionally, to send a response before the
|
|
124
|
+
request is handled by the `handler` please refer to [Respond to a request from a
|
|
125
|
+
hook](./Hooks.md#respond-to-a-request-from-a-hook).
|
|
79
126
|
|
|
80
127
|
Example:
|
|
81
128
|
```js
|
|
@@ -102,15 +149,24 @@ fastify.route({
|
|
|
102
149
|
})
|
|
103
150
|
```
|
|
104
151
|
|
|
105
|
-
<a name="shorthand-declaration"></a>
|
|
106
152
|
### Shorthand declaration
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
`fastify.
|
|
113
|
-
|
|
153
|
+
<a id="shorthand-declaration"></a>
|
|
154
|
+
|
|
155
|
+
The above route declaration is more *Hapi*-like, but if you prefer an
|
|
156
|
+
*Express/Restify* approach, we support it as well:
|
|
157
|
+
|
|
158
|
+
`fastify.get(path, [options], handler)`
|
|
159
|
+
|
|
160
|
+
`fastify.head(path, [options], handler)`
|
|
161
|
+
|
|
162
|
+
`fastify.post(path, [options], handler)`
|
|
163
|
+
|
|
164
|
+
`fastify.put(path, [options], handler)`
|
|
165
|
+
|
|
166
|
+
`fastify.delete(path, [options], handler)`
|
|
167
|
+
|
|
168
|
+
`fastify.options(path, [options], handler)`
|
|
169
|
+
|
|
114
170
|
`fastify.patch(path, [options], handler)`
|
|
115
171
|
|
|
116
172
|
Example:
|
|
@@ -132,7 +188,8 @@ fastify.get('/', opts, (request, reply) => {
|
|
|
132
188
|
})
|
|
133
189
|
```
|
|
134
190
|
|
|
135
|
-
`fastify.all(path, [options], handler)` will add the same handler to all the
|
|
191
|
+
`fastify.all(path, [options], handler)` will add the same handler to all the
|
|
192
|
+
supported methods.
|
|
136
193
|
|
|
137
194
|
The handler may also be supplied via the `options` object:
|
|
138
195
|
```js
|
|
@@ -154,13 +211,17 @@ const opts = {
|
|
|
154
211
|
fastify.get('/', opts)
|
|
155
212
|
```
|
|
156
213
|
|
|
157
|
-
> Note: if the handler is specified in both the `options` and as the third
|
|
214
|
+
> Note: if the handler is specified in both the `options` and as the third
|
|
215
|
+
> parameter to the shortcut method then throws duplicate `handler` error.
|
|
158
216
|
|
|
159
|
-
<a name="url-building"></a>
|
|
160
217
|
### Url building
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
218
|
+
<a id="url-building"></a>
|
|
219
|
+
|
|
220
|
+
Fastify supports both static and dynamic URLs.
|
|
221
|
+
|
|
222
|
+
To register a **parametric** path, use the *colon* before the parameter name.
|
|
223
|
+
For **wildcard**, use the *star*. *Remember that static routes are always
|
|
224
|
+
checked before parametric and wildcard.*
|
|
164
225
|
|
|
165
226
|
```js
|
|
166
227
|
// parametric
|
|
@@ -171,13 +232,15 @@ fastify.get('/example/:userId/:secretToken', (request, reply) => {})
|
|
|
171
232
|
fastify.get('/example/*', (request, reply) => {})
|
|
172
233
|
```
|
|
173
234
|
|
|
174
|
-
Regular expression routes are supported as well, but pay attention, RegExp are
|
|
235
|
+
Regular expression routes are supported as well, but pay attention, RegExp are
|
|
236
|
+
very expensive in term of performance!
|
|
175
237
|
```js
|
|
176
238
|
// parametric with regexp
|
|
177
239
|
fastify.get('/example/:file(^\\d+).png', (request, reply) => {})
|
|
178
240
|
```
|
|
179
241
|
|
|
180
|
-
It is possible to define more than one parameter within the same couple of slash
|
|
242
|
+
It is possible to define more than one parameter within the same couple of slash
|
|
243
|
+
("/"). Such as:
|
|
181
244
|
```js
|
|
182
245
|
fastify.get('/example/near/:lat-:lng/radius/:r', (request, reply) => {})
|
|
183
246
|
```
|
|
@@ -187,18 +250,23 @@ Finally it is possible to have multiple parameters with RegExp.
|
|
|
187
250
|
```js
|
|
188
251
|
fastify.get('/example/at/:hour(^\\d{2})h:minute(^\\d{2})m', (request, reply) => {})
|
|
189
252
|
```
|
|
190
|
-
In this case as parameter separator it is possible to use whatever character is
|
|
253
|
+
In this case as parameter separator it is possible to use whatever character is
|
|
254
|
+
not matched by the regular expression.
|
|
191
255
|
|
|
192
|
-
Having a route with multiple parameters may affect negatively the performance,
|
|
193
|
-
|
|
256
|
+
Having a route with multiple parameters may affect negatively the performance,
|
|
257
|
+
so prefer single parameter approach whenever possible, especially on routes that
|
|
258
|
+
are on the hot path of your application. If you are interested in how we handle
|
|
259
|
+
the routing, check out [find-my-way](https://github.com/delvedor/find-my-way).
|
|
194
260
|
|
|
195
|
-
If you want a path containing a colon without declaring a parameter, use a
|
|
261
|
+
If you want a path containing a colon without declaring a parameter, use a
|
|
262
|
+
double colon. For example:
|
|
196
263
|
```js
|
|
197
264
|
fastify.post('/name::verb') // will be interpreted as /name:verb
|
|
198
265
|
```
|
|
199
266
|
|
|
200
|
-
<a name="async-await"></a>
|
|
201
267
|
### Async Await
|
|
268
|
+
<a id="async-await"></a>
|
|
269
|
+
|
|
202
270
|
Are you an `async/await` user? We have you covered!
|
|
203
271
|
```js
|
|
204
272
|
fastify.get('/', options, async function (request, reply) {
|
|
@@ -208,7 +276,8 @@ fastify.get('/', options, async function (request, reply) {
|
|
|
208
276
|
})
|
|
209
277
|
```
|
|
210
278
|
|
|
211
|
-
As you can see, we are not calling `reply.send` to send back the data to the
|
|
279
|
+
As you can see, we are not calling `reply.send` to send back the data to the
|
|
280
|
+
user. You just need to return the body and you are done!
|
|
212
281
|
|
|
213
282
|
If you need it you can also send back the data to the user with `reply.send`.
|
|
214
283
|
```js
|
|
@@ -219,8 +288,8 @@ fastify.get('/', options, async function (request, reply) {
|
|
|
219
288
|
})
|
|
220
289
|
```
|
|
221
290
|
|
|
222
|
-
If the route is wrapping a callback-based API that will call
|
|
223
|
-
|
|
291
|
+
If the route is wrapping a callback-based API that will call `reply.send()`
|
|
292
|
+
outside of the promise chain, it is possible to `await reply`:
|
|
224
293
|
|
|
225
294
|
```js
|
|
226
295
|
fastify.get('/', options, async function (request, reply) {
|
|
@@ -243,29 +312,44 @@ fastify.get('/', options, async function (request, reply) {
|
|
|
243
312
|
```
|
|
244
313
|
|
|
245
314
|
**Warning:**
|
|
246
|
-
* When using both `return value` and `reply.send(value)` at the same time, the
|
|
247
|
-
|
|
315
|
+
* When using both `return value` and `reply.send(value)` at the same time, the
|
|
316
|
+
first one that happens takes precedence, the second value will be discarded,
|
|
317
|
+
and a *warn* log will also be emitted because you tried to send a response
|
|
318
|
+
twice.
|
|
319
|
+
* You cannot return `undefined`. For more details read
|
|
320
|
+
[promise-resolution](#promise-resolution).
|
|
248
321
|
|
|
249
|
-
<a name="promise-resolution"></a>
|
|
250
322
|
### Promise resolution
|
|
323
|
+
<a id="promise-resolution"></a>
|
|
251
324
|
|
|
252
|
-
If your handler is an `async` function or returns a promise, you should be aware
|
|
325
|
+
If your handler is an `async` function or returns a promise, you should be aware
|
|
326
|
+
of a special behavior that is necessary to support the callback and promise
|
|
327
|
+
control-flow. If the handler's promise is resolved with `undefined`, it will be
|
|
328
|
+
ignored causing the request to hang and an *error* log to be emitted.
|
|
253
329
|
|
|
254
|
-
1. If you want to use `async/await` or promises but return a value with
|
|
330
|
+
1. If you want to use `async/await` or promises but return a value with
|
|
331
|
+
`reply.send`:
|
|
255
332
|
- **Do not** `return` any value.
|
|
256
333
|
- **Do not** forget to call `reply.send`.
|
|
257
334
|
2. If you want to use `async/await` or promises:
|
|
258
335
|
- **Do not** use `reply.send`.
|
|
259
336
|
- **Do not** return `undefined`.
|
|
260
337
|
|
|
261
|
-
In this way, we can support both `callback-style` and `async-await`, with the
|
|
338
|
+
In this way, we can support both `callback-style` and `async-await`, with the
|
|
339
|
+
minimum trade-off. In spite of so much freedom we highly recommend to go with
|
|
340
|
+
only one style because error handling should be handled in a consistent way
|
|
341
|
+
within your application.
|
|
262
342
|
|
|
263
343
|
**Notice**: Every async function returns a promise by itself.
|
|
264
344
|
|
|
265
|
-
<a name="route-prefixing"></a>
|
|
266
345
|
### Route Prefixing
|
|
267
|
-
|
|
268
|
-
|
|
346
|
+
<a id="route-prefixing"></a>
|
|
347
|
+
|
|
348
|
+
Sometimes you need to maintain two or more different versions of the same API; a
|
|
349
|
+
classic approach is to prefix all the routes with the API version number,
|
|
350
|
+
`/v1/user` for example. Fastify offers you a fast and smart way to create
|
|
351
|
+
different versions of the same API without changing all the route names by hand,
|
|
352
|
+
*route prefixing*. Let's see how it works:
|
|
269
353
|
|
|
270
354
|
```js
|
|
271
355
|
// server.js
|
|
@@ -292,31 +376,42 @@ module.exports = function (fastify, opts, done) {
|
|
|
292
376
|
done()
|
|
293
377
|
}
|
|
294
378
|
```
|
|
295
|
-
Fastify will not complain because you are using the same name for two different
|
|
379
|
+
Fastify will not complain because you are using the same name for two different
|
|
380
|
+
routes, because at compilation time it will handle the prefix automatically
|
|
381
|
+
*(this also means that the performance will not be affected at all!)*.
|
|
296
382
|
|
|
297
383
|
Now your clients will have access to the following routes:
|
|
298
384
|
- `/v1/user`
|
|
299
385
|
- `/v2/user`
|
|
300
386
|
|
|
301
|
-
You can do this as many times as you want, it works also for nested `register`
|
|
302
|
-
|
|
387
|
+
You can do this as many times as you want, it works also for nested `register`
|
|
388
|
+
and routes parameter are supported as well. Be aware that if you use
|
|
389
|
+
[`fastify-plugin`](https://github.com/fastify/fastify-plugin) this option will
|
|
390
|
+
not work.
|
|
303
391
|
|
|
304
392
|
#### Handling of / route inside prefixed plugins
|
|
305
393
|
|
|
306
|
-
The `/` route has a different behavior depending on if the prefix ends with
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
and `/something/`.
|
|
394
|
+
The `/` route has a different behavior depending on if the prefix ends with `/`
|
|
395
|
+
or not. As an example, if we consider a prefix `/something/`, adding a `/` route
|
|
396
|
+
will only match `/something/`. If we consider a prefix `/something`, adding a
|
|
397
|
+
`/` route will match both `/something` and `/something/`.
|
|
311
398
|
|
|
312
399
|
See the `prefixTrailingSlash` route option above to change this behavior.
|
|
313
400
|
|
|
314
|
-
<a name="custom-log-level"></a>
|
|
315
401
|
### Custom Log Level
|
|
316
|
-
|
|
317
|
-
|
|
402
|
+
<a id="custom-log-level"></a>
|
|
403
|
+
|
|
404
|
+
It could happen that you need different log levels in your routes; Fastify
|
|
405
|
+
achieves this in a very straightforward way.
|
|
406
|
+
|
|
407
|
+
You just need to pass the option `logLevel` to the plugin option or the route
|
|
408
|
+
option with the
|
|
409
|
+
[value](https://github.com/pinojs/pino/blob/master/docs/api.md#level-string)
|
|
410
|
+
that you need.
|
|
318
411
|
|
|
319
|
-
Be aware that if you set the `logLevel` at plugin level, also the
|
|
412
|
+
Be aware that if you set the `logLevel` at plugin level, also the
|
|
413
|
+
[`setNotFoundHandler`](./Server.md#setnotfoundhandler) and
|
|
414
|
+
[`setErrorHandler`](./Server.md#seterrorhandler) will be affected.
|
|
320
415
|
|
|
321
416
|
```js
|
|
322
417
|
// server.js
|
|
@@ -334,12 +429,16 @@ fastify.get('/', { logLevel: 'warn' }, (request, reply) => {
|
|
|
334
429
|
reply.send({ hello: 'world' })
|
|
335
430
|
})
|
|
336
431
|
```
|
|
337
|
-
*Remember that the custom log level is applied only to the routes, and not to
|
|
432
|
+
*Remember that the custom log level is applied only to the routes, and not to
|
|
433
|
+
the global Fastify Logger, accessible with `fastify.log`*
|
|
338
434
|
|
|
339
|
-
<a name="custom-log-serializer"></a>
|
|
340
435
|
### Custom Log Serializer
|
|
436
|
+
<a id="custom-log-serializer"></a>
|
|
341
437
|
|
|
342
|
-
In some context, you may need to log a large object but it could be a waste of
|
|
438
|
+
In some context, you may need to log a large object but it could be a waste of
|
|
439
|
+
resources for some routes. In this case, you can define some
|
|
440
|
+
[`serializer`](https://github.com/pinojs/pino/blob/master/docs/api.md#serializers-object)
|
|
441
|
+
and attach them in the right context!
|
|
343
442
|
|
|
344
443
|
```js
|
|
345
444
|
const fastify = require('fastify')({ logger: true })
|
|
@@ -396,9 +495,11 @@ async function context1 (fastify, opts) {
|
|
|
396
495
|
fastify.listen(3000)
|
|
397
496
|
```
|
|
398
497
|
|
|
399
|
-
<a name="routes-config"></a>
|
|
400
498
|
### Config
|
|
401
|
-
|
|
499
|
+
<a id="routes-config"></a>
|
|
500
|
+
|
|
501
|
+
Registering a new handler, you can pass a configuration object to it and
|
|
502
|
+
retrieve it in the handler.
|
|
402
503
|
|
|
403
504
|
```js
|
|
404
505
|
// server.js
|
|
@@ -414,16 +515,34 @@ fastify.get('/it', { config: { output: 'ciao mondo!' } }, handler)
|
|
|
414
515
|
fastify.listen(3000)
|
|
415
516
|
```
|
|
416
517
|
|
|
417
|
-
<a name="constraints"></a>
|
|
418
518
|
### Constraints
|
|
519
|
+
<a id="constraints"></a>
|
|
419
520
|
|
|
420
|
-
Fastify supports constraining routes to match only certain requests based on
|
|
521
|
+
Fastify supports constraining routes to match only certain requests based on
|
|
522
|
+
some property of the request, like the `Host` header, or any other value via
|
|
523
|
+
[`find-my-way`](https://github.com/delvedor/find-my-way) constraints.
|
|
524
|
+
Constraints are specified in the `constraints` property of the route options.
|
|
525
|
+
Fastify has two built-in constraints ready for use: the `version` constraint and
|
|
526
|
+
the `host` constraint, and you can add your own custom constraint strategies to
|
|
527
|
+
inspect other parts of a request to decide if a route should be executed for a
|
|
528
|
+
request.
|
|
421
529
|
|
|
422
530
|
#### Version Constraints
|
|
423
531
|
|
|
424
|
-
You can provide a `version` key in the `constraints` option to a route.
|
|
425
|
-
|
|
426
|
-
|
|
532
|
+
You can provide a `version` key in the `constraints` option to a route.
|
|
533
|
+
Versioned routes allow you to declare multiple handlers for the same HTTP route
|
|
534
|
+
path, which will then be matched according to each request's `Accept-Version`
|
|
535
|
+
header. The `Accept-Version` header value should follow the
|
|
536
|
+
[semver](http://semver.org/) specification, and routes should be declared with
|
|
537
|
+
exact semver versions for matching.
|
|
538
|
+
|
|
539
|
+
Fastify will require a request `Accept-Version` header to be set if the route
|
|
540
|
+
has a version set, and will prefer a versioned route to a non-versioned route
|
|
541
|
+
for the same path. Advanced version ranges and pre-releases currently are not
|
|
542
|
+
supported.
|
|
543
|
+
|
|
544
|
+
*Be aware that using this feature will cause a degradation of the overall
|
|
545
|
+
performances of the router.*
|
|
427
546
|
|
|
428
547
|
```js
|
|
429
548
|
fastify.route({
|
|
@@ -447,9 +566,11 @@ fastify.inject({
|
|
|
447
566
|
```
|
|
448
567
|
|
|
449
568
|
> ## ⚠ Security Notice
|
|
450
|
-
> Remember to set a
|
|
451
|
-
>
|
|
452
|
-
>
|
|
569
|
+
> Remember to set a
|
|
570
|
+
> [`Vary`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary)
|
|
571
|
+
> header in your responses with the value you are using for defining the
|
|
572
|
+
> versioning (e.g.: `'Accept-Version'`), to prevent cache poisoning attacks. You
|
|
573
|
+
> can also configure this as part of your Proxy/CDN.
|
|
453
574
|
>
|
|
454
575
|
> ```js
|
|
455
576
|
> const append = require('vary').append
|
|
@@ -464,14 +585,22 @@ fastify.inject({
|
|
|
464
585
|
> })
|
|
465
586
|
> ```
|
|
466
587
|
|
|
467
|
-
If you declare multiple versions with the same major or minor, Fastify will
|
|
468
|
-
|
|
588
|
+
If you declare multiple versions with the same major or minor, Fastify will
|
|
589
|
+
always choose the highest compatible with the `Accept-Version` header value.
|
|
590
|
+
|
|
591
|
+
If the request will not have the `Accept-Version` header, a 404 error will be
|
|
592
|
+
returned.
|
|
469
593
|
|
|
470
|
-
It is possible to define a custom version matching logic. This can be done
|
|
594
|
+
It is possible to define a custom version matching logic. This can be done
|
|
595
|
+
through the [`constraints`](./Server.md#constraints) configuration when creating
|
|
596
|
+
a Fastify server instance.
|
|
471
597
|
|
|
472
598
|
#### Host Constraints
|
|
473
599
|
|
|
474
|
-
You can provide a `host` key in the `constraints` route option for to limit that
|
|
600
|
+
You can provide a `host` key in the `constraints` route option for to limit that
|
|
601
|
+
route to only be matched for certain values of the request `Host` header. `host`
|
|
602
|
+
constraint values can be specified as strings for exact matches or RegExps for
|
|
603
|
+
arbitrary host matching.
|
|
475
604
|
|
|
476
605
|
```js
|
|
477
606
|
fastify.route({
|
|
@@ -504,7 +633,8 @@ fastify.inject({
|
|
|
504
633
|
})
|
|
505
634
|
```
|
|
506
635
|
|
|
507
|
-
RegExp `host` constraints can also be specified allowing constraining to hosts
|
|
636
|
+
RegExp `host` constraints can also be specified allowing constraining to hosts
|
|
637
|
+
matching wildcard subdomains (or any other pattern):
|
|
508
638
|
|
|
509
639
|
```js
|
|
510
640
|
fastify.route({
|