Lesson 13 / 32
Lifecycle Hooks
Run code at lifecycle points such as onRequest, preHandler and onSend, globally or per route.
Hook points in Fastify
Per request, hooks run in this order: onRequest, preParsing, preValidation, preHandler, then preSerialization, onSend and onResponse. Use them for middleware-like logic.
Common hooks
Register hooks globally or per-route. They run in sequence and can modify request/response.
// Global hook: log every request
fastify.addHook('onRequest', async (request) => {
request.startTime = Date.now();
request.log.info(`${request.method} ${request.url}`);
});
// Global hook: add timing header
fastify.addHook('onSend', async (request, reply, payload) => {
reply.header('X-Response-Time', `${Date.now() - request.startTime}ms`);
return payload;
});
// Per-route hook: validate auth token
fastify.get('/admin',
{ onRequest: async (req, reply) => {
const token = req.headers.authorization;
if (!token) return reply.status(401).send({ error: 'Unauthorized' });
}},
async () => ({ message: 'Admin access granted' })
);Quick check
Quick check: Which hook runs after a request is validated but before the handler?
- preHandler
- onRequest
- preValidation
- onSend
Answer
preHandler — preHandler runs after validation and before the route handler. Use it for auth checks or last-minute data preparation.
An onRequest hook
Hooks run at fixed points in the lifecycle.
onRequestruns first, before parsing the body.- Use
asyncand just return, or calldone()in callback style, never both. - Here we reject requests lacking a header.
const fastify = require('fastify')();
fastify.addHook('onRequest', async (request, reply) => {
if (!request.headers['x-api-key']) {
reply.code(401).send({ error: 'missing key' });
}
});
fastify.get('/', async () => ({ ok: true }));
fastify.listen({ port: 3000 });Quick check
Quick check: Which hook runs before the body is parsed?
- preHandler
- onRequest
- onSend
Answer
onRequest — Order: onRequest, preParsing, preValidation, preHandler. The body is available from preValidation onward.