본문 바로가기
Backend/NestJS

NestJS에서 validation 관련 설정 방법 (class-validator & class-transformer)

by 찬찬2 2024. 6. 18.

1. Pipe

- controller 에서 사용.

- NestJS 에서 Pipe 는 먼저 transform 하고 validate 한다.

 

에러메시지는 "validation failed".

 

@Controller('posts')
export class PostsController {
   constructor(private readonly postsService: PostsService) {}

   @Get(':id')
   getPost(
      @Param('id', ParseIntPipe) id: number
   ){
      return this.postService.getPost();
   }
}

 

2. class-validator

- Entity 또는 DTO 에서 사용

- IsNumber, IsString, IsEmail, etc...

- 위 데코레이터들이 실행되게 하기 위해서

 

① main.ts 를 아래와 같이 설정하거나

② controller 에서 @UsePipes 데코레이터와 NesJS 에서 제공하는 "ValidationPipe" 객체를 넣어줘야 한다.

③ module.ts 에서

 

// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';

async function bootstrap() {
   const app = await NestFactory.create(AppModule);
   app.useGlobalPipes(new ValidationPipe());  // 여기
   
   await app.listen(3000);
}
bootstrap();

// controller.ts
@Controller('posts')
export class PostsController {
   constructor(private readonly postsService: PostsService) {}
   
   @Post()
   @UsePipes(new ValidationPipe()) // 여기
   createPost(
      @Body() dto: CreatePostDto
   ){
      return this.postsService.createPost();
   }
}

// app.module.ts
import { APP_PIPE } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_PIPE,
      useClass: ValidationPipe,
    },
  ],
})
export class AppModule {}

 

@Entity()
export class User {
    @Column()
    @IsString()
    name: string;

    @Column()
    @IsString()
    email: string;

    @Column()
    @IsString()
    age: number;
}

export class CreateUserDto {
   @IsNumber()
   id: number;
   
   @IsString()
   email: string;
   
   @IsString()
   password: string;
}

 

DTO 를 사용해서 유효성 검사를 할때는 반드시 데이터를 먼저 변형시켜줘야 한다. 제일 처음 언급했던 ParseIntPipe 과 같은 맥락이다.

 

URL 은 문자열이다. 그렇기 때문에 URL 에 있는 파라미터를 DTO에 있는 타입으로 변환하는 작업이 먼저 필요하다. 방법은 두 가지이다.

 

main.ts 안에서 "enableImplicitConversion: true"

DTO 안에서 "@Type(() => Number)"

 

// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';

async function bootstrap() {
   const app = await NestFactory.create(AppModule);
   app.useGlobalPipes(new ValidationPipe({
      transform: true,
      transformOptions: {
         enableImplicitConversion: true // 여기
      }
   }));
   
   await app.listen(3000);
}
bootstrap();

// DTO
import { Type } from "class-transformer";

export class CreateUserDto {
   @Type(() => Number) // 여기
   @IsNumber()
   id: number;
   
   @IsString()
   email: string;
   
   @IsString()
   password: string;
}

댓글