教程 hono tutorial

中间件机制

中间件用于处理多个路由共同需要的逻辑,例如日志、鉴权、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() 的中间件。你可以先用官方中间件解决通用问题,再为项目补充自定义逻辑。