Careeroza
Real World Example
Checkout DTO with Nested Validation
An e-commerce checkout (Flipkart, Myntra, Meesho) sends a list of items and an address. Nested DTOs are validated with @ValidateNested + @Type.
src/orders/dto/create-order.dto.ts
import { Type } from 'class-transformer';
import { ArrayMaxSize, ArrayMinSize, IsEnum, IsInt, IsOptional, IsString, Length, Matches, Max, Min, ValidateNested } from 'class-validator';
export enum PaymentMethod { UPI = 'UPI', CARD = 'CARD', COD = 'COD' }
export class OrderItemDto {
@IsInt() @Min(1) productId: number;
@IsInt() @Min(1) @Max(10) quantity: number;
}
export class AddressDto {
@IsString() @Length(5, 200) line1: string;
@IsString() city: string;
@Matches(/^[1-9][0-9]{5}$/, { message: 'pincode must be a valid 6-digit Indian PIN code' })
pincode: string;
}
export class CreateOrderDto {
@ValidateNested({ each: true })
@Type(() => OrderItemDto)
@ArrayMinSize(1)
@ArrayMaxSize(50)
items: OrderItemDto[];
@ValidateNested()
@Type(() => AddressDto)
address: AddressDto;
@IsEnum(PaymentMethod)
paymentMethod: PaymentMethod;
@IsOptional() @IsString() couponCode?: string;
}Example
curl -X POST http://localhost:3000/orders -H "Content-Type: application/json" \
-d '{"items":[{"productId":7,"quantity":20}],"address":{"line1":"12 MG Road","city":"Bengaluru","pincode":"056001"},"paymentMethod":"UPI"}'Example output
{"message":["items.0.quantity must not be greater than 10","address.pincode must be a valid 6-digit Indian PIN code"],"error":"Bad Request","statusCode":400}