Skip to main content

Validation & DTOs Strategy

We use Zod combined with nestjs-zod for all Data Transfer Objects (DTOs) and runtime validation. We explicitly avoid class-validator to ensure strict type safety and cleaner schema definitions.

The Pattern

  1. Define Schema: Create a Zod schema defining the shape and rules.
  2. Create Class: Extend createZodDto(Schema) to generate a NestJS-compatible class.
  3. Use in Controller: Use the class as a type in the controller method. Typical ValidationPipe is replaced/augmented by ZodValidationPipe (registered globally or locally).

Example

src/users/dto/create-user.dto.ts

import { createZodDto } from 'nestjs-zod';
import { z } from 'zod';

// 1. Define Zod Schema
export const CreateUserSchema = z.object({
name: z.string().min(2, 'Name is too short').max(50),
email: z.string().email(),
password: z.string().min(6),
// Enums match Prisma enums
role: z.enum(['User', 'Admin']).default('User'),
// Optional fields
synagogueCode: z.string().optional(),
});

// 2. Export DTO Class
export class CreateUserDto extends createZodDto(CreateUserSchema) {}

Global Setup

The validation pipe is enabled in main.ts:

import { ZodValidationPipe } from 'nestjs-zod';

app.useGlobalPipes(new ZodValidationPipe());

Swagger Integration

nestjs-zod automatically generates Swagger (OpenAPI) schemas from the Zod definitions. You generally do not need to add @ApiProperty() decorators manually unless you need to override the description or example.

// Swagger shows 'name' as string, required, min 2 chars automatically.

Best Practices

  • Strict Mode: Zod schemas are strict by default (strip unknown keys).
  • Transformation: Use .transform() with caution as it runs during validation.
  • Reusability: Export common schemas (e.g., MongoIdSchema) in src/common/validation.