创建时间: 2026-04-08最后更新: 2026-04-18

1. 为什么需要数据校验

用户提交的数据永远不可信。少一个字段、类型不对、格式错误,这些情况每天都在发生。

手动校验长这样:

index.ts
01
app.post('/users', async (c) => {
02
const body = await c.req.json()
03
04
if (!body.name || typeof body.name !== 'string') {
05
return c.json({ error: 'name is required' }, 400)
06
}
07
if (!body.email || typeof body.email !== 'string') {
08
return c.json({ error: 'email is required' }, 400)
09
}
10
if (!body.email.includes('@')) {
11
return c.json({ error: 'invalid email' }, 400)
12
}
13
14
// 终于可以写业务逻辑了...
15
})

问题很明显:又丑又容易漏,字段一多就失控。而且校验完之后,TypeScript 依然不知道 body 的类型是什么,你还得手动断言。

Hono + Zod 的方案:用 schema 声明数据结构,校验和类型推导一步到位。

什么是 schema

如果你第一次接触后端校验,可以先把 schema 理解成一份数据规则说明书。它不是实际的数据,而是用来描述「什么样的数据才算合法」

比如下面这段数据:

data.json
1
{
2
"name": "Alice",
3
"email": "alice@example.com"
4
}

它对应的 schema 想表达的是:

  • name 这个字段必须存在
  • name 必须是字符串
  • email 这个字段必须存在
  • email 必须是合法邮箱格式

也就是说,schema 回答的不是「数据是什么」,而是「数据应该长什么样」

在没有 schema 的时候,这些规则通常散落在很多 if 判断里;有了 schema,这些规则就被集中写到一个地方,代码会更清楚。

用 Zod 写出来就是这样:

index.ts
1
const createUserSchema = z.object({
2
name: z.string().min(1),
3
email: z.string().email(),
4
})

这段 schema 可以直接读成自然语言:

  • 整体是一个对象 z.object({...})
  • name 是字符串,而且不能为空
  • email 是字符串,而且必须符合邮箱格式

所以后面你看到 schema 这个词时,不要把它想得太玄。你就把它当成一份「输入数据的规则定义」就行

订阅后可阅读剩余内容
AI 电子伴侣企业级项目实战
已发布145计划发布120目标已完成121%