본문 바로가기

개발자 강화/백엔드

🌟[공부, 개발] NestJS의 Pipes란?

NestJS의 Pipes

데이터 변환, 검증, 정제(sanitization) 역할을 수행하는 미들웨어와 비슷한 기능

요청(Request)에서 들어오는 데이터를 변환하거나, 특정 조건을 만족하는지 검증하는 데 사용됨

 

Pipes의 주요 역할

1. 데이터 변환(Transformation): 문자열을 숫자로 변환 ("123" -> 123)

2. 데이터 검증(Validation); 값이 특정 조건을 충족하는지 확인(이메일 형식 체크)

3. 데이터 정제(Sanitization): 공백 제거, 특수문자 제거

 

Pipes 사용법

Pipe 설명
ValidationPipe DTO 기반 유효성 검사
ParseIntPipe 문자열을 정수로 변환
ParseBoolPipe "true", "false"를 boolean으로 변환
ParseUUIDpipe UUID 문자열 검증
DefaultValuePipe 기본값 설정
Custom Pipes 직접 정의 가능

 

[1] ValidationPipe 예제

import { IsString, IsInt, Min, Max } from 'class-validator';

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

  @IsInt()
  @Min(18)
  @Max(100)
  age: number;
}

DTO 정의

import { Body, Controller, Post, UsePipes, ValidationPipe } from '@nestjs/common';

@Controller('users')
export class UsersController {
  @Post()
  @UsePipes(new ValidationPipe())
  createUser(@Body() createUserDto: CreateUserDto) {
    return `User Created: ${createUserDto.name}`;
  }
}

Controller에 적용

 

name이 문자열이 아니거나 age가 18~100 범위를 벗어나면 요청이 거부됨

ValidationPipe를 사용하면 자동으로 DTO를 검증하고, 실패 시 400 Bad Request 반환

 

전역적으로 ValidationPipe 적용

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();

매번 @UsePipes() 사용하지 않고, 전역적으로 Pipes 적용

 

[2] ParseIntPipe 예제

@Get(':id')
getUser(@Param('id', ParseIntPipe) id: number) {
  return `User ID: ${id}`;
}

id 값이 문자열로 전달되더라도 자동으로 숫자로 변환됨

숫자로 변환이 불가능한 값(예: "abc")이면 400 Bad Request 응답 발생

 

[3] Custom Pipe 예제

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

@Injectable()
export class UpperCasePipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    return typeof value === 'string' ? value.toUpperCase() : value;
  }
}

Custom Pipe 생성

import { Controller, Get, Query, UsePipes } from '@nestjs/common';
import { UpperCasePipe } from './upper-case.pipe';

@Controller('example')
export class ExampleController {
  @Get()
  @UsePipes(new UpperCasePipe())
  getExample(@Query('text') text: string) {
    return `Modified Text: ${text}`;
  }
}

컨트롤러 적용

 

GET /example?text=hello 요청 시 "Modified Text: HELLO" 반환됨


예전에 백엔드 만들면서 내가 실제로 썼던 Pipes

import { ApiOperation, ApiTags, ApiCreatedResponse } from '@nestjs/swagger';
import { UserService } from './user.service';
import {
  Body,
  Controller,
  Post,
  UsePipes,
  ValidationPipe,
} from '@nestjs/common';
import { AuthDTO, EnterDTO } from './dto/authDto';
@ApiTags('user')
@Controller('user')
@UsePipes(ValidationPipe)
export class UserController {
  constructor(private readonly userService: UserService) {}
  @ApiOperation({ summary: 'Signup' })
  @ApiCreatedResponse({ description: 'Signup Success' })
  @Post('/signup')
  async signup(@Body() enterDTO: EnterDTO) {
    return this.userService.createUser(enterDTO);
  }

  @ApiOperation({ summary: 'Signin' })
  @ApiCreatedResponse({ description: 'Signin Success' })
  @Post('/signin')
  async signin(@Body() authDTO: AuthDTO) {
    return this.userService.enterUser(authDTO);
  }
}

 

@UsePipe를 Controller에 통째로 적용해서 UseController에 들어오는 모든 Request에 대해 유효성 검증 실행

 

각 API에서 @Body()로 받은 데이터를 EnterDTO나 AuthDTO에 자동으로 매핑해서 데이터 유효성 검증

충족하지 않으면 400 Bad Reqeust 반환

 

import { ApiProperty } from '@nestjs/swagger';
import { IsEmail, IsString, Length } from 'class-validator';
export class AuthDTO {
  @ApiProperty({ description: 'email' })
  @IsEmail()
  email: string;

  @ApiProperty({ description: 'password' })
  @IsString()
  @Length(4, 20)
  password: string;
}

export class EnterDTO {
  @ApiProperty({ description: 'email' })
  @IsEmail()
  email: string;

  @ApiProperty({ description: 'password' })
  @IsString()
  @Length(4, 20)
  password: string;

  @ApiProperty({ description: 'nickname' })
  @IsString()
  @Length(2, 20)
  nickName: string;
}

 

 

DTO에는 글자수 제한, 이메일 형식 제한, 문자열 여부 등을 걸어놨다

해당 길이나 형태에 안맞으면 에러 반환하게 되어있음

 

최근에 Pipes 써봤냐는 질문에 당황해서 안써봤다고 했는데...

코드 까보니까 아주 잘 써놨었더라...

저건 간단한 부분이고... 중요 로직에도 다 잘 적용해놨음...바보...ㅠㅠㅠ

인간이 망각의 동물인게 너무 원망스러움


출처

[1] NestJS 공식 독스. Pipes. https://docs.nestjs.com/pipes

[2] gpt에게 Pipes에 대해 묻다

[3] 1년 전에 작성한 나의 NestJS 코드