如何在响应中对Date进行序列化,同时不影响Swagger/OpenAPI?

后端开发 2026-07-12

我正在使用 nestjs-zod 包来进行请求/响应校验和Swagger生成,构建一个NestJS API。

我的领域实体如下:

    export class UserEntity {
      constructor(
        public readonly id: string,
        public readonly username: string,
        public readonly hashPassword: string,
        public readonly is_active: boolean,
        public readonly created_at: Date,
        public readonly updated_at: Date | null,
      ) {}
    }

我的Zod响应模式如下:

    import { z } from "zod"
    import { createZodDto } from "nestjs-zod"

    export const registerResponseSchema = z.object({
      id: z.string(),
      username: z.string(),
      created_at: z.string(),
    })

    export class RegisterResponse extends createZodDto(registerResponseSchema) {}

控制器:

  import { Body, Controller, Post } from '@nestjs/common'
    import { ApiOperation, ApiTags } from '@nestjs/swagger'
    import { ZodResponse } from 'nestjs-zod'

    @ApiTags('Auth')
    @Controller('auth')
    export class AuthController {
      constructor(private readonly register: RegisterUseCase) {}

      @ApiOperation({ summary: 'Registrations' })
      @ZodResponse({
        status: 201,
        type: RegisterResponse,
      })
      @Post('register')
      async registration(@Body() body: RegisterRequest) {
        return await this.register.register(body.username, body.password)
      }
    }

我的实体返回一个Date值:

created_at: Date

如果我把响应模式定义为:

created_at: z.string()

Swagger能正确工作,但运行时校验失败,因为返回的值是Date,而不是字符串。

如果我把模式改成:

created_at: z.date()

那么运行时校验可以通过,但Swagger生成功能会因为以下错误而失败:

Date cannot be represented in JSON Schema

因此,看起来不可能同时做到:

  • 使用ZodResponse验证响应
  • 生成Swagger/OpenAPI
  • 在实体中保留Date

在使用nestjs-zod与 Swagger时,推荐的处理Date字段的方式是什么?

解决方案

使用z.coerce.date() 搭配自定义转换器,或使用z.string().datetime() 并进行序列化。

最简单的做法是在模式层将Date转换为字符串,这样就能同时满足运行时校验和Swagger的生成功能。

import { z } from "zod"
import { createZodDto } from "nestjs-zod"

export const registerResponseSchema = z.object({
  id: z.string(),
  username: z.string(),
  created_at: z.preprocess(
    (val) => (val instanceof Date ? val.toISOString() : val),
    z.string().datetime()
  ),
})

export class RegisterResponse extends createZodDto(registerResponseSchema) {}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章