NestJS의 ValidationPipe 대표 옵션 정리

Daehyeon Yun·2024년 8월 14일

NestJS에서 ValidationPipe 는 요청 데이터를 유효성 검사하며 필요에 따라 데이터를 변환하는 데 사용되는 파이프(Pipe) 이다. 이는 main.ts 에서 글로벌로 설정할 수 있으며 다양한 옵션을 활성화하여 파이프 동작을 커스터마이징 할 수 있다.


💡  ValidationPipe 의 주요 옵션

🎈 1. whitelist

  • DTO에 정의되어 있지 않은 속성들이 요청 데이터에 포함되어 있으면 이를 자동으로 제거한다.
    → 클라이언트가 의도치 않게 추가 데이터를 전송하더라도, 서버는 필요한 데이터만 받게 된다.
new ValidationPipe({ whitelist: true })

🎈 2. forbidNonWhitelisted

  • whitelist 옵션과 함께 사용하는 옵션이다.
  • DTO에 정의되지 않은 속성이 요청 데이터에 포함되어 있으면 에러를 발생시킨다.
    허용되지 않은 속성이 포함된 요청을 서버가 거부하게 된다.
new ValidationPipe({
	whitelist: true,
	forbidNonWhitelisted: true,
})

🎈 3. transform

  • 요청 데이터를 자동으로 변환하여 컨트롤러에서 정의된 타입에 맞게 전달된다.
    → ex) HTTP 요청 Body에 포함된 숫자가 문자열로 요청되었을 경우 이를 숫자 타입으로 변환한다.
    new ValidationPipe({ transform: true })

🎈 4. transformOptions

  • transform 옵션과 함께 사용하는 옵션이다.
  • transform 옵션을 더욱 세밀하게 조정할 수 있으며 class-transformer 라이브러리의 옵션을 사용할 수 있다.
new ValidationPipe({
	transform: true,
	transformOptions: { enbleImplicitConversion: true },
})

🎈 5. disableErrorMessages

  • 유효성 검사 실패 시 에러 메시지를 비활성화 시킨다. → 프로덕션 환경에서 보안을 위해 상세한 에러 메시지를 숨길 때 유용하다.
new ValidationPipe({ disableErrorMessages: true })

🎈 6. exceptionFactory

  • 유효성 검사 실패 시 커스텀 예외를 생성할 수 있다 → 기본 예외 대신 사용자 정의 예외를 발생시키고자 할 때 사용한다.
new ValidationPipe({
	exceptionFactory: (errors) => new MyCustomException(errors),
})

💡  ValidationPipe 대표 옵션들이 HTTP 요청 시 어떻게 작동할까?

우선, 아래와 같은 DTO 를 작성하자. 해당 DTOage 필드만을 가지고 있다.

// CreateUserDTO
export class CreateUserDTO{
	age: number;
}

그 후 클라이언트는 다음과 같은 JSON 데이터를 요청한다 가정한다.

{
	"name": "gildong"
}

🎈 1. whitelist 활성화

  • 요청 본문에는 name 필드와 gildong 이 포함되어 있지만 실제 서버 DTO 에는 name 필드가 정의되어 있지 않다. 이에 따라 서버는 정의되어있지 않은 필드가 요청에 포함되었을 경우 제거시키는 whitelist 옵션이 활성화 되어있으므로 {}, 빈 객체 를 받게 된다.
  • 하지만, 에러는 발생하지 않으므로  forbidNonWhitelisted와 함께 사용하여 응용할 수 있다.

🎈 2. forbidNonWhitelisted 활성화

  • 해당 옵션은 위 whitelist 와 함께 사용되는 옵션이다.
  • 위와 같은 상황에서 forbidNonWhitelisted 가 활성화 되어있다면 필드가 제거되는 대신 예외를 발생시켜 클라이언트에게 잘못된 필드가 포함되었다고 알린다.
  • 따라서 서버는 HTTP 400 (Bad Request) 를 반환하고 에러 메시지는 'name' is not allowed 와 같은 내용이 포함된다.

🎈 3. transform 활성화

  • 요청 본문엔 name 필드가 전달되었지만 DTO 에는 age 필드만 존재하기에 transform 옵션만으로는 큰 변화가 존재하지 않는다.
  • 만약, 요청 본문이 아래와 같이 age 필드가 문자열로 전달되었을 경우
{
	"age": "24",
}

CreateUserDTOage숫자(number) 타입이므로 자동으로 숫자로 형변환이 이루어진다.


🎈 4. disableErrorMessages 활성화

  • disableErrorMessage 는 다른 옵션과 조합할 수 있다.
  • 예를 들어 forbidNonWhitelisted 를 사용하면 'name' is not allowed 와 같이 어떤 필드가 잘못되었는지 알려주지만 disableErrorMessages 를 활성화 시 HTTP 400 (Bad Request) 를 반환하지만 에러 메시지는 숨겨지며 클라이언트에게 상세한 정보를 제공하지 않는다.

ValidationPipe 에 있는 각 옵션을 통해 요청 데이터의 유효성을 엄격하게 관리하여, 애플리케이션의 보안과 안정성을 손쉽게 높일 수 있다는 점이 또다른 강점이지 않을까싶다.

profile
열심히 살아야지

0개의 댓글