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
- Define Schema: Create a Zod schema defining the shape and rules.
- Create Class: Extend
createZodDto(Schema)to generate a NestJS-compatible class. - Use in Controller: Use the class as a type in the controller method. Typical
ValidationPipeis replaced/augmented byZodValidationPipe(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) insrc/common/validation.