Search code examples
swaggernestjsdto

ZOD to swagger API Dto class for nestjs swagger


How can I turn this zod schema into the CountryDto for the swagger user? I am using nestjs with zod for input validation. Using nesjs/swagger package for swagger.

export const CountrySchema = z
  .object({
    name: z.string({
      required_error: 'Name is required',
      invalid_type_error: 'Name is invalid',
    }),
    iso2: z.string({
      required_error: 'iso2 is required',
      invalid_type_error: 'iso2 is invalid',
    }),
    iso3: z.string({
      required_error: 'iso3 is required',
      invalid_type_error: 'iso3 is invalid',
    }),
    dialCode: z.string({
      required_error: 'dialCode is required',
      invalid_type_error: 'dialCode is invalid',
    }),
    flagUrl: z.string({
      required_error: 'flagUrl is required',
      invalid_type_error: 'flagUrl is invalid',
    }),
  })
  .required();

Solution

  • You can use the lib: https://github.com/colinhacks/zod

    And do:

    import { createZodDto } from 'nestjs-zod';
    import { z } from 'nestjs-zod/z';
    
    // Define Zod schema for CountrySchema
    const CountrySchema = z.object({
      // ... (your schema definition here)
    });
    
    // Create DTO class using createZodDto
    export class CountryDTO extends createZodDto(CountrySchema) {}
    

    You need to make some configurations in your main.ts/js

    You need to import PatchNestJsSwagger into the main.ts and call it, like this:

    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './app.module';
    import { Logger } from '@nestjs/common';
    import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
    import { patchNestJsSwagger } from 'nestjs-zod';
    import { ConfigService } from '@nestjs/config';
    import { Env } from './env';
    
    async function bootstrap() {
      const app = await NestFactory.create(AppModule);
      const configService = app.get<ConfigService<Env, true>>(ConfigService);
      patchNestJsSwagger();
    
      app.enableCors();
    
      const config = new DocumentBuilder()
        .setTitle('Area API')
        .setDescription('Uma api para uma área de membros')
        .setVersion('1.0')
        .addTag('MEMBROS')
        .build();
      const document = SwaggerModule.createDocument(app, config);
      SwaggerModule.setup('api-docs', app, document);
    
      app.setGlobalPrefix('api');
      const port = configService.get('PORT', { infer: true });
      await app.listen(port);
      Logger.log(`Server running on http://localhost:${port}`, 'Bootstrap');
    }
      bootstrap();
    

    You can find more informations in the nestjs/zod lib quoted in the start of the response.