在工程一体性和开发体验上,Zod 方案已经反超了传统 class-validator 套路。
⚙️ 一、Swagger 集成的“假自动”
class-validator + @nestjs/swagger 的组合,确实被吹得“无缝集成”,
但实际上,它只是“约定式自动”,不是“类型级自动”。
看个例子👇:
export class CreateUserDto {
@ApiProperty({ description: '邮箱', example: 'alice@example.com' })
@IsEmail()
email: string;
@ApiProperty({ description: '密码', example: '123456' })
@IsString()
password: string;
}
问题来了:
-
你要写三遍:
- 字段名 + 类型(TS)
- 校验规则(
@IsString()) - Swagger 描述(
@ApiProperty())
💥 这意味着:
类型、校验、文档 —— 三套独立系统,只是靠装饰器拼在一起,看起来“一体”,其实脱节。
⚡ 二、Zod 的一体式声明
而 Zod 是真正的“一体式”:
import { z } from 'zod';
import { extendZodWithOpenApi } from 'zod-to-openapi';
extendZodWithOpenApi(z);
export const CreateUserSchema = z.object({
email: z.string().email().openapi({
description: '邮箱',
example: 'alice@example.com',
}),
password: z.string().min(6).max(20).openapi({
description: '密码',
example: '123456',
}),
});
export type CreateUserDto = z.infer<typeof CreateUserSchema>;
✅ 写一遍,自动获得三样东西:
| 功能 | class-validator | Zod |
|---|---|---|
| 类型定义 | 要写 class | 自动推导 infer |
| 校验逻辑 | 写装饰器 | 内嵌规则 |
| OpenAPI | 写 @ApiProperty | .openapi() 自动合成 |
📊 三、自动化差异总结
| 对比维度 | class-validator + @nestjs/swagger | Zod + zod-to-openapi |
|---|---|---|
| 定义重复度 | 三处重复(类型 + 装饰器 + 文档) | 一处声明即可 |
| 类型同步 | ❌ 不自动同步 Swagger | ✅ schema 自动推导 |
| 文档维护成本 | 高(靠人工保持一致) | 低(schema 即真相) |
| 扩展灵活性 | 装饰器必须配合框架运行时解析 | Schema 可导出共享、动态组合 |
| 类型安全性 | TS → class-validator → Swagger 三套系统 | 一套 schema 统一三端 |
| 跨层复用(前后端共享) | 几乎不可能 | ✅ 可共享 schema |
🧩 四、为什么 Zod 一体性更强?
Zod 的理念是 「schema 即真相」:
一次声明 = 类型 + 校验 + 文档
而 NestJS 的 class-validator 思路是 「三段式拼合」:
类型(TypeScript)
+ 校验(class-validator)
+ 文档(@nestjs/swagger)
= 看起来的一体
区别就在:
- class-validator 是“运行时拼装出来的一体感”
- zod 是“编译时+运行时一体的真实统一”
🚀 五、Zod 真正的工程优势
| 能力 | class-validator | Zod |
|---|---|---|
| 类型即验证(Type as Validator) | ❌ 不支持 | ✅ 强类型直连 |
| Prisma schema 复用 | ❌ 难(需单独维护) | ✅ 一行 zod-prisma |
| 前后端复用 | ❌ 不可行 | ✅ 可生成 TS + Swagger + JSON Schema |
| 生成器生态 | 限 | 强(zod-to-json-schema、zod-to-openapi、zod-prisma) |
| 声明体验 | 繁琐(装饰器+文档) | 简洁(链式 API) |
🧭 六、总结一句话
@nestjs/swagger+class-validator看似自动,实则“三段拼装”;
zod+zod-to-openapi才是 真正的一体式声明,
类型、验证、文档三者源于同一份 schema,才是真正的“单一事实源(Single Source of Truth)”。
408

被折叠的 条评论
为什么被折叠?



