[NestJS] ValidationPipe 사용 방법

Validation

웹 애플리케이션으로 전송되는 데이터의 검증을 도와줍니다.
들어오는 요청을 자동으로 검증하기 위해 Nest는 즉시 사용할 수 있는 여러 파이프를 제공합니다.

ValidationPipe

ValidationPipe는 강력한 클래스 유효성 검사기 패키지와 선언적 유효성 검사 데코레이터를 사용합니다. ValidationPipe는 들어오는 모든 클라이언트 페이로드에 대해 유효성 검사 규칙을 적용하는 편리한 접근 방식을 제공합니다.

ValidationPipe 사용을 위한 class-validator, class-transformer 패키지를 설치합니다.

1
npm i --save class-validator class-transformer

사용 예시

ValidationPipe 를 사용하기 위해 main.ts 파일에 다음과 같이 추가합니다.

1
2
3
4
5
6
7
8
9
10
11
12
// 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);
// ValidationPipe 추가
app.useGlobalPipes(new ValidationPipe());
await app.listen(3000);
}
bootstrap();

유효성 검사를 위해 사용자 등록을 예시로 작성했습니다.

먼저 사용자 등록을 위한 DTO(Data Transfer Object) 클래스를 생성합니다. 그리고 validation decorator(IsString, IsNumber 등)를 유효성 검사하기 위한 필드에 추가합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
// create-user.dto.ts
import { IsString, IsNumber } from 'class-validator';

export class CreateUserDto {
@IsString()
readonly name: string;

@IsNumber()
readonly age: number;

@IsString({ each: true })
readonly hobbies: string[];
}

사용자 등록 요청을 받기 위해 컨트롤러 클래스를 생성합니다. create 함수의 파라미터에 생성한 DTO 클래스를 타입으로 지정합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { Body, Controller, Post } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';

@Controller('users')
export class UserController {
constructor() {}

/**
* 사용자 등록
* @param userData
* @returns
*/
@Post()
create(@Body() userData: CreateUserDto) {
return '사용자 등록 성공!!';
}
}

사용자 등록 요청을 해보겠습니다. Postman 또는 Insomnia 툴을 이용합니다.
http://localhost:3000/student/ 주소를 POST 방식으로 요청합니다.

1
2
3
4
// 클라이언트 측에서 전송한 데이터가 다음과 같을 경우
{
"height": 180
}
1
2
3
4
5
6
7
8
9
10
// 서버에서 응답
{
"statusCode": 400,
"message": [
"name must be a string",
"age must be a number conforming to the specified constraints",
"each value in hobbies must be a string"
],
"error": "Bad Request"
}

요청하는 데이터가 “name”, “age”, “hobbies” 필드가 존재하지 않으므로 예외를 응답합니다. 즉, ValidationPipe를 사용하면 모든 엔드포인트가 잘못된 데이터를 수신하지 못하도록 보호됩니다. 간단한 설정만으로 유효성 체크를 할 수 있습니다.

옵션

whitelist

whitelist: true로 설정하면 유효성 검사기는 class-validator의 유효성 검사 데코레이터를 적어도 하나라도 사용하지 않은 모든 속성 객체를 제거합니다.

1
2
3
4
5
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
})
);

forbidNonWhitelisted

forbidNonWhitelisted: true로 설정하면 화이트리스트에 없는 속성을 제거하는 대신 유효성 검사기가 예외를 발생합니다.

1
2
3
4
5
6
app.useGlobalPipes(
new ValidationPipe({
whitelist: true,
forbidNonWhitelisted: true,
})
);

whitelist 와 forbidNonWhitelisted 옵션을 true로 설정하면 "height"이라는 속성은 화이트리스트에 존재하지 않으므로 HttpException을 응답합니다.

1
2
3
4
5
6
7
// 클라이언트 측에서 전송한 데이터가 다음과 같을 경우
{
"name": "hgko",
"age": 35,
"hobbies": ["soccer"],
"height": 180
}
1
2
3
4
5
6
// 서버에서 응답
{
"statusCode": 400,
"message": ["property height should not exist"],
"error": "Bad Request"
}

transform (자동 형변환)

네트워크를 통해 들어오는 payload는 일반 JavaScript 객체입니다. ValidationPipe는 payload를 DTO 클래스에 따라 유형이 지정된 객체로 자동 변환할 수 있습니다. 자동 변환을 활성화하려면 transform을 true로 설정하십시오. 이 동작을 전역적으로 활성화하려면 전역 파이프에서 옵션을 설정합니다.

1
2
3
4
5
app.useGlobalPipes(
new ValidationPipe({
transform: true,
})
);

참고

Share