[NestJS] - 9. Pipe와 Validator, 요청 데이터 사전 검문하기
이번 포스팅에서는 앞서 만든 REST API를 데이터베이스와 연동하기 이전에 Pipe의 개념과 클래스의 값 유효성을 검증하는 Class-Validator에 대해 간단히 포스팅하고 넘어가려고 한다.
Pipe
- @Injectable 데코레이터에 의해 사용되는 Providers에 속하는 클래스
- 클라이언트의 요청 데이터 인수를 Route Handler에서 작업하기 이전에 사전에 처리해주는 역할을 한다. 파이프를 사용 시 데이터를 사용 가능한지 판별하거나 사용하기 적절하게 가공하는 과정을 거치며, 해당 과정을 통과해야 라우터에 도달하게 된다.
- 요청값을 원하는 형식으로 바꿔주는 Data Transformation과, 입력값의 자료형 등의 유효성을 판별하는 Data Validation의 역할을 수행한다.
Validator의 필요성
@Post()
createProduct(@Body() input: CreateProductInput): boolean {
return this.productService.create(input);
}
다음과 같이 상품을 등록하는 API가 있다고 생각해보자. 클라이언트는 Body에 이름, 가격 등을 포함한 상품 모델을 함께 인수로 전달하여, 서버는 해당 인수를 바탕으로 데이터베이스에 Insert하게 될 것이다.
그런데 가격이 만약 "안녕"과 같은 문자로 입력받게 된다면 문제가 발생하게 될 것이다.
클라이언트쪽에서 잘 막아주면 되지 않는가라고 질문할 수 있지만 누군가 백엔드 개발자는 절대 프론트엔드와 클라이언트를 믿지 말라고 했다. 어떠한 기상천외한 방법을 시도할 지 모른다.
Validator Pipe 사용하기
패키지 설치
yarn add class-validator class-transformer |
▶ createProduct.dto.ts
import { IsInt, IsString } from 'class-validator';
export class CreateProductInput {
@IsString()
name: string;
@IsString()
description: string;
@IsInt()
price: number;
}
다음과 같이 클래스 안에 데코레이터를 통해서 클래스 속성에 대한 허용값을 정해준다.
자료형 지정은 물론, NULL 허용여부나 최소값/최댓값 등 다양한 데코레이터들을 지원해준다.
하지만 이런다고 끝나는 것은 아니고 해당 Validator을 사용한다고 파이프를 설정해주어야 한다.
@Post()
@UsePipes(ValidationPipe)
createProduct(@Body() input: CreateProductInput): boolean {
return this.productService.create(input);
}
다음과 같이 @UsePipes(ValidationPipe)를 통해서 Class-Validator를 통해 사전에 검사하겠다고 파이프를 설정해주어야 한다.
참고로 ValidationPipe는 NestJS가 기본적으로 제공해주는 파이프 종류 중 하나이다.
price가 String으로 들어오자 400 Error을 반환한다. | 모든 값이 유효하므로 라우터에서 해당 요청을 처리하여 결과를 반환하였다. |
GlobalPipes 사용하기
그렇다면 매번 @UsePipes(ValidationPipe)를 컨트롤러에 매번 붙여주어야 할까? 그렇지는 않다. NestJS에서 전역적으로 파이프를 적용시킬 수도 있다.
▶ main.ts
import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe());
await app.listen(3000);
}
bootstrap();
다음과 같이 app.useGlobalPipes()를 적용시키면 모든 요청에 ValidationPipe를 적용시키는 것이 가능하다.
@Post()
createProduct(@Body() input: CreateProductInput): boolean {
return this.productService.create(input);
}
그러면 데코레이터 없이 Input값에 대해서 Validation Pipe를 적용시키는 것이 가능하다.
해당 강의를 들으면서 학습한 내용을 바탕으로 저만의 프로젝트를 만드는 과정을 기록하여 남기는 것을 목표로 하고 있습니다.
주관적인 생각이 들어가 있을 수 있으므로 혹시 틀린 내용이 있다면 피드백 부탁드립니다.
'Backend > Node.js (NestJS)' 카테고리의 다른 글
[NestJS] - 11. TypeORM Delete, 실제 삭제와 소프트 삭제 (1) | 2023.02.23 |
---|---|
[NestJS] - 10. TypeORM Insert / Update (0) | 2023.02.23 |
[NestJS] - 8. 데이터베이스 관계와 TypeORM 데이터베이스 관계 매핑 (0) | 2023.02.22 |
[NestJS] - 7. TypeORM 데이터베이스 연동과 엔티티 매핑 (0) | 2023.02.22 |
[NestJS] - 6. 상품 REST API 만들기 (0) | 2023.02.09 |