fastify 5.2.1 → 5.3.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.
Files changed (85) hide show
  1. package/LICENSE +1 -1
  2. package/PROJECT_CHARTER.md +7 -7
  3. package/README.md +24 -25
  4. package/SPONSORS.md +1 -0
  5. package/docs/Guides/Benchmarking.md +4 -4
  6. package/docs/Guides/Database.md +1 -1
  7. package/docs/Guides/Delay-Accepting-Requests.md +10 -10
  8. package/docs/Guides/Ecosystem.md +7 -1
  9. package/docs/Guides/Fluent-Schema.md +1 -1
  10. package/docs/Guides/Getting-Started.md +9 -5
  11. package/docs/Guides/Index.md +1 -1
  12. package/docs/Guides/Migration-Guide-V4.md +1 -1
  13. package/docs/Guides/Migration-Guide-V5.md +12 -2
  14. package/docs/Guides/Plugins-Guide.md +6 -6
  15. package/docs/Guides/Serverless.md +14 -48
  16. package/docs/Guides/Style-Guide.md +2 -2
  17. package/docs/Guides/Testing.md +2 -2
  18. package/docs/Guides/Write-Plugin.md +2 -3
  19. package/docs/Reference/ContentTypeParser.md +58 -78
  20. package/docs/Reference/Decorators.md +249 -60
  21. package/docs/Reference/Encapsulation.md +28 -33
  22. package/docs/Reference/Errors.md +52 -53
  23. package/docs/Reference/HTTP2.md +7 -7
  24. package/docs/Reference/Hooks.md +31 -30
  25. package/docs/Reference/LTS.md +10 -15
  26. package/docs/Reference/Lifecycle.md +19 -24
  27. package/docs/Reference/Logging.md +59 -56
  28. package/docs/Reference/Middleware.md +19 -19
  29. package/docs/Reference/Plugins.md +55 -71
  30. package/docs/Reference/Principles.md +25 -30
  31. package/docs/Reference/Reply.md +11 -10
  32. package/docs/Reference/Request.md +89 -98
  33. package/docs/Reference/Routes.md +108 -128
  34. package/docs/Reference/Server.md +18 -16
  35. package/docs/Reference/Type-Providers.md +19 -21
  36. package/docs/Reference/TypeScript.md +1 -18
  37. package/docs/Reference/Validation-and-Serialization.md +134 -159
  38. package/docs/Reference/Warnings.md +22 -25
  39. package/fastify.js +3 -2
  40. package/lib/contentTypeParser.js +7 -8
  41. package/lib/decorate.js +18 -3
  42. package/lib/error-handler.js +14 -12
  43. package/lib/errors.js +4 -0
  44. package/lib/headRoute.js +4 -2
  45. package/lib/pluginUtils.js +4 -2
  46. package/lib/reply.js +17 -2
  47. package/lib/request.js +28 -2
  48. package/lib/server.js +5 -0
  49. package/lib/validation.js +1 -1
  50. package/lib/warnings.js +9 -0
  51. package/lib/wrapThenable.js +8 -1
  52. package/package.json +12 -12
  53. package/test/bundler/esbuild/package.json +1 -1
  54. package/test/close.test.js +125 -108
  55. package/test/custom-parser-async.test.js +34 -36
  56. package/test/custom-parser.4.test.js +55 -38
  57. package/test/decorator.test.js +174 -4
  58. package/test/fastify-instance.test.js +12 -2
  59. package/test/genReqId.test.js +125 -174
  60. package/test/has-route.test.js +1 -3
  61. package/test/hooks.on-listen.test.js +17 -14
  62. package/test/internals/content-type-parser.test.js +1 -1
  63. package/test/internals/errors.test.js +14 -1
  64. package/test/issue-4959.test.js +84 -0
  65. package/test/listen.1.test.js +37 -34
  66. package/test/listen.2.test.js +50 -40
  67. package/test/listen.3.test.js +28 -32
  68. package/test/listen.4.test.js +61 -45
  69. package/test/listen.5.test.js +23 -0
  70. package/test/register.test.js +55 -50
  71. package/test/request-error.test.js +114 -94
  72. package/test/route-shorthand.test.js +36 -32
  73. package/test/stream.5.test.js +35 -33
  74. package/test/throw.test.js +87 -91
  75. package/test/toolkit.js +32 -0
  76. package/test/trust-proxy.test.js +23 -23
  77. package/test/types/instance.test-d.ts +4 -0
  78. package/test/types/reply.test-d.ts +1 -0
  79. package/test/types/request.test-d.ts +4 -0
  80. package/test/types/type-provider.test-d.ts +40 -0
  81. package/test/upgrade.test.js +32 -33
  82. package/types/instance.d.ts +6 -0
  83. package/types/reply.d.ts +1 -0
  84. package/types/request.d.ts +2 -0
  85. package/types/type-provider.d.ts +12 -3
@@ -2,16 +2,15 @@
2
2
 
3
3
  ## Decorators
4
4
 
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.
5
+ The decorators API customizes core Fastify objects, such as the server instance
6
+ and any request and reply objects used during the HTTP request lifecycle. It
7
+ can attach any type of property to core objects, e.g., functions, plain
8
+ objects, or native types.
9
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.
10
+ This API is *synchronous*. Defining a decoration asynchronously could result in
11
+ the Fastify instance booting before the decoration completes. To register an
12
+ asynchronous decoration, use the `register` API with `fastify-plugin`. See the
13
+ [Plugins](./Plugins.md) documentation for more details.
15
14
 
16
15
  Decorating core objects with this API allows the underlying JavaScript engine to
17
16
  optimize the handling of server, request, and reply objects. This is
@@ -35,9 +34,9 @@ fastify.get('/', function (req, reply) {
35
34
  })
36
35
  ```
37
36
 
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
40
- object. By using the decoration API this deoptimization is avoided:
37
+ The above example mutates the request object after instantiation, causing the
38
+ JavaScript engine to deoptimize access. Using the decoration API avoids this
39
+ deoptimization:
41
40
 
42
41
  ```js
43
42
  // Decorate request with a 'user' property
@@ -54,17 +53,13 @@ fastify.get('/', (req, reply) => {
54
53
  })
55
54
  ```
56
55
 
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.
61
-
62
- Remember this example works only with value types as reference types will
63
- thrown and error during the fastify startup. See [decorateRequest](#decorate-request).
64
-
65
- See [JavaScript engine fundamentals: Shapes and Inline
66
- Caches](https://mathiasbynens.be/notes/shapes-ics) for more information on this
67
- topic.
56
+ Keep the initial shape of a decorated field close to its future dynamic value.
57
+ Initialize a decorator as `''` for strings and `null` for objects or functions.
58
+ This works only with value types; reference types will throw an error during
59
+ Fastify startup. See [decorateRequest](#decorate-request) and
60
+ [JavaScript engine fundamentals: Shapes
61
+ and Inline Caches](https://mathiasbynens.be/notes/shapes-ics)
62
+ for more information.
68
63
 
69
64
  ### Usage
70
65
  <a id="usage"></a>
@@ -72,8 +67,7 @@ topic.
72
67
  #### `decorate(name, value, [dependencies])`
73
68
  <a id="decorate"></a>
74
69
 
75
- This method is used to customize the Fastify [server](./Server.md)
76
- instance.
70
+ This method customizes the Fastify [server](./Server.md) instance.
77
71
 
78
72
  For example, to attach a new method to the server instance:
79
73
 
@@ -83,7 +77,7 @@ fastify.decorate('utility', function () {
83
77
  })
84
78
  ```
85
79
 
86
- As mentioned above, non-function values can be attached to the server instance as:
80
+ Non-function values can also be attached to the server instance:
87
81
 
88
82
  ```js
89
83
  fastify.decorate('conf', {
@@ -118,9 +112,9 @@ fastify.get('/', async function (request, reply) {
118
112
  ```
119
113
 
120
114
  The `dependencies` parameter is an optional list of decorators that the
121
- decorator being defined relies upon. This list is simply a list of string names
122
- of other decorators. In the following example, the "utility" decorator depends
123
- upon "greet" and "hi" decorators:
115
+ decorator being defined relies upon. This list contains the names of other
116
+ decorators. In the following example, the "utility" decorator depends on the
117
+ "greet" and "hi" decorators:
124
118
 
125
119
  ```js
126
120
  async function greetDecorator (fastify, opts) {
@@ -155,18 +149,17 @@ fastify.listen({ port: 3000 }, (err, address) => {
155
149
  })
156
150
  ```
157
151
 
158
- Note: using an arrow function will break the binding of `this` to the
159
- `FastifyInstance`.
152
+ Using an arrow function breaks the binding of `this` to
153
+ the `FastifyInstance`.
160
154
 
161
- If a dependency is not satisfied, the `decorate` method will throw an exception.
162
- The dependency check is performed before the server instance is booted. Thus, it
163
- cannot occur during runtime.
155
+ If a dependency is not satisfied, the `decorate` method throws an exception.
156
+ The dependency check occurs before the server instance boots, not during
157
+ runtime.
164
158
 
165
159
  #### `decorateReply(name, value, [dependencies])`
166
160
  <a id="decorate-reply"></a>
167
161
 
168
- As the name suggests, this API is used to add new methods/properties to the core
169
- `Reply` object:
162
+ This API adds new methods/properties to the core `Reply` object:
170
163
 
171
164
  ```js
172
165
  fastify.decorateReply('utility', function () {
@@ -174,29 +167,29 @@ fastify.decorateReply('utility', function () {
174
167
  })
175
168
  ```
176
169
 
177
- Note: using an arrow function will break the binding of `this` to the Fastify
170
+ Using an arrow function will break the binding of `this` to the Fastify
178
171
  `Reply` instance.
179
172
 
180
- Note: using `decorateReply` will throw and error if used with a reference type:
173
+ Using `decorateReply` will throw and error if used with a reference type:
181
174
 
182
175
  ```js
183
176
  // Don't do this
184
177
  fastify.decorateReply('foo', { bar: 'fizz'})
185
178
  ```
186
- In this example, the reference of the object would be shared with all the requests
187
- and **any mutation will impact all requests, potentially creating security
188
- vulnerabilities or memory leaks**, so Fastify blocks it.
179
+ In this example, the object reference would be shared with all requests, and
180
+ **any mutation will impact all requests, potentially creating security
181
+ vulnerabilities or memory leaks**. Fastify blocks this.
189
182
 
190
183
  To achieve proper encapsulation across requests configure a new value for each
191
- incoming request in the [`'onRequest'` hook](./Hooks.md#onrequest). Example:
184
+ incoming request in the [`'onRequest'` hook](./Hooks.md#onrequest).
192
185
 
193
186
  ```js
194
187
  const fp = require('fastify-plugin')
195
188
 
196
189
  async function myPlugin (app) {
197
- app.decorateRequest('foo')
190
+ app.decorateReply('foo')
198
191
  app.addHook('onRequest', async (req, reply) => {
199
- req.foo = { bar: 42 }
192
+ reply.foo = { bar: 42 }
200
193
  })
201
194
  }
202
195
 
@@ -208,8 +201,8 @@ See [`decorate`](#decorate) for information about the `dependencies` parameter.
208
201
  #### `decorateRequest(name, value, [dependencies])`
209
202
  <a id="decorate-request"></a>
210
203
 
211
- As above with [`decorateReply`](#decorate-reply), this API is used add new
212
- methods/properties to the core `Request` object:
204
+ As with [`decorateReply`](#decorate-reply), this API adds new methods/properties
205
+ to the core `Request` object:
213
206
 
214
207
  ```js
215
208
  fastify.decorateRequest('utility', function () {
@@ -217,18 +210,18 @@ fastify.decorateRequest('utility', function () {
217
210
  })
218
211
  ```
219
212
 
220
- Note: using an arrow function will break the binding of `this` to the Fastify
213
+ Using an arrow function will break the binding of `this` to the Fastify
221
214
  `Request` instance.
222
215
 
223
- Note: using `decorateRequest` will emit an error if used with a reference type:
216
+ Using `decorateRequest` will emit an error if used with a reference type:
224
217
 
225
218
  ```js
226
219
  // Don't do this
227
220
  fastify.decorateRequest('foo', { bar: 'fizz'})
228
221
  ```
229
- In this example, the reference of the object would be shared with all the requests
230
- and **any mutation will impact all requests, potentially creating security
231
- vulnerabilities or memory leaks**, so Fastify blocks it.
222
+ In this example, the object reference would be shared with all requests, and
223
+ **any mutation will impact all requests, potentially creating security
224
+ vulnerabilities or memory leaks**. Fastify blocks this.
232
225
 
233
226
  To achieve proper encapsulation across requests configure a new value for each
234
227
  incoming request in the [`'onRequest'` hook](./Hooks.md#onrequest).
@@ -249,7 +242,7 @@ module.exports = fp(myPlugin)
249
242
  ```
250
243
 
251
244
  The hook solution is more flexible and allows for more complex initialization
252
- because you can add more logic to the `onRequest` hook.
245
+ because more logic can be added to the `onRequest` hook.
253
246
 
254
247
  Another approach is to use the getter/setter pattern, but it requires 2 decorators:
255
248
 
@@ -268,8 +261,7 @@ fastify.get('/', async function (req, reply) {
268
261
  })
269
262
  ```
270
263
 
271
- This ensures that the `user` property is always unique for each
272
- request.
264
+ This ensures that the `user` property is always unique for each request.
273
265
 
274
266
  See [`decorate`](#decorate) for information about the `dependencies` parameter.
275
267
 
@@ -305,9 +297,7 @@ fastify.hasReplyDecorator('utility')
305
297
 
306
298
  Defining a decorator (using `decorate`, `decorateRequest`, or `decorateReply`)
307
299
  with the same name more than once in the same **encapsulated** context will
308
- throw an exception.
309
-
310
- As an example, the following will throw:
300
+ throw an exception. For example, the following will throw:
311
301
 
312
302
  ```js
313
303
  const server = require('fastify')()
@@ -358,9 +348,9 @@ server.listen({ port: 3000 })
358
348
  ### Getters and Setters
359
349
  <a id="getters-setters"></a>
360
350
 
361
- Decorators accept special "getter/setter" objects. These objects have functions
362
- named `getter` and `setter` (though the `setter` function is optional). This
363
- allows defining properties via decorators, for example:
351
+ Decorators accept special "getter/setter" objects with `getter` and optional
352
+ `setter` functions. This allows defining properties via decorators,
353
+ for example:
364
354
 
365
355
  ```js
366
356
  fastify.decorate('foo', {
@@ -375,3 +365,202 @@ Will define the `foo` property on the Fastify instance:
375
365
  ```js
376
366
  console.log(fastify.foo) // 'a getter'
377
367
  ```
368
+
369
+ ### `getDecorator<T>` API
370
+
371
+ Fastify's `getDecorator<T>` API retrieves an existing decorator from the
372
+ Fastify instance, `Request`, or `Reply`. If the decorator is not defined, an
373
+ `FST_ERR_DEC_UNDECLARED` error is thrown.
374
+
375
+ #### Use cases
376
+
377
+ **Early Plugin Dependency Validation**
378
+
379
+ `getDecorator<T>` on Fastify instance verifies that required decorators are
380
+ available at registration time.
381
+
382
+ For example:
383
+
384
+ ```js
385
+ fastify.register(async function (fastify) {
386
+ const usersRepository = fastify.getDecorator('usersRepository')
387
+
388
+ fastify.get('/users', async function (request, reply) {
389
+ // We are sure `usersRepository` exists at runtime
390
+ return usersRepository.findAll()
391
+ })
392
+ })
393
+ ```
394
+
395
+ **Handling Missing Decorators**
396
+
397
+ Directly accessing a decorator may lead to unexpected behavior if it is not declared:
398
+
399
+ ```ts
400
+ const user = request.user;
401
+ if (user && user.isAdmin) {
402
+ // Execute admin tasks.
403
+ }
404
+ ```
405
+
406
+ If `request.user` doesn't exist, then `user` will be set to `undefined`.
407
+ This makes it unclear whether the user is unauthenticated or the decorator is missing.
408
+
409
+ Using `getDecorator` enforces runtime safety:
410
+
411
+ ```ts
412
+ // If the decorator is missing, an explicit `FST_ERR_DEC_UNDECLARED`
413
+ // error is thrown immediately.
414
+ const user = request.getDecorator('user');
415
+ if (user && user.isAdmin) {
416
+ // Execute admin tasks.
417
+ }
418
+ ```
419
+
420
+ **Alternative to Module Augmentation**
421
+
422
+ Decorators are typically typed via module augmentation:
423
+
424
+ ```ts
425
+ declare module 'fastify' {
426
+ interface FastifyInstance {
427
+ usersRepository: IUsersRepository
428
+ }
429
+ interface FastifyRequest {
430
+ session: ISession
431
+ }
432
+ interface FastifyReply {
433
+ sendSuccess: SendSuccessFn
434
+ }
435
+ }
436
+ ```
437
+
438
+ This approach modifies the Fastify instance globally, which may lead to
439
+ conflicts and inconsistent behavior in multi-server setups or with plugin
440
+ encapsulation.
441
+
442
+ Using `getDecorator<T>` allows to limit types scope:
443
+
444
+ ```ts
445
+ serverOne.register(async function (fastify) {
446
+ const usersRepository = fastify.getDecorator<PostgreUsersRepository>(
447
+ 'usersRepository'
448
+ )
449
+
450
+ fastify.decorateRequest('session', null)
451
+ fastify.addHook('onRequest', async (req, reply) => {
452
+ // Yes, the request object has a setDecorator method.
453
+ // More information will be provided soon.
454
+ req.setDecorator('session', { user: 'Jean' })
455
+ })
456
+
457
+ fastify.get('/me', (request, reply) => {
458
+ const session = request.getDecorator<ISession>('session')
459
+ reply.send(session)
460
+ })
461
+ })
462
+
463
+ serverTwo.register(async function (fastify) {
464
+ const usersRepository = fastify.getDecorator<SqlLiteUsersRepository>(
465
+ 'usersRepository'
466
+ )
467
+
468
+ fastify.decorateReply('sendSuccess', function (data) {
469
+ return this.send({ success: true })
470
+ })
471
+
472
+ fastify.get('/success', async (request, reply) => {
473
+ const sendSuccess = reply.getDecorator<SendSuccessFn>('sendSuccess')
474
+ await sendSuccess()
475
+ })
476
+ })
477
+ ```
478
+
479
+ #### Bound functions inference
480
+
481
+ To save time, it's common to infer function types instead of
482
+ writing them manually:
483
+
484
+ ```ts
485
+ function sendSuccess (this: FastifyReply) {
486
+ return this.send({ success: true })
487
+ }
488
+
489
+ export type SendSuccess = typeof sendSuccess
490
+ ```
491
+
492
+ However, `getDecorator` returns functions with the `this`
493
+ context already **bound**, meaning the `this` parameter disappears
494
+ from the function signature.
495
+
496
+ To correctly type it, you should use `OmitThisParameter` utility:
497
+
498
+ ```ts
499
+ function sendSuccess (this: FastifyReply) {
500
+ return this.send({ success: true })
501
+ }
502
+
503
+ type BoundSendSuccess = OmitThisParameter<typeof sendSuccess>
504
+
505
+ fastify.decorateReply('sendSuccess', sendSuccess)
506
+ fastify.get('/success', async (request, reply) => {
507
+ const sendSuccess = reply.getDecorator<BoundSendSuccess>('sendSuccess')
508
+ await sendSuccess()
509
+ })
510
+ ```
511
+
512
+ ### `Request.setDecorator<T>` Method
513
+
514
+ The `setDecorator<T>` method provides a safe and convenient way to
515
+ update the value of a `Request` decorator.
516
+ If the decorator does not exist, a `FST_ERR_DEC_UNDECLARED` error
517
+ is thrown.
518
+
519
+ #### Use Cases
520
+
521
+ **Runtime Safety**
522
+
523
+ A typical way to set a `Request` decorator looks like this:
524
+
525
+ ```ts
526
+ fastify.decorateRequest('user', '')
527
+ fastify.addHook('preHandler', async (req, reply) => {
528
+ req.user = 'Bob Dylan'
529
+ })
530
+ ```
531
+
532
+ However, there is no guarantee that the decorator actually exists
533
+ unless you manually check beforehand.
534
+ Additionally, typos are common, e.g. `account`, `acount`, or `accout`.
535
+
536
+ By using `setDecorator`, you are always sure that the decorator exists:
537
+
538
+ ```ts
539
+ fastify.decorateRequest('user', '')
540
+ fastify.addHook('preHandler', async (req, reply) => {
541
+ // Throws FST_ERR_DEC_UNDECLARED if the decorator does not exist
542
+ req.setDecorator('user-with-typo', 'Bob Dylan')
543
+ })
544
+ ```
545
+
546
+ ---
547
+
548
+ **Type Safety**
549
+
550
+ If the `FastifyRequest` interface does not declare the decorator, you
551
+ would typically need to use type assertions:
552
+
553
+ ```ts
554
+ fastify.addHook('preHandler', async (req, reply) => {
555
+ (req as typeof req & { user: string }).user = 'Bob Dylan'
556
+ })
557
+ ```
558
+
559
+ The `setDecorator<T>` method eliminates the need for explicit type
560
+ assertions while allowing type safety:
561
+
562
+ ```ts
563
+ fastify.addHook('preHandler', async (req, reply) => {
564
+ req.setDecorator<string>('user', 'Bob Dylan')
565
+ })
566
+ ```
@@ -3,21 +3,20 @@
3
3
  ## Encapsulation
4
4
  <a id="encapsulation"></a>
5
5
 
6
- A fundamental feature of Fastify is the "encapsulation context." The
7
- encapsulation context governs which [decorators](./Decorators.md), registered
8
- [hooks](./Hooks.md), and [plugins](./Plugins.md) are available to
9
- [routes](./Routes.md). A visual representation of the encapsulation context
10
- is shown in the following figure:
6
+ A fundamental feature of Fastify is the "encapsulation context." It governs
7
+ which [decorators](./Decorators.md), registered [hooks](./Hooks.md), and
8
+ [plugins](./Plugins.md) are available to [routes](./Routes.md). A visual
9
+ representation of the encapsulation context is shown in the following figure:
11
10
 
12
11
  ![Figure 1](../resources/encapsulation_context.svg)
13
12
 
14
- In the above figure, there are several entities:
13
+ In the figure above, there are several entities:
15
14
 
16
15
  1. The _root context_
17
16
  2. Three _root plugins_
18
- 3. Two _child contexts_ where each _child context_ has
17
+ 3. Two _child contexts_, each with:
19
18
  * Two _child plugins_
20
- * One _grandchild context_ where each _grandchild context_ has
19
+ * One _grandchild context_, each with:
21
20
  - Three _child plugins_
22
21
 
23
22
  Every _child context_ and _grandchild context_ has access to the _root plugins_.
@@ -26,15 +25,14 @@ _child plugins_ registered within the containing _child context_, but the
26
25
  containing _child context_ **does not** have access to the _child plugins_
27
26
  registered within its _grandchild context_.
28
27
 
29
- Given that everything in Fastify is a [plugin](./Plugins.md), except for the
28
+ Given that everything in Fastify is a [plugin](./Plugins.md) except for the
30
29
  _root context_, every "context" and "plugin" in this example is a plugin
31
- that can consist of decorators, hooks, plugins, and routes. Thus, to put
32
- this example into concrete terms, consider a basic scenario of a REST API
33
- server that has three routes: the first route (`/one`) requires authentication,
34
- the second route (`/two`) does not, and the third route (`/three`) has
35
- access to the same context as the second route. Using
36
- [@fastify/bearer-auth][bearer] to provide the authentication, the code for this
37
- example is as follows:
30
+ that can consist of decorators, hooks, plugins, and routes. To put this
31
+ example into concrete terms, consider a basic scenario of a REST API server
32
+ with three routes: the first route (`/one`) requires authentication, the
33
+ second route (`/two`) does not, and the third route (`/three`) has access to
34
+ the same context as the second route. Using [@fastify/bearer-auth][bearer] to
35
+ provide authentication, the code for this example is as follows:
38
36
 
39
37
  ```js
40
38
  'use strict'
@@ -52,9 +50,9 @@ fastify.register(async function authenticatedContext (childServer) {
52
50
  handler (request, response) {
53
51
  response.send({
54
52
  answer: request.answer,
55
- // request.foo will be undefined as it's only defined in publicContext
53
+ // request.foo will be undefined as it is only defined in publicContext
56
54
  foo: request.foo,
57
- // request.bar will be undefined as it's only defined in grandchildContext
55
+ // request.bar will be undefined as it is only defined in grandchildContext
58
56
  bar: request.bar
59
57
  })
60
58
  }
@@ -71,7 +69,7 @@ fastify.register(async function publicContext (childServer) {
71
69
  response.send({
72
70
  answer: request.answer,
73
71
  foo: request.foo,
74
- // request.bar will be undefined as it's only defined in grandchildContext
72
+ // request.bar will be undefined as it is only defined in grandchildContext
75
73
  bar: request.bar
76
74
  })
77
75
  }
@@ -97,16 +95,16 @@ fastify.register(async function publicContext (childServer) {
97
95
  fastify.listen({ port: 8000 })
98
96
  ```
99
97
 
100
- The above server example shows all of the encapsulation concepts outlined in the
98
+ The server example above demonstrates the encapsulation concepts from the
101
99
  original diagram:
102
100
 
103
101
  1. Each _child context_ (`authenticatedContext`, `publicContext`, and
104
- `grandchildContext`) has access to the `answer` request decorator defined in
105
- the _root context_.
102
+ `grandchildContext`) has access to the `answer` request decorator defined in
103
+ the _root context_.
106
104
  2. Only the `authenticatedContext` has access to the `@fastify/bearer-auth`
107
- plugin.
105
+ plugin.
108
106
  3. Both the `publicContext` and `grandchildContext` have access to the `foo`
109
- request decorator.
107
+ request decorator.
110
108
  4. Only the `grandchildContext` has access to the `bar` request decorator.
111
109
 
112
110
  To see this, start the server and issue requests:
@@ -125,16 +123,13 @@ To see this, start the server and issue requests:
125
123
  ## Sharing Between Contexts
126
124
  <a id="shared-context"></a>
127
125
 
128
- Notice that each context in the prior example inherits _only_ from the parent
129
- contexts. Parent contexts cannot access any entities within their descendent
130
- contexts. This default is occasionally not desired. In such cases, the
131
- encapsulation context can be broken through the usage of
132
- [fastify-plugin][fastify-plugin] such that anything registered in a descendent
133
- context is available to the containing parent context.
126
+ Each context in the prior example inherits _only_ from its parent contexts. Parent
127
+ contexts cannot access entities within their descendant contexts. If needed,
128
+ encapsulation can be broken using [fastify-plugin][fastify-plugin], making
129
+ anything registered in a descendant context available to the parent context.
134
130
 
135
- Assuming the `publicContext` needs access to the `bar` decorator defined
136
- within the `grandchildContext` in the previous example, the code can be
137
- rewritten as:
131
+ To allow `publicContext` access to the `bar` decorator in `grandchildContext`,
132
+ rewrite the code as follows:
138
133
 
139
134
  ```js
140
135
  'use strict'