这是 Fastify 的灵魂章节。
在很多框架里,验证像额外保安。
在 Fastify 里,验证更像主分拣线前的扫描门。
fastify.post('/shipments', {
schema: {
body: {
type: 'object',
required: ['trackingNo', 'weight', 'destination'],
additionalProperties: false,
properties: {
trackingNo: { type: 'string', minLength: 8 },
weight: { type: 'number', exclusiveMinimum: 0 },
destination: { type: 'string', minLength: 2 },
priority: { type: 'string', enum: ['normal', 'urgent'] }
}
}
}
}, async function (request, reply) {
reply.code(201)
return {
ok: true,
shipment: request.body
}
})现在这条分拣线会自动做这些事:
- 请求体是不是对象
- 运单号是不是字符串
- 重量是不是大于 0
- 优先级是不是限定值
- 有没有多余字段混进来
请求流转会变成这样:
包裹进站
│
▼
扫描门读取 schema
│
├── 合规 -> 进入处理工位
└── 不合规 -> 直接退回错误响应#为什么这一步对性能也重要
因为 Fastify 不是“收到请求再慢慢猜数据长什么样”,而是按已声明规则走编译后的扫描流程。
#一个非常重要的工程规则
Schema 是应用代码,不是用户输入。
不要做这种事:
// 不要这样:把用户传来的 schema 动态编译
const userSchema = request.body.schema因为验证和序列化背后依赖的是编译过的规则,用户可控 schema 会把你送进安全风险区。