Jay's Cookbook
Menu
  • Tags
  • Categories
  • Projects
Computer Science
OS
Network
Data Structure
Algorithm
Language
Code Architecture
Python
Javascript
Typescript
Java
Backend
Backend Theory
TypeORM
Node.js
NestJS
FastAPI
Frontend
HTML/CSS
React
Next.js
Data Engineering
DE Theory
MySQL
MongoDB
Elastic
Redis
Kafka
Spark
Airflow
AI
Basic
Pytorch
NLP
Computer Vision
Data Analytics
Statistics
Pandas
Matplotlib
DevOps
Git
Docker
Kubernetes
AWS
[NestJS] 구성요소(5) Pipes
backend
NestJS

[NestJS] 구성요소(5) Pipes

Jay Kim
Jay Kim 03 Dec 2023
[NestJS] 구성요소(4) Guards [NestJS] 구성요소(6) DTO

Table of Contents

  • Pipes
    • Built-in Pipes
      • ValidationPipe
      • DefaultValuePipe
      • Parse* Pipe
    • Pipe 적용하기
      • Parameter-level 적용 예시
      • Global-level 적용 예시
    • 커스텀 파이프 만들기

Pipes

  • 들어온 데이터를 검증/변환하는 용도의 클래스
  • PipeTransform 를 implements 하면 됨

Built-in Pipes

  • Nest에서 기본적으로 다음과 같은 빌트인 파이프 제공

ValidationPipe

  • 글로벌한 규칙을 적용하고 싶은 경우에 많이 사용
  • ValidationPipeOptions 객체를 통해 옵션 전달할 수 있음
  • ex. whitelist, forbidNonWhitelisted, transform 등과 같은 인자로 글로벌하게 규칙 적용
  • 어플리케이션에서 정해둔 인풋 데이터를 whitelist 라고 함
  • whitelist: true
    • 정해둔 인풋 데이터만 받음
    • (정해두지 않은 예상치 않은 인풋 데이터를 허용하면, 보안상 취약점 생길 수 있음)
  • forbidNonWhitelisted: true
    • 정해두지 않은 예상치 않은 인풋 데이터가 들어오면, 400 예외 발생시킴으로써 아예 어플리케이션에서 추가 실행되지 않도록 할 수 있음
    • (whitelist: true 옵션도 함께 줘야 예상대로 동작함)
  • transform: true
    • 타입 힌팅으로 전달해준 타입으로 알아서 변환해줌
    • (ex. ParseIntPipe 안써도, int로 타입 힌팅해주면 numeric한 문자열을 정수 타입으로 변환해줌)

DefaultValuePipe

  • Parse* 파이프를 통과해야 하는 파라미터는 그냥 단순히 =’기본값’ 형태로 디폴트를 줄 수 없음
  • DefaultValuePipe 파이프를 사용해 디폴트 값을 줘야함

Parse* Pipe

  • ParseIntPipe, ParseFloatPipe, ParseBoolPipe, ParseArrayPipe, ParseUUIDPipe, ParseEnumPipe, ParseFilePipe
  • Parse* 파이프들은 Int, Float, .. 등으로 데이터를 변환시켜줌으로써 해당 데이터 타입임을 확실할 수 있도록 해줌
  • 변환 불가능한 타입이면 Bad Request 예외 발생 (ex. ParseIntPipe에 대해 ‘Apple’: 예외 발생, ‘1’: 1로 변환)
  • 대부분 파라미터에 사용

Pipe 적용하기

Parameter-level 적용 예시

  • @Param(), @Query() 등과 같은 데코레이터에 전달
  • 여러 파이프를 순차적으로 전달할 수도 있음
  • 의존성 주입 방식으로 그냥 클래스만 전달 할 수도 있고, 옵션을 넣어줌으로써 조금 더 커스텀하게 쓰고 싶은 경우 직접 인스턴스를 전달할 수도 있음
@Get(':id')
async findOne(@Param('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
@Get(':id')
async findOne(
  @Param('id', new ParseIntPipe({ errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE }))
  id: number,
) {
  return this.catsService.findOne(id);
}
  • Parse* 파이프들은 항상 어떤 값이 들어오기를 기대 -> null, undefined 들어오면 예외 발생
  • 그래서 Parse* 파이프 앞에 먼저 DefaultValuePipe 파이프 넣어주면 좋음
@Get()
async findAll(
  @Query('activeOnly', new DefaultValuePipe(false), ParseBoolPipe) activeOnly: boolean,
  @Query('page', new DefaultValuePipe(0), ParseIntPipe) page: number,
) {
  return this.catsService.findAll({ activeOnly, page });
}

Global-level 적용 예시

  • useGlobalPipes()를 통해 main.ts 파일에 적용
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe(
  { 
    whitelist: true,
    forbidNonWhitelisted: true,
  })
)

커스텀 파이프 만들기

  • PipeTransform 을 implements 하면 됨
  • transform() 을 구현해야함. 다음의 두 인자를 받음
    • value: 파이프를 지나는 데이터
    • metadata: 파이프가 적용된 데이터의 메타데이터
      • metadata 객체는 다음과 같은 속성을 가짐
      • type: 인자가 요청의 어느 부분으로 들어오는지 (‘body’, ‘query’, ‘param’, ‘custom’)
      • metatype: 데이터에 선언된 타입 (ex. @Param('id', ParseIntPipe) id: number) 인 경우 number)
      • data: 데코레이터에 넘겨진 문자열 (ex. @Param('id', ParseIntPipe) id: number) 인 경우 id)
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class MyValidationPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    return value;
  }
}
[NestJS] 구성요소(4) Guards [NestJS] 구성요소(6) DTO

You may also like

See all NestJS
14 Oct 2024 [NestJS] API 문서화
backend
NestJS

[NestJS] API 문서화

09 Oct 2024 [NestJS] SSE
backend
NestJS

[NestJS] SSE

08 Oct 2024 [NestJS] 웹 소켓
backend
NestJS

[NestJS] 웹 소켓

Jay Kim

Jay Kim

Web development, data engineering for human for the Earth. I share posts, free resources and inspiration.

Rest
Lifestyle
Hobby
Hobby
Hobby
Hobby
2025 © Jay's Cookbook. Crafted & Designed by Artem Sheludko.