Fastify hooks allow us to listen to specific events in the application or in the request response cycle. One of the most useful hooks is the Fastify PreHandler Hook.

Fastify PreHandler Hook is one of the hooks in the request reply cycle. It allows us to execute a piece of code before the incoming request is handled by a request handler. This makes it easy to perform some repeatable action for every request.

1 – Fastify PreHandler Hook Example

Let us assume that we want to log every incoming request. The ideal approach to accomplish this is by using the prehandler hook.

See below example:

const fastify = require('fastify')({
    logger: true
})

fastify.decorate('logRequest', (request) => { 
    fastify.log.info(`The incoming request is: ${JSON.stringify(request.headers)}`)
})

fastify.addHook('preHandler', (request, reply, done) => {
    fastify.logRequest(request)
    done()
})

fastify.get('/', function(request, reply) {
    reply.send({ hello: 'world' })
})

fastify.listen(3000, function(err, address) {
    if (err) {
        fastify.log.error(err)
        process.exit(1)
    }
})

We decorate our Fastify instance with a utility function. We call this function logRequest. It simply logs the request headers using the in-built Fastify logger. You can read more Fastify decorate API in this detailed post on Fastify Plugin System.

Next, we use the addHook() API to register the preHandler hook. The preHandler hook gets access to the request and reply objects. We use the logRequest utility to log the request headers.

Lastly, we have an actual endpoint that returns a typical hello world object. Basically, every time there is a request to the root endpoint, the preHandler hook will kick in and log the request headers. In fact, even if we add any other route handlers in the same context, the incoming requests to those endpoints will go through the preHandler hook.

In other words, hooks are a great way to reduce repeatability in your coding. It is also scalable for growing applications.

2 – Fastify PreHandler for Route Subset

It is also a common requirement to have a particular functionality to be executed for a subset of routes. It is also possible to achieve this using Fastify hooks.

See below example:

fastify.register((fastify, options, done) => {
    fastify.decorate('sayGreeting', () => {
        fastify.log.info("Welcome to the admin routes");
    })

    fastify.addHook('preHandler', (request, reply, done) => {
        fastify.sayGreeting();
        done();
    })

    fastify.get('/admin', (request, reply) => {
        reply.send({ hello: 'admin' })
    })

    done()
})

Basically, here we are relying on the concept of encapsulation in Fastify. We use the register() API to create a new context. With this context, we decorate our Fastify instance with another utility function sayGreeting(). This function simply logs a welcome message.

Then, we use the addHook() API to register a preHandler hook. Note that new hook will be applicable only within this Fastify context. Lastly, we declare a route with path as /admin.

In this case, whenever there is a request to /admin, the sayGreeting() function will be triggered. However, the same won’t be be applicable to the root path.

3 – Conclusion

With this, we have successfully understood the behaviour of Fastify PreHandler hook. It is particularly useful for repeatable tasks for every incoming request such as logging the request or perform authentication.

Want to build a bigger application with Fastify? Check out this post on creating a REST API using Fastify and Postgres.

If you have any comments or queries about this post, please feel free to mention them in the comments section below.

Categories: BlogFastify

Saurabh Dashora

Saurabh is a Software Architect with over 12 years of experience. He has worked on large-scale distributed systems across various domains and organizations. He is also a passionate Technical Writer and loves sharing knowledge in the community.

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *