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 코드
'개발자 강화 > 백엔드' 카테고리의 다른 글
[매일메일] 스케일 아웃 & 스케일 업 (BE.250210) (0) | 2025.02.10 |
---|---|
🌟[공부] NestJS의 Custom Decorators란? (0) | 2025.02.09 |
[매일메일] 캐싱 전략 (BE.250205) (1) | 2025.02.08 |
[매일메일] ACID란? (BE.250207) (0) | 2025.02.08 |
[매일메일] 동시성 제어(BE.250114/250115/250205/250106 통합) (0) | 2025.02.06 |