教程 hono tutorial

路由基础

Hono 路由用于把 HTTP 方法和路径映射到处理函数。处理函数接收 Context,并返回一个响应。

基本路由

ts
import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => c.text('Home'))
app.get('/posts', (c) => c.json([{ id: 1, title: 'Hono 入门' }]))
app.post('/posts', async (c) => {
  const body = await c.req.json()
  return c.json({ id: 2, ...body }, 201)
})

常用方法包括:

方法 用途
app.get() 查询资源。
app.post() 创建资源或提交动作。
app.put() 整体更新资源。
app.patch() 局部更新资源。
app.delete() 删除资源。
app.all() 匹配所有 HTTP 方法。

动态参数

路径中使用 :name 定义动态参数:

ts
app.get('/users/:id', (c) => {
  const id = c.req.param('id')
  return c.json({ id })
})

多个参数也可以同时使用:

ts
app.get('/teams/:teamId/users/:userId', (c) => {
  return c.json({
    teamId: c.req.param('teamId'),
    userId: c.req.param('userId'),
  })
})

查询参数

ts
app.get('/search', (c) => {
  const keyword = c.req.query('q') ?? ''
  const page = Number(c.req.query('page') ?? '1')

  return c.json({ keyword, page })
})

如果同名查询参数出现多次,可以用 queries():

ts
app.get('/tags', (c) => {
  const tags = c.req.queries('tag') ?? []
  return c.json({ tags })
})

通配符路径

通配符适合静态资源、代理和兜底路由:

ts
app.get('/assets/*', (c) => {
  return c.text(`asset path: ${c.req.path}`)
})

注意不要把通配符路由放在过早的位置,否则可能吞掉后续更具体的路由。

模块化路由

当路由变多时,把相关路由拆成子应用:

ts
// routes/users.ts
import { Hono } from 'hono'

export const users = new Hono()

users.get('/', (c) => c.json([{ id: 1, name: 'Ada' }]))
users.get('/:id', (c) => c.json({ id: c.req.param('id') }))

在入口文件挂载:

ts
import { Hono } from 'hono'
import { users } from './routes/users'

const app = new Hono()

app.route('/users', users)

export default app

这样 /users 命中列表,/users/:id 命中详情。

路由设计建议

  • 用名词表示资源,例如 /users、/posts、/orders。
  • 使用 HTTP 方法表达动作,不要滥用 /createUser、/deleteUser。
  • 对公开 API 保持稳定路径,破坏性变更使用版本前缀,例如 /v1/users。
  • 把鉴权、中间件和验证放在路由附近,避免全局逻辑难以追踪。