# Lifecycle Hooks — Fastify: Building High-Performance Node.js APIs

Source: https://www.skillbyai.com/en/fastify/ff-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.

```javascript
// 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

**Quiz:** Which hook runs after a request is validated but before the handler?

- [x] 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.

- `onRequest` runs first, before parsing the body.
- Use `async` and just return, or call `done()` in callback style, never both.
- Here we reject requests lacking a header.

```js
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

**Quiz:** Which hook runs before the body is parsed?

- [ ] preHandler
- [x] onRequest
- [ ] onSend

*Answer:* onRequest. Order: onRequest, preParsing, preValidation, preHandler. The body is available from preValidation onward.
