You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Zod Schema转换为NestJS Swagger的CountryDto?

如何将Zod的CountrySchema转换为NestJS Swagger可用的CountryDto

你可以通过两种方式实现需求:手动编写DTO类结合Swagger装饰器,或者借助工具自动将Zod Schema转换为Swagger兼容的DTO。

方法一:手动编写CountryDto

这种方式适合简单场景,能精准控制Swagger文档的展示细节:

  1. 创建CountryDto类,导入@nestjs/swagger的@ApiProperty装饰器,为每个字段配置描述、必填状态和示例值:
import { ApiProperty } from '@nestjs/swagger';

export class CountryDto {
  @ApiProperty({
    description: '国家名称',
    required: true,
    example: 'China',
  })
  name: string;

  @ApiProperty({
    description: 'ISO 两位国家代码',
    required: true,
    example: 'CN',
  })
  iso2: string;

  @ApiProperty({
    description: 'ISO 三位国家代码',
    required: true,
    example: 'CHN',
  })
  iso3: string;

  @ApiProperty({
    description: '国际电话区号',
    required: true,
    example: '+86',
  })
  dialCode: string;

  @ApiProperty({
    description: '国旗图片URL',
    required: true,
    example: 'https://example.com/cn-flag.png',
  })
  flagUrl: string;
}
  1. 为了让DTO类型和Zod Schema保持一致,可通过z.infer获取Schema的类型并让DTO实现该类型:
import { z } from 'zod';
import { ApiProperty } from '@nestjs/swagger';
import { CountrySchema } from './path-to-your-schema';

// 从Zod Schema推导类型
type CountryType = z.infer<typeof CountrySchema>;

export class CountryDto implements CountryType {
  @ApiProperty({
    description: '国家名称',
    required: true,
    example: 'China',
  })
  name: string;

  @ApiProperty({
    description: 'ISO 两位国家代码',
    required: true,
    example: 'CN',
  })
  iso2: string;

  // 其他字段配置同上
  iso3: string;
  dialCode: string;
  flagUrl: string;
}
  1. 在控制器中使用该DTO,并结合ZodValidationPipe做输入校验:
import { Controller, Post, Body, UsePipes } from '@nestjs/common';
import { ZodValidationPipe } from '@nestjs/zod';
import { CountryDto } from './country.dto';
import { CountrySchema } from './country.schema';

@Controller('countries')
export class CountryController {
  @Post()
  @UsePipes(new ZodValidationPipe(CountrySchema))
  createCountry(@Body() countryDto: CountryDto) {
    // 业务逻辑实现
    return countryDto;
  }
}

方法二:自动转换(基于zod-to-openapi和@nestjs/zod)

这种方式能减少重复代码,自动同步Zod Schema和Swagger文档:

  1. 安装依赖:
npm install zod-to-openapi @nestjs/zod
  1. 扩展Zod以支持OpenAPI配置,修改你的CountrySchema:
import { z } from 'zod';
import { extendZodWithOpenApi } from 'zod-to-openapi';

// 扩展Zod,添加openapi配置方法
extendZodWithOpenApi(z);

export const CountrySchema = z
  .object({
    name: z.string({
      required_error: 'Name is required',
      invalid_type_error: 'Name is invalid',
    }).openapi({
      description: '国家名称',
      example: 'China',
    }),
    iso2: z.string({
      required_error: 'iso2 is required',
      invalid_type_error: 'iso2 is invalid',
    }).openapi({
      description: 'ISO 两位国家代码',
      example: 'CN',
    }),
    iso3: z.string({
      required_error: 'iso3 is required',
      invalid_type_error: 'iso3 is invalid',
    }).openapi({
      description: 'ISO 三位国家代码',
      example: 'CHN',
    }),
    dialCode: z.string({
      required_error: 'dialCode is required',
      invalid_type_error: 'dialCode is invalid',
    }).openapi({
      description: '国际电话区号',
      example: '+86',
    }),
    flagUrl: z.string({
      required_error: 'flagUrl is required',
      invalid_type_error: 'flagUrl is invalid',
    }).openapi({
      description: '国旗图片URL',
      example: 'https://example.com/cn-flag.png',
    }),
  })
  .required()
  .openapi({
    title: 'CountryDto',
    description: '国家信息DTO',
  });
  1. 使用@nestjs/zod的createZodDto生成兼容Swagger的DTO:
import { createZodDto } from '@nestjs/zod';
import { CountrySchema } from './country.schema';

// 自动生成DTO,同时继承Zod的校验规则
export class CountryDto extends createZodDto(CountrySchema) {}
  1. 在main.ts中配置Swagger时,将该DTO加入额外模型:
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { CountryDto } from './country.dto';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  const config = new DocumentBuilder()
    .setTitle('API文档')
    .setDescription('国家管理API')
    .setVersion('1.0')
    .build();

  // 注册DTO,让Swagger识别并生成对应文档
  const document = SwaggerModule.createDocument(app, config, {
    extraModels: [CountryDto],
  });

  SwaggerModule.setup('api', app, document);

  await app.listen(3000);
}
bootstrap();

这样Swagger会自动读取Zod Schema中的OpenAPI配置生成接口文档,同时createZodDto生成的DTO也能直接用于控制器的参数校验。

内容的提问来源于stack exchange,提问作者Owali Ullah Shawon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 03:39:55