[Nest.js] Pipe로 데이터 검증과 변환 쉽게 처리하기

궁금하면 500원·2024년 8월 14일

1.Nest.js에서 Pipe란?

Pipe는 Nest.js에서 요청(request)을 처리하기 전, 데이터 변환 및 유효성 검증을 수행하는 핵심 도구입니다.

요청이 들어올 때 컨트롤러가 데이터를 받기 전에 특정 작업을 처리하는 미들웨어 역할을 하며,
주로 변환(transform)유효성 검증(validation)을 수행합니다.

Transform(변환): 들어오는 데이터를 다른 형식으로 변환합니다.
예를 들어, 문자열로 들어온 데이터를 정수로 변환하거나,
특정 구조로 데이터를 재구성할 수 있습니다.

Validation(검증): 들어오는 데이터가 특정 조건을 만족하는지 확인합니다.
예를 들어, 값이 비어있지 않은지, 특정 패턴을 따르는지 등을 검증할 수 있습니다.

Pipes는 컨트롤러 메서드에서 매개변수 수준으로 적용할 수 있으며,
글로벌 수준에서도 사용할 수 있습니다.

2. 기본 Pipe 타입 1

2.1. ValidationPipe

ValidationPipe는 들어오는 데이터에 대해 DTO(Data Transfer Object)와 함께 유효성 검사를 수행하는 Pipe입니다.

주로 class-validator와 함께 사용되며, DTO에 정의된 조건에 따라 요청 데이터를 검증합니다.

  • 예시 코드:
import { IsInt, IsString } from 'class-validator';

class CreateUserDto {
  @IsString()
  name: string;

  @IsInt()
  age: number;
}

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

@Controller('users')
export class UserController {
  @Post()
  createUser(@Body(new ValidationPipe()) createUserDto: CreateUserDto) {
    return 'User created successfully!';
  }
}

1.2 ParseIntPipe

ParseIntPipe는 문자열로 받은 값을 정수로 변환하는 Pipe입니다.

만약 변환이 불가능하면 예외를 발생시킵니다.

  • 예시 코드:
import { Controller, Get, Param, ParseIntPipe } from '@nestjs/common';

@Controller('users')
export class UserController {
  @Get(':id')
  getUserById(@Param('id', ParseIntPipe) id: number) {
    return `User ID is ${id}`;
  }
}

1.3. ParseFloatPipe

ParseFloatPipe는 문자열로 받은 값을 실수로 변환하는 Pipe입니다.

정수 변환과 비슷하게 실수로 변환할 수 없을 경우 예외를 던집니다.

  • 예시 코드:
import { Controller, Get, Param, ParseFloatPipe } from '@nestjs/common';

@Controller('prices')
export class PriceController {
  @Get(':amount')
  getPrice(@Param('amount', ParseFloatPipe) amount: number) {
    return `Price is ${amount}`;
  }
}

1.4. ParseBoolPipe

ParseBoolPipe는 문자열을 Boolean 타입으로 변환합니다.

true, false 문자열이 아니면 예외를 던집니다.

  • 예시 코드:
import { Controller, Get, Param, ParseBoolPipe } from '@nestjs/common';

@Controller('flags')
export class FlagController {
  @Get(':flag')
  checkFlag(@Param('flag', ParseBoolPipe) flag: boolean) {
    return `Flag is ${flag}`;
  }
}

1.5. ParseArrayPipe

ParseArrayPipe는 문자열을 배열로 변환합니다.

주로 쿼리 매개변수에서 사용되며, 배열의 각 요소도 추가로 검증할 수 있습니다.

  • 예시 코드:
import { Controller, Get, Query, ParseArrayPipe } from '@nestjs/common';

@Controller('items')
export class ItemController {
  @Get()
  getItems(@Query('ids', new ParseArrayPipe({ items: Number })) ids: number[]) {
    return `Items IDs are ${ids}`;
  }
}

3.기본 Pipe 타입 2

3.1. ParseUUIDPipe

ParseUUIDPipe는 주어진 문자열이 유효한 UUID(Universally Unique Identifier)인지 검증하는 Pipe입니다.

UUID 형식이 아니면 예외를 던집니다.

  • 예시 코드:
import { Controller, Get, Param, ParseUUIDPipe } from '@nestjs/common';

@Controller('users')
export class UserController {
  @Get(':uuid')
  getUserByUUID(@Param('uuid', ParseUUIDPipe) uuid: string) {
    return `User UUID is ${uuid}`;
  }
}

3.2. ParseEnumPipe

ParseEnumPipe는 문자열을 열거형(Enum) 값으로 변환하고 검증하는 Pipe입니다.

  • 예시 코드:
enum Role {
  ADMIN = 'admin',
  USER = 'user',
}

import { Controller, Get, Param, ParseEnumPipe } from '@nestjs/common';

@Controller('roles')
export class RoleController {
  @Get(':role')
  getRole(@Param('role', new ParseEnumPipe(Role)) role: Role) {
    return `Role is ${role}`;
  }
}

3.3DefaultValuePipe

DefaultValuePipe는 값이 없거나 undefined일 때 기본값을 설정하는 Pipe입니다.

  • 예시 코드:
import { Controller, Get, Query, DefaultValuePipe } from '@nestjs/common';

@Controller('items')
export class ItemController {
  @Get()
  getItems(@Query('limit', new DefaultValuePipe(10)) limit: number) {
    return `Items limit is ${limit}`;
  }
}

3.4. ParseFilePipe

ParseFilePipe는 파일을 처리하는 데 사용되는 Pipe입니다.

파일 업로드 시 파일의 유효성을 검증하거나 필터링할 수 있습니다.

  • 예시 코드:
import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { ParseFilePipe } from '@nestjs/common';

@Controller('files')
export class FileController {
  @Post('upload')
  @UseInterceptors(FileInterceptor('file'))
  uploadFile(@UploadedFile(new ParseFilePipe()) file: Express.Multer.File) {
    return 'File uploaded successfully';
  }
}

4.사용자가 직접 만드는 Pipe

사용자가 직접 Pipe를 만들려면 PipeTransform 인터페이스를 구현하고,
transform 메서드를 정의해야 합니다.

이 메서드는 요청에서 받은 데이터를 변환하거나 유효성을 검사하는 데 사용됩니다.

예시: 문자열을 대문자로 변환하는 커스텀 Pipe

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

@Injectable()
export class UpperCasePipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    if (typeof value !== 'string') {
      throw new BadRequestException('Expected a string value');
    }
    return value.toUpperCase();
  }
}

import { Controller, Get, Param } from '@nestjs/common';

@Controller('strings')
export class StringController {
  @Get(':text')
  transformToUpperCase(@Param('text', UpperCasePipe) text: string) {
    return `Transformed text is: ${text}`;
  }
}

문자열을 대문자로 변환하는 Pipe를 만들었으며, 이를 특정 요청에 적용할 수 있습니다.

사용자 정의 Pipe는 Nest.js 애플리케이션에서 복잡한 데이터 처리 로직을 캡슐화하고
재사용하는 데 매우 유용합니다.

profile
에러가 나도 괜찮아 — 그건 내가 배우고 있다는 증거야.

0개의 댓글