typescript 55 lines · 9 steps

How validation groups reuse one DTO in NestJS

A single UserDto validates differently for create and update by tagging each rule with a group.

Explained by highlit
1import {
2 IsEmail,
3 IsNotEmpty,
4 IsOptional,
5 IsString,
6 IsUUID,
7 MinLength,
8} from 'class-validator';
9 
10export const CREATE = 'create';
11export const UPDATE = 'update';
12 
13export class UserDto {
14 @IsUUID('4', { groups: [UPDATE] })
15 @IsNotEmpty({ groups: [UPDATE] })
16 id?: string;
17 
18 @IsEmail({}, { groups: [CREATE, UPDATE] })
19 @IsNotEmpty({ groups: [CREATE] })
20 @IsOptional({ groups: [UPDATE] })
21 email!: string;
22 
23 @IsString({ groups: [CREATE, UPDATE] })
24 @MinLength(2, { groups: [CREATE, UPDATE] })
25 @IsNotEmpty({ groups: [CREATE] })
26 @IsOptional({ groups: [UPDATE] })
27 displayName!: string;
28 
29 @IsString({ groups: [CREATE] })
30 @MinLength(8, { groups: [CREATE] })
31 @IsNotEmpty({ groups: [CREATE] })
32 password!: string;
33}
34 
35@Controller('users')
36export class UsersController {
37 constructor(private readonly users: UsersService) {}
38 
39 @Post()
40 create(
41 @Body(new ValidationPipe({ groups: [CREATE], whitelist: true }))
42 dto: UserDto,
43 ) {
44 return this.users.create(dto);
45 }
46 
47 @Patch(':id')
48 update(
49 @Param('id', ParseUUIDPipe) id: string,
50 @Body(new ValidationPipe({ groups: [UPDATE], whitelist: true }))
51 dto: UserDto,
52 ) {
53 return this.users.update(id, dto);
54 }
55}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Validation groups let one DTO enforce different rule sets per operation without duplicating classes.
  2. 2Naming groups as shared constants keeps the DTO decorators and the controller pipes in sync.
  3. 3A ValidationPipe scoped to a group only runs the decorators tagged with that group, so the same field can be required in one flow and optional in another.

Related explainers

Share this explainer

Here's the card — post it anywhere.

How validation groups reuse one DTO in NestJS — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code