You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					696 lines
				
				20 KiB
			
		
		
			
		
	
	
					696 lines
				
				20 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								<h1 align="center">Fastify</h1>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Hooks
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Hooks are registered with the `fastify.addHook` method and allow you to listen
							 | 
						||
| 
								 | 
							
								to specific events in the application or request/response lifecycle. You have to
							 | 
						||
| 
								 | 
							
								register a hook before the event is triggered, otherwise, the event is lost.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								By using hooks you can interact directly with the lifecycle of Fastify. There
							 | 
						||
| 
								 | 
							
								are Request/Reply hooks and application hooks:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- [Request/Reply Hooks](#requestreply-hooks)
							 | 
						||
| 
								 | 
							
								  - [onRequest](#onrequest)
							 | 
						||
| 
								 | 
							
								  - [preParsing](#preparsing)
							 | 
						||
| 
								 | 
							
								  - [preValidation](#prevalidation)
							 | 
						||
| 
								 | 
							
								  - [preHandler](#prehandler)
							 | 
						||
| 
								 | 
							
								  - [preSerialization](#preserialization)
							 | 
						||
| 
								 | 
							
								  - [onError](#onerror)
							 | 
						||
| 
								 | 
							
								  - [onSend](#onsend)
							 | 
						||
| 
								 | 
							
								  - [onResponse](#onresponse)
							 | 
						||
| 
								 | 
							
								  - [onTimeout](#ontimeout)
							 | 
						||
| 
								 | 
							
								  - [Manage Errors from a hook](#manage-errors-from-a-hook)
							 | 
						||
| 
								 | 
							
								  - [Respond to a request from a hook](#respond-to-a-request-from-a-hook)
							 | 
						||
| 
								 | 
							
								- [Application Hooks](#application-hooks)
							 | 
						||
| 
								 | 
							
								  - [onReady](#onready)
							 | 
						||
| 
								 | 
							
								  - [onClose](#onclose)
							 | 
						||
| 
								 | 
							
								  - [onRoute](#onroute)
							 | 
						||
| 
								 | 
							
								  - [onRegister](#onregister)
							 | 
						||
| 
								 | 
							
								- [Scope](#scope)
							 | 
						||
| 
								 | 
							
								- [Route level hooks](#route-level-hooks)
							 | 
						||
| 
								 | 
							
								- [Diagnostics Channel Hooks](#diagnostics-channel-hooks)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								**Notice:** the `done` callback is not available when using `async`/`await` or
							 | 
						||
| 
								 | 
							
								returning a `Promise`. If you do invoke a `done` callback in this situation
							 | 
						||
| 
								 | 
							
								unexpected behavior may occur, e.g. duplicate invocation of handlers.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Request/Reply Hooks
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								[Request](./Request.md) and [Reply](./Reply.md) are the core Fastify objects.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								`done` is the function to continue with the [lifecycle](./Lifecycle.md).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								It is easy to understand where each hook is executed by looking at the
							 | 
						||
| 
								 | 
							
								[lifecycle page](./Lifecycle.md).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Hooks are affected by Fastify's encapsulation, and can thus be applied to
							 | 
						||
| 
								 | 
							
								selected routes. See the [Scopes](#scope) section for more information.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								There are eight different hooks that you can use in Request/Reply *(in order of
							 | 
						||
| 
								 | 
							
								execution)*:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### onRequest
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onRequest', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  // Some code
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								Or `async/await`:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onRequest', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								  // Some code
							 | 
						||
| 
								 | 
							
								  await asyncMethod()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								**Notice:** in the [onRequest](#onrequest) hook, `request.body` will always be
							 | 
						||
| 
								 | 
							
								`null`, because the body parsing happens before the
							 | 
						||
| 
								 | 
							
								[preValidation](#prevalidation) hook.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### preParsing
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If you are using the `preParsing` hook, you can transform the request payload
							 | 
						||
| 
								 | 
							
								stream before it is parsed. It receives the request and reply objects as other
							 | 
						||
| 
								 | 
							
								hooks, and a stream with the current request payload.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If it returns a value (via `return` or via the callback function), it must
							 | 
						||
| 
								 | 
							
								return a stream.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								For instance, you can uncompress the request body:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('preParsing', (request, reply, payload, done) => {
							 | 
						||
| 
								 | 
							
								  // Some code
							 | 
						||
| 
								 | 
							
								  done(null, newPayload)
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								Or `async/await`:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('preParsing', async (request, reply, payload) => {
							 | 
						||
| 
								 | 
							
								  // Some code
							 | 
						||
| 
								 | 
							
								  await asyncMethod()
							 | 
						||
| 
								 | 
							
								  return newPayload
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								**Notice:** in the [preParsing](#preparsing) hook, `request.body` will always be
							 | 
						||
| 
								 | 
							
								`null`, because the body parsing happens before the
							 | 
						||
| 
								 | 
							
								[preValidation](#prevalidation) hook.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								**Notice:** you should also add a `receivedEncodedLength` property to the
							 | 
						||
| 
								 | 
							
								returned stream. This property is used to correctly match the request payload
							 | 
						||
| 
								 | 
							
								with the `Content-Length` header value. Ideally, this property should be updated
							 | 
						||
| 
								 | 
							
								on each received chunk.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								**Notice**: The old syntaxes `function(request, reply, done)` and `async
							 | 
						||
| 
								 | 
							
								function(request, reply)` for the parser are still supported but they are
							 | 
						||
| 
								 | 
							
								deprecated.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### preValidation
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If you are using the `preValidation` hook, you can change the payload before it
							 | 
						||
| 
								 | 
							
								is validated. For example:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('preValidation', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  request.body = { ...request.body, importantKey: 'randomString' }
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								Or `async/await`:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('preValidation', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								  const importantKey = await generateRandomString()
							 | 
						||
| 
								 | 
							
								  request.body = { ...request.body, importantKey }
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### preHandler
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('preHandler', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  // some code
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								Or `async/await`:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('preHandler', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								  // Some code
							 | 
						||
| 
								 | 
							
								  await asyncMethod()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								### preSerialization
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If you are using the `preSerialization` hook, you can change (or replace) the
							 | 
						||
| 
								 | 
							
								payload before it is serialized. For example:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('preSerialization', (request, reply, payload, done) => {
							 | 
						||
| 
								 | 
							
								  const err = null
							 | 
						||
| 
								 | 
							
								  const newPayload = { wrapped: payload }
							 | 
						||
| 
								 | 
							
								  done(err, newPayload)
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								Or `async/await`:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('preSerialization', async (request, reply, payload) => {
							 | 
						||
| 
								 | 
							
								  return { wrapped: payload }
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Note: the hook is NOT called if the payload is a `string`, a `Buffer`, a
							 | 
						||
| 
								 | 
							
								`stream`, or `null`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### onError
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onError', (request, reply, error, done) => {
							 | 
						||
| 
								 | 
							
								  // Some code
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								Or `async/await`:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onError', async (request, reply, error) => {
							 | 
						||
| 
								 | 
							
								  // Useful for custom error logging
							 | 
						||
| 
								 | 
							
								  // You should not use this hook to update the error
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								This hook is useful if you need to do some custom error logging or add some
							 | 
						||
| 
								 | 
							
								specific header in case of error.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								It is not intended for changing the error, and calling `reply.send` will throw
							 | 
						||
| 
								 | 
							
								an exception.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This hook will be executed only after the `customErrorHandler` has been
							 | 
						||
| 
								 | 
							
								executed, and only if the `customErrorHandler` sends an error back to the user
							 | 
						||
| 
								 | 
							
								*(Note that the default `customErrorHandler` always sends the error back to the
							 | 
						||
| 
								 | 
							
								user)*.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								**Notice:** unlike the other hooks, pass an error to the `done` function is not
							 | 
						||
| 
								 | 
							
								supported.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### onSend
							 | 
						||
| 
								 | 
							
								If you are using the `onSend` hook, you can change the payload. For example:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onSend', (request, reply, payload, done) => {
							 | 
						||
| 
								 | 
							
								  const err = null;
							 | 
						||
| 
								 | 
							
								  const newPayload = payload.replace('some-text', 'some-new-text')
							 | 
						||
| 
								 | 
							
								  done(err, newPayload)
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								Or `async/await`:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onSend', async (request, reply, payload) => {
							 | 
						||
| 
								 | 
							
								  const newPayload = payload.replace('some-text', 'some-new-text')
							 | 
						||
| 
								 | 
							
								  return newPayload
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								You can also clear the payload to send a response with an empty body by
							 | 
						||
| 
								 | 
							
								replacing the payload with `null`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onSend', (request, reply, payload, done) => {
							 | 
						||
| 
								 | 
							
								  reply.code(304)
							 | 
						||
| 
								 | 
							
								  const newPayload = null
							 | 
						||
| 
								 | 
							
								  done(null, newPayload)
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								> You can also send an empty body by replacing the payload with the empty string
							 | 
						||
| 
								 | 
							
								> `''`, but be aware that this will cause the `Content-Length` header to be set
							 | 
						||
| 
								 | 
							
								> to `0`, whereas the `Content-Length` header will not be set if the payload is
							 | 
						||
| 
								 | 
							
								> `null`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Note: If you change the payload, you may only change it to a `string`, a
							 | 
						||
| 
								 | 
							
								`Buffer`, a `stream`, or `null`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### onResponse
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onResponse', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  // Some code
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								Or `async/await`:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onResponse', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								  // Some code
							 | 
						||
| 
								 | 
							
								  await asyncMethod()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The `onResponse` hook is executed when a response has been sent, so you will not
							 | 
						||
| 
								 | 
							
								be able to send more data to the client. It can however be useful for sending
							 | 
						||
| 
								 | 
							
								data to external services, for example, to gather statistics.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### onTimeout
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onTimeout', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  // Some code
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								Or `async/await`:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onTimeout', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								  // Some code
							 | 
						||
| 
								 | 
							
								  await asyncMethod()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								`onTimeout` is useful if you need to monitor the request timed out in your
							 | 
						||
| 
								 | 
							
								service (if the `connectionTimeout` property is set on the Fastify instance).
							 | 
						||
| 
								 | 
							
								The `onTimeout` hook is executed when a request is timed out and the HTTP socket
							 | 
						||
| 
								 | 
							
								has been hanged up. Therefore, you will not be able to send data to the client.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Manage Errors from a hook
							 | 
						||
| 
								 | 
							
								If you get an error during the execution of your hook, just pass it to `done()`
							 | 
						||
| 
								 | 
							
								and Fastify will automatically close the request and send the appropriate error
							 | 
						||
| 
								 | 
							
								code to the user.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onRequest', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  done(new Error('Some error'))
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If you want to pass a custom error code to the user, just use `reply.code()`:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('preHandler', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  reply.code(400)
							 | 
						||
| 
								 | 
							
								  done(new Error('Some error'))
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								*The error will be handled by [`Reply`](./Reply.md#errors).*
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Or if you're using `async/await` you can just throw an error:
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onResponse', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								  throw new Error('Some error')
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### Respond to a request from a hook
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If needed, you can respond to a request before you reach the route handler, for
							 | 
						||
| 
								 | 
							
								example when implementing an authentication hook. Replying from a hook implies
							 | 
						||
| 
								 | 
							
								that the hook chain is __stopped__ and the rest of the hooks and handlers are
							 | 
						||
| 
								 | 
							
								not executed. If the hook is using the callback approach, i.e. it is not an
							 | 
						||
| 
								 | 
							
								`async` function or it returns a `Promise`, it is as simple as calling
							 | 
						||
| 
								 | 
							
								`reply.send()` and avoiding calling the callback. If the hook is `async`,
							 | 
						||
| 
								 | 
							
								`reply.send()` __must__ be called _before_ the function returns or the promise
							 | 
						||
| 
								 | 
							
								resolves, otherwise, the request will proceed. When `reply.send()` is called
							 | 
						||
| 
								 | 
							
								outside of the promise chain, it is important to `return reply` otherwise the
							 | 
						||
| 
								 | 
							
								request will be executed twice.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								It is important to __not mix callbacks and `async`/`Promise`__, otherwise the
							 | 
						||
| 
								 | 
							
								hook chain will be executed twice.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If you are using `onRequest` or `preHandler` use `reply.send`.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onRequest', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  reply.send('Early response')
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Works with async functions too
							 | 
						||
| 
								 | 
							
								fastify.addHook('preHandler', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								  await something()
							 | 
						||
| 
								 | 
							
								  reply.send({ hello: 'world' })
							 | 
						||
| 
								 | 
							
								  return reply // optional in this case, but it is a good practice
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If you want to respond with a stream, you should avoid using an `async` function
							 | 
						||
| 
								 | 
							
								for the hook. If you must use an `async` function, your code will need to follow
							 | 
						||
| 
								 | 
							
								the pattern in
							 | 
						||
| 
								 | 
							
								[test/hooks-async.js](https://github.com/fastify/fastify/blob/94ea67ef2d8dce8a955d510cd9081aabd036fa85/test/hooks-async.js#L269-L275).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onRequest', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  const stream = fs.createReadStream('some-file', 'utf8')
							 | 
						||
| 
								 | 
							
								  reply.send(stream)
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If you are sending a response without `await` on it, make sure to always `return
							 | 
						||
| 
								 | 
							
								reply`:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('preHandler', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								  setImmediate(() => { reply.send('hello') })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // This is needed to signal the handler to wait for a response
							 | 
						||
| 
								 | 
							
								  // to be sent outside of the promise chain
							 | 
						||
| 
								 | 
							
								  return reply
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.addHook('preHandler', async (request, reply) => {
							 | 
						||
| 
								 | 
							
								  // the @fastify/static plugin will send a file asynchronously,
							 | 
						||
| 
								 | 
							
								  // so we should return reply
							 | 
						||
| 
								 | 
							
								  reply.sendFile('myfile')
							 | 
						||
| 
								 | 
							
								  return reply
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Application Hooks
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								You can hook into the application-lifecycle as well.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- [onReady](#onready)
							 | 
						||
| 
								 | 
							
								- [onClose](#onclose)
							 | 
						||
| 
								 | 
							
								- [onRoute](#onroute)
							 | 
						||
| 
								 | 
							
								- [onRegister](#onregister)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### onReady
							 | 
						||
| 
								 | 
							
								Triggered before the server starts listening for requests and when `.ready()` is
							 | 
						||
| 
								 | 
							
								invoked. It cannot change the routes or add new hooks. Registered hook functions
							 | 
						||
| 
								 | 
							
								are executed serially. Only after all `onReady` hook functions have completed
							 | 
						||
| 
								 | 
							
								will the server start listening for requests. Hook functions accept one
							 | 
						||
| 
								 | 
							
								argument: a callback, `done`, to be invoked after the hook function is complete.
							 | 
						||
| 
								 | 
							
								Hook functions are invoked with `this` bound to the associated Fastify instance.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// callback style
							 | 
						||
| 
								 | 
							
								fastify.addHook('onReady', function (done) {
							 | 
						||
| 
								 | 
							
								  // Some code
							 | 
						||
| 
								 | 
							
								  const err = null;
							 | 
						||
| 
								 | 
							
								  done(err)
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// or async/await style
							 | 
						||
| 
								 | 
							
								fastify.addHook('onReady', async function () {
							 | 
						||
| 
								 | 
							
								  // Some async code
							 | 
						||
| 
								 | 
							
								  await loadCacheFromDatabase()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### onClose
							 | 
						||
| 
								 | 
							
								<a id="on-close"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Triggered when `fastify.close()` is invoked to stop the server. It is useful
							 | 
						||
| 
								 | 
							
								when [plugins](./Plugins.md) need a "shutdown" event, for example, to close an
							 | 
						||
| 
								 | 
							
								open connection to a database.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The hook function takes the Fastify instance as a first argument, 
							 | 
						||
| 
								 | 
							
								and a `done` callback for synchronous hook functions.
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								// callback style
							 | 
						||
| 
								 | 
							
								fastify.addHook('onClose', (instance, done) => {
							 | 
						||
| 
								 | 
							
								  // Some code
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// or async/await style
							 | 
						||
| 
								 | 
							
								fastify.addHook('onClose', async (instance) => {
							 | 
						||
| 
								 | 
							
								  // Some async code
							 | 
						||
| 
								 | 
							
								  await closeDatabaseConnections()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### onRoute
							 | 
						||
| 
								 | 
							
								<a id="on-route"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Triggered when a new route is registered. Listeners are passed a `routeOptions`
							 | 
						||
| 
								 | 
							
								object as the sole parameter. The interface is synchronous, and, as such, the
							 | 
						||
| 
								 | 
							
								listeners are not passed a callback. This hook is encapsulated.
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onRoute', (routeOptions) => {
							 | 
						||
| 
								 | 
							
								  //Some code
							 | 
						||
| 
								 | 
							
								  routeOptions.method
							 | 
						||
| 
								 | 
							
								  routeOptions.schema
							 | 
						||
| 
								 | 
							
								  routeOptions.url // the complete URL of the route, it will include the prefix if any
							 | 
						||
| 
								 | 
							
								  routeOptions.path // `url` alias
							 | 
						||
| 
								 | 
							
								  routeOptions.routePath // the URL of the route without the prefix
							 | 
						||
| 
								 | 
							
								  routeOptions.bodyLimit
							 | 
						||
| 
								 | 
							
								  routeOptions.logLevel
							 | 
						||
| 
								 | 
							
								  routeOptions.logSerializers
							 | 
						||
| 
								 | 
							
								  routeOptions.prefix
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								If you are authoring a plugin and you need to customize application routes, like
							 | 
						||
| 
								 | 
							
								modifying the options or adding new route hooks, this is the right place.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onRoute', (routeOptions) => {
							 | 
						||
| 
								 | 
							
								  function onPreSerialization(request, reply, payload, done) {
							 | 
						||
| 
								 | 
							
								    // Your code
							 | 
						||
| 
								 | 
							
								    done(null, payload)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								  // preSerialization can be an array or undefined
							 | 
						||
| 
								 | 
							
								  routeOptions.preSerialization = [...(routeOptions.preSerialization || []), onPreSerialization]
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								### onRegister
							 | 
						||
| 
								 | 
							
								<a id="on-register"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Triggered when a new plugin is registered and a new encapsulation context is
							 | 
						||
| 
								 | 
							
								created. The hook will be executed **before** the registered code.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This hook can be useful if you are developing a plugin that needs to know when a
							 | 
						||
| 
								 | 
							
								plugin context is formed, and you want to operate in that specific context, thus
							 | 
						||
| 
								 | 
							
								this hook is encapsulated.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								**Note:** This hook will not be called if a plugin is wrapped inside
							 | 
						||
| 
								 | 
							
								[`fastify-plugin`](https://github.com/fastify/fastify-plugin).
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.decorate('data', [])
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.register(async (instance, opts) => {
							 | 
						||
| 
								 | 
							
								  instance.data.push('hello')
							 | 
						||
| 
								 | 
							
								  console.log(instance.data) // ['hello']
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  instance.register(async (instance, opts) => {
							 | 
						||
| 
								 | 
							
								    instance.data.push('world')
							 | 
						||
| 
								 | 
							
								    console.log(instance.data) // ['hello', 'world']
							 | 
						||
| 
								 | 
							
								  }, { prefix: '/hola' })
							 | 
						||
| 
								 | 
							
								}, { prefix: '/ciao' })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.register(async (instance, opts) => {
							 | 
						||
| 
								 | 
							
								  console.log(instance.data) // []
							 | 
						||
| 
								 | 
							
								}, { prefix: '/hello' })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.addHook('onRegister', (instance, opts) => {
							 | 
						||
| 
								 | 
							
								  // Create a new array from the old one
							 | 
						||
| 
								 | 
							
								  // but without keeping the reference
							 | 
						||
| 
								 | 
							
								  // allowing the user to have encapsulated
							 | 
						||
| 
								 | 
							
								  // instances of the `data` property
							 | 
						||
| 
								 | 
							
								  instance.data = instance.data.slice()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  // the options of the new registered instance
							 | 
						||
| 
								 | 
							
								  console.log(opts.prefix)
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Scope
							 | 
						||
| 
								 | 
							
								<a id="scope"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Except for [onClose](#onclose), all hooks are encapsulated. This means that you
							 | 
						||
| 
								 | 
							
								can decide where your hooks should run by using `register` as explained in the
							 | 
						||
| 
								 | 
							
								[plugins guide](../Guides/Plugins-Guide.md). If you pass a function, that
							 | 
						||
| 
								 | 
							
								function is bound to the right Fastify context and from there you have full
							 | 
						||
| 
								 | 
							
								access to the Fastify API.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onRequest', function (request, reply, done) {
							 | 
						||
| 
								 | 
							
								  const self = this // Fastify context
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Note that the Fastify context in each hook is the same as the plugin where the
							 | 
						||
| 
								 | 
							
								route was registered, for example:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onRequest', async function (req, reply) {
							 | 
						||
| 
								 | 
							
								  if (req.raw.url === '/nested') {
							 | 
						||
| 
								 | 
							
								    assert.strictEqual(this.foo, 'bar')
							 | 
						||
| 
								 | 
							
								  } else {
							 | 
						||
| 
								 | 
							
								    assert.strictEqual(this.foo, undefined)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.get('/', async function (req, reply) {
							 | 
						||
| 
								 | 
							
								  assert.strictEqual(this.foo, undefined)
							 | 
						||
| 
								 | 
							
								  return { hello: 'world' }
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.register(async function plugin (fastify, opts) {
							 | 
						||
| 
								 | 
							
								  fastify.decorate('foo', 'bar')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.get('/nested', async function (req, reply) {
							 | 
						||
| 
								 | 
							
								    assert.strictEqual(this.foo, 'bar')
							 | 
						||
| 
								 | 
							
								    return { hello: 'world' }
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Warn: if you declare the function with an [arrow
							 | 
						||
| 
								 | 
							
								function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions),
							 | 
						||
| 
								 | 
							
								the `this` will not be Fastify, but the one of the current scope.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Route level hooks
							 | 
						||
| 
								 | 
							
								<a id="route-hooks"></a>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								You can declare one or more custom lifecycle hooks ([onRequest](#onrequest),
							 | 
						||
| 
								 | 
							
								[onResponse](#onresponse), [preParsing](#preparsing),
							 | 
						||
| 
								 | 
							
								[preValidation](#prevalidation), [preHandler](#prehandler),
							 | 
						||
| 
								 | 
							
								[preSerialization](#preserialization), [onSend](#onsend),
							 | 
						||
| 
								 | 
							
								[onTimeout](#ontimeout), and [onError](#onerror)) hook(s) that will be
							 | 
						||
| 
								 | 
							
								**unique** for the route. If you do so, those hooks are always executed as the
							 | 
						||
| 
								 | 
							
								last hook in their category.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This can be useful if you need to implement authentication, where the
							 | 
						||
| 
								 | 
							
								[preParsing](#preparsing) or [preValidation](#prevalidation) hooks are exactly
							 | 
						||
| 
								 | 
							
								what you need. Multiple route-level hooks can also be specified as an array.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								fastify.addHook('onRequest', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  // Your code
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.addHook('onResponse', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  // your code
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.addHook('preParsing', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  // Your code
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.addHook('preValidation', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  // Your code
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.addHook('preHandler', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  // Your code
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.addHook('preSerialization', (request, reply, payload, done) => {
							 | 
						||
| 
								 | 
							
								  // Your code
							 | 
						||
| 
								 | 
							
								  done(null, payload)
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.addHook('onSend', (request, reply, payload, done) => {
							 | 
						||
| 
								 | 
							
								  // Your code
							 | 
						||
| 
								 | 
							
								  done(null, payload)
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.addHook('onTimeout', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								  // Your code
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.addHook('onError', (request, reply, error, done) => {
							 | 
						||
| 
								 | 
							
								  // Your code
							 | 
						||
| 
								 | 
							
								  done()
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								fastify.route({
							 | 
						||
| 
								 | 
							
								  method: 'GET',
							 | 
						||
| 
								 | 
							
								  url: '/',
							 | 
						||
| 
								 | 
							
								  schema: { ... },
							 | 
						||
| 
								 | 
							
								  onRequest: function (request, reply, done) {
							 | 
						||
| 
								 | 
							
								    // This hook will always be executed after the shared `onRequest` hooks
							 | 
						||
| 
								 | 
							
								    done()
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  onResponse: function (request, reply, done) {
							 | 
						||
| 
								 | 
							
								    // this hook will always be executed after the shared `onResponse` hooks
							 | 
						||
| 
								 | 
							
								    done()
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  preParsing: function (request, reply, done) {
							 | 
						||
| 
								 | 
							
								    // This hook will always be executed after the shared `preParsing` hooks
							 | 
						||
| 
								 | 
							
								    done()
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  preValidation: function (request, reply, done) {
							 | 
						||
| 
								 | 
							
								    // This hook will always be executed after the shared `preValidation` hooks
							 | 
						||
| 
								 | 
							
								    done()
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  preHandler: function (request, reply, done) {
							 | 
						||
| 
								 | 
							
								    // This hook will always be executed after the shared `preHandler` hooks
							 | 
						||
| 
								 | 
							
								    done()
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  // // Example with an array. All hooks support this syntax.
							 | 
						||
| 
								 | 
							
								  //
							 | 
						||
| 
								 | 
							
								  // preHandler: [function (request, reply, done) {
							 | 
						||
| 
								 | 
							
								  //   // This hook will always be executed after the shared `preHandler` hooks
							 | 
						||
| 
								 | 
							
								  //   done()
							 | 
						||
| 
								 | 
							
								  // }],
							 | 
						||
| 
								 | 
							
								  preSerialization: (request, reply, payload, done) => {
							 | 
						||
| 
								 | 
							
								    // This hook will always be executed after the shared `preSerialization` hooks
							 | 
						||
| 
								 | 
							
								    done(null, payload)
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  onSend: (request, reply, payload, done) => {
							 | 
						||
| 
								 | 
							
								    // This hook will always be executed after the shared `onSend` hooks
							 | 
						||
| 
								 | 
							
								    done(null, payload)
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  onTimeout: (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								    // This hook will always be executed after the shared `onTimeout` hooks
							 | 
						||
| 
								 | 
							
								    done()
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  onError: (request, reply, error, done) => {
							 | 
						||
| 
								 | 
							
								    // This hook will always be executed after the shared `onError` hooks
							 | 
						||
| 
								 | 
							
								    done()
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  handler: function (request, reply) {
							 | 
						||
| 
								 | 
							
								    reply.send({ hello: 'world' })
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								**Note**: both options also accept an array of functions.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								## Diagnostics Channel Hooks
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								> **Note:** The `diagnostics_channel` is currently experimental on Node.js, so
							 | 
						||
| 
								 | 
							
								> its API is subject to change even in semver-patch releases of Node.js. For
							 | 
						||
| 
								 | 
							
								> versions of Node.js supported by Fastify where `diagnostics_channel` is
							 | 
						||
| 
								 | 
							
								> unavailable, the hook will use the
							 | 
						||
| 
								 | 
							
								> [polyfill](https://www.npmjs.com/package/diagnostics_channel) if it is
							 | 
						||
| 
								 | 
							
								> available. Otherwise this feature will not be present.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Currently, one
							 | 
						||
| 
								 | 
							
								[`diagnostics_channel`](https://nodejs.org/api/diagnostics_channel.html) publish
							 | 
						||
| 
								 | 
							
								event, `'fastify.initialization'`, happens at initialization time. The Fastify
							 | 
						||
| 
								 | 
							
								instance is passed into the hook as a property of the object passed in. At this
							 | 
						||
| 
								 | 
							
								point, the instance can be interacted with to add hooks, plugins, routes or any
							 | 
						||
| 
								 | 
							
								other sort of modification.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								For example, a tracing package might do something like the following (which is,
							 | 
						||
| 
								 | 
							
								of course, a simplification). This would be in a file loaded in the
							 | 
						||
| 
								 | 
							
								initialization of the tracking package, in the typical "require instrumentation
							 | 
						||
| 
								 | 
							
								tools first" fashion.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								```js
							 | 
						||
| 
								 | 
							
								const tracer = /* retrieved from elsehwere in the package */
							 | 
						||
| 
								 | 
							
								const dc = require('diagnostics_channel')
							 | 
						||
| 
								 | 
							
								const channel = dc.channel('fastify.initialization')
							 | 
						||
| 
								 | 
							
								const spans = new WeakMap()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								channel.subscribe(function ({ fastify }) {
							 | 
						||
| 
								 | 
							
								  fastify.addHook('onRequest', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								    const span = tracer.startSpan('fastify.request')
							 | 
						||
| 
								 | 
							
								    spans.set(request, span)
							 | 
						||
| 
								 | 
							
								    done()
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  fastify.addHook('onResponse', (request, reply, done) => {
							 | 
						||
| 
								 | 
							
								    const span = spans.get(request)
							 | 
						||
| 
								 | 
							
								    span.finish()
							 | 
						||
| 
								 | 
							
								    done()
							 | 
						||
| 
								 | 
							
								  })
							 | 
						||
| 
								 | 
							
								})
							 | 
						||
| 
								 | 
							
								```
							 |