# 中间件机制

URL: https://caijiao.org/hono/02-core/03-middleware
Source: docs/hono/02-core/03-middleware.md
Description: 学习 Hono 中间件的执行顺序、自定义中间件写法、路径匹配、next 调用和常见使用场景。

中间件用于处理多个路由共同需要的逻辑，例如日志、鉴权、CORS、错误包装、请求 ID、限流和响应头。

Hono 的中间件函数接收 `(c, next)`。调用 `await next()` 后，会继续执行后续中间件和路由处理函数。

## 最小中间件

```ts
app.use(async (c, next) => {
  console.log('before')
  await next()
  console.log('after')
})
```

执行顺序类似洋葱模型：

```text
middleware 1 before
middleware 2 before
handler
middleware 2 after
middleware 1 after
```

## 按路径使用中间件

```ts
app.use('/api/*', async (c, next) => {
  c.header('X-API-Version', 'v1')
  await next()
})

app.get('/api/users', (c) => {
  return c.json([])
})
```

路径越具体越容易维护。不要把所有逻辑都挂到全局中间件，否则调试时很难判断某个路由为什么被拦截。

## 自定义鉴权中间件

```ts
const auth = async (c, next) => {
  const token = c.req.header('Authorization')

  if (token !== 'Bearer secret') {
    return c.json({ message: 'Unauthorized' }, 401)
  }

  await next()
}

app.use('/admin/*', auth)

app.get('/admin/stats', (c) => {
  return c.json({ users: 100 })
})
```

中间件可以直接返回响应。这样后续路由不会继续执行。

## 请求计时

```ts
app.use(async (c, next) => {
  const started = performance.now()
  await next()
  const ms = Math.round(performance.now() - started)
  c.header('Server-Timing', `app;dur=${ms}`)
})
```

这种写法适合统一观察接口耗时。生产环境中建议把请求方法、路径、状态码和耗时写入结构化日志。

## 中间件顺序

常见顺序：

1. 请求 ID、日志、错误包装。
2. CORS、安全响应头。
3. Body 限制、鉴权、权限判断。
4. 验证器。
5. 路由处理函数。

顺序不正确会带来微妙问题。例如 CORS 应该在业务路由之前注册，否则预检请求可能无法正确响应。

## 使用内置中间件

Hono 提供了一批内置中间件：

```ts
import { cors } from 'hono/cors'
import { logger } from 'hono/logger'

app.use(logger())
app.use('/api/*', cors())
```

内置中间件大多是普通函数，返回可传给 `app.use()` 的中间件。你可以先用官方中间件解决通用问题，再为项目补充自定义逻辑。
