如何在zod-openapi的Swagger中展示Zod校验错误及问题排查
问题修复方案
一、Zod校验错误无法在OpenAPI/Swagger界面展示的修复
问题原因
Swagger UI仅会展示OpenAPI文档中明确定义的响应结构,当前接口只配置了201成功响应,未定义400错误响应;同时Zod错误的返回格式也未在OpenAPI Schema中注册,导致Swagger无法识别并展示错误内容。
修复步骤
定义Zod错误的OpenAPI Schema
在Schema文件中新增ZodError的结构定义,并注册到registry:// data/schemas.ts 或单独的错误Schema文件 import { z } from 'zod'; import { registry } from '@/utils/registry'; export const zodErrorSchema = z.object({ name: z.string(), message: z.string(), issues: z.array(z.object({ code: z.string(), expected: z.string(), received: z.string().nullable(), path: z.array(z.string()), message: z.string() })) }); registry.register('ZodError', zodErrorSchema);在接口中添加400错误响应定义
修改create-user.ts中的createUserRoute,在responses里新增400状态码的响应配置:export const createUserRoute = registry.registerPath({ // 其他配置保持不变... responses: { 201: { content: { 'application/json': { schema: createUserSchema.response, }, }, description: '用户创建成功', }, 400: { content: { 'application/json': { schema: { $ref: '#/components/schemas/ZodError' }, }, }, description: '请求参数校验失败', }, }, });验证返回格式匹配
当前makeError函数返回的错误格式已与上述zodErrorSchema一致,无需修改。测试时在Swagger中发送无效请求,即可看到结构化的Zod错误信息。
二、可空字段仅传first_name仍报错的修复
问题原因
Zod的nullable()仅允许字段值为null,但不允许字段不存在(即undefined)。若需求是允许字段可选(可以不传),需使用optional()修饰符,而非仅用nullable()。
修复步骤
修改userSchema中first_name和last_name的定义,结合需求选择合适的修饰符:
// data/users/schema.ts import { z } from 'zod'; export const userSchema = z.object({ // 其他字段... // 允许不传、传null、传有效字符串 first_name: z.string().nullable().optional(), last_name: z.string().nullable().optional(), });
- 若仅需允许字段可选(可以不传),不需要接受
null值,直接用z.string().optional()即可; - 若需同时允许不传或传null,则用
z.string().nullable().optional()。
修改后,仅传入first_name时,last_name为undefined,Zod会通过校验。
内容的提问来源于stack exchange,提问作者user19991216
相关产品推荐
相关产品推荐

