# 插件示例：中间件

URL: https://caijiao.org/fastify/plugins/middleware-example
Source: docs/fastify/plugins/middleware-example.md
Description: 介绍如何在 Fastify 中编写和使用中间件插件，包括请求处理、日志记录、跨域支持等功能。

在 [Fastify](/fastify/) 中，中间件通常用于处理请求、响应生命周期中的某些操作，例如日志记录、跨域处理、请求验证等。Fastify 的中间件机制基于生命周期钩子实现，提供高效、灵活的处理方式。

## 中间件基本概念

Fastify 的中间件是通过钩子（hooks）来实现的。钩子允许在请求生命周期的不同阶段进行操作。

常见钩子类型：

- **onRequest**：在请求到达路由前触发。
- **preHandler**：在路由处理函数前触发。
- **onResponse**：在响应发送前触发。

## 示例：编写日志记录中间件

日志记录是常见的中间件需求。可以使用 `onRequest` 钩子记录每个请求的详细信息。

```js
async function logMiddleware(fastify, options) {
  fastify.addHook('onRequest', (request, reply, done) => {
    console.log(`请求 URL: ${request.url}, 请求方法: ${request.method}`);
    done();
  });
}

module.exports = logMiddleware;
```

注册插件：

```js
const fastify = require('fastify')();
fastify.register(require('./logMiddleware'));
```

每个请求都会输出日志信息，方便开发与调试。

## 示例：跨域支持中间件

跨域资源共享（CORS）是另一常见的中间件需求。可以通过中间件在请求到达路由前添加 CORS 头信息。

```js
async function corsMiddleware(fastify, options) {
  fastify.addHook('onRequest', (request, reply, done) => {
    reply.header('Access-Control-Allow-Origin', '*');
    reply.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
    reply.header('Access-Control-Allow-Headers', 'Content-Type');
    done();
  });
}

module.exports = corsMiddleware;
```

注册插件后，所有请求都会带上 CORS 头信息。

## 示例：自定义验证中间件

可以在请求处理之前进行自定义验证，例如请求参数验证、用户认证等。

```js
async function authMiddleware(fastify, options) {
  fastify.addHook('preHandler', async (request, reply) => {
    if (!request.headers['authorization']) {
      reply.status(401).send({ error: 'Unauthorized' });
    }
  });
}

module.exports = authMiddleware;
```

此中间件会在每个请求到达路由处理前，检查是否有有效的授权头。

## 中间件与插件的区别

Fastify 的插件系统与传统的中间件机制有所不同，插件不仅可以处理请求，还可以注册路由、装饰器、钩子等。与传统的中间件相比，Fastify 插件更加模块化和隔离，易于维护和扩展。

### 插件结构

- 插件是一个函数，接收 `fastify` 实例和 `options` 参数。
- 插件可以是同步或异步的。
- 插件可以注册钩子、路由、装饰器等。
  
中间件在 Fastify 中实际上是通过钩子来实现的，因此可以把中间件看作是 Fastify 插件的一部分。

## 总结

通过 [Fastify](/fastify/) 的中间件插件机制，我们可以灵活地扩展和处理请求与响应。例如，日志记录、CORS 处理、身份验证等功能都可以通过插件来实现，并且能确保应用程序的模块化和可维护性。
