[NestJS] - Pipe

morecodeplease·2024년 12월 3일
0

NestJS TIL

목록 보기
8/9
post-thumbnail

👀 1. Pipe란?

✅ Pipe는 NestJS의 요청 처리 라이프사이클에서 요청 데이터를 변환하거나 검증하는 데 사용한다.


주요 기능

  1. 데이터 변환 (Transformation): 데이터를 다른 형식으로 변환.
  2. 데이터 검증 (Validation): 요청 데이터가 유효한지 확인.
  • Pipe컨트롤러 핸들러로 들어가기 전에 데이터를 처리한다.

❗ 기본 내장 Pipe

NestJS는 기본적으로 제공하는 Pipe가 있다.

Pipe 이름설명
ValidationPipe요청 데이터를 검증 (e.g., DTO와 class-validator 사용)
ParseIntPipe요청 데이터를 정수로 변환
ParseBoolPipe요청 데이터를 부울 값으로 변환
ParseArrayPipe요청 데이터를 배열로 변환
ParseUUIDPipe요청 데이터를 UUID 형식으로 검증
DefaultValuePipe값이 없을 경우 기본값을 제공

👌 사용 방법

1. Global Pipe

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({
      whitelist: true, // 정의하지 않은 값들은 전부 전달이 안되게 함, dto 에 존재하는값과 존재하지않는 값 구분이 가능
      forbidNonWhitelisted: true, // whitelist에서 걸리면 에러까지 return
    }),
  );
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
  • main.tsuseGlobalPipes를 적용해서 전역으로 pipe를 사용할 수 있다.

2. Custom Pipe

import {
  ArgumentMetadata,
  BadRequestException,
  Inject,
  Injectable,
  PipeTransform,
} from '@nestjs/common';

@Injectable()
export class MovieTitleValidationPipe implements PipeTransform<string, string> {
  transform(value: string, metadata: ArgumentMetadata): string {
    if (!value) {
      return value;
    }

    // 만약에 글자 길이가 1보다 작거나 같으면 에러 던지기!
    if (value.length <= 1) {
      throw new BadRequestException('영화의 제목은 3자 이상 작성해주세요!');
    }
    return value;
  }
}
  • Custom pipe를 만들기 위해서는 PipeTransform를 implements 해야한다.
  • 입력과 반환 타입의 제네릭을 명시한다.
  • value: string은 요청 데이터의 값이다.
  • metadata: ArgumentMetadata는 요청 데이터에 대한 메타데이터인데
    type: 데이터의 타입 (body, query, param, 등).
    metatype: 데이터의 클래스 또는 원시 타입 (e.g., String, Number, CreateMovieDto).
    data: 매개변수 이름 또는 키 이름. 이 있다.
  • 로직은 글자의 길이가 1보다 작거나 같으면 에러를 던지고 아니면 value를 리턴해준다.

3. Router parameter pipe

  @Get()
  getMovies(@Query('title', MovieTitleValidationPipe) title?: string) {
    return this.movieService.findAll(title);
  }
  • 위에서 만든 Custom pipe를 파라미터에 적용 시켜서 검증할 수 있다!

4. Controller pipe

@Controller('movie')
@UsePipes(MovieTitleValidationPipe)
@UseInterceptors(ClassSerializerInterceptor) // class-transformer를 movie controller에 적용을 하기 위한 코드
export class MovieController {
  constructor(private readonly movieService: MovieService) {}

  @Get()
  getMovies(@Query('title', MovieTitleValidationPipe) title?: string) {
    return this.movieService.findAll(title);
  }

  @Get(':id')
  getMovie(@Param('id', ParseIntPipe) id: number) {
    console.log(test);
    return this.movieService.findOne(id);
  }
  • @Controller annotation에 적용하면 모든 핸들러에 pipe가 적용된다.

5. Rotuer Pipe

 @Patch(':id')
  @UsePipes(MovieTitleValidationPipe)
  patchMovie(
    @Param('id', ParseIntPipe) id: string,
    @Body() body: UpdateMovieDto,
  ) {
    return this.movieService.update(+id, body);
  }
  • 각 라우터에 annotation을 적용할 수 도 있다.

참조

profile
Everyday's a lesson

0개의 댓글