ํฐ์คํ ๋ฆฌ ๋ทฐ
๐งผ NestJS Pipes ์๋ฒฝ ๊ฐ์ด๋ – ์ ํจ์ฑ ๊ฒ์ฆ๊ณผ ๋ฐ์ดํฐ ๋ณํ์ ํต์ฌ
octo54 2025. 4. 18. 11:20๐งผ NestJS Pipes ์๋ฒฝ ๊ฐ์ด๋ – ์ ํจ์ฑ ๊ฒ์ฆ๊ณผ ๋ฐ์ดํฐ ๋ณํ์ ํต์ฌ
NestJS์์ **Pipe(ํ์ดํ)**๋ ์
๋ ฅ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ณต, ๊ฒ์ฆ, ๋ณํํ๋ ๋๊ตฌ์
๋๋ค.
์ด ๊ธ์ NestJS ๊ณต์ ๋ฌธ์ Pipes๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๊ธ ๋ฒ์ญ + ์ค๋ฌด ์ค์ฌ ํด์ค๋ก ๊ตฌ์ฑํ์ต๋๋ค.
"๋ฐฑ์๋์ ํ์ง์ ์ ๋ ฅ ๊ฒ์ฆ์์ ๊ฒฐ์ ๋ฉ๋๋ค."
NestJS์ Pipe๋ฅผ ์ ์ฐ๋ฉด DTO + Validation + Type ๋ณํ๊น์ง ํ ๋ฒ์ ํด๊ฒฐ๋ฉ๋๋ค!
โ Pipe๋?
- ์์ฒญ(Request)์์ ๋ค์ด์จ ๋ฐ์ดํฐ๋ฅผ ๋ณํ(transform) ํ๊ฑฐ๋ ๊ฒ์ฆ(validate) ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
- NestJS์์๋ @Body(), @Param(), @Query() ๋ฑ์์ ์๋์ผ๋ก ํ์ดํ๋ฅผ ์ ์ฉํ ์ ์์ต๋๋ค.
- Express์ middleware์ ๋ฌ๋ฆฌ, ๋ฐ์ดํฐ ๋ ๋ฒจ์์ ์๋ํ๋ ์ ์ฒ๋ฆฌ๊ธฐ๋ผ๊ณ ๋ณด๋ฉด ๋ฉ๋๋ค.
1๏ธโฃ ๊ธฐ๋ณธ 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;
}
}
2๏ธโฃ Pipe ์ฌ์ฉ ๋ฐฉ๋ฒ
@Get(':name')
getUser(@Param('name', UppercasePipe) name: string) {
return `์ฌ์ฉ์ ์ด๋ฆ: ${name}`;
}
- @Param()์ Pipe๋ฅผ ์ฐ๊ฒฐํ๋ฉด ์์ฒญ ํ๋ผ๋ฏธํฐ๊ฐ ๋ณํ๋ ๊ฐ์ผ๋ก ๋ค์ด์ต๋๋ค.
- ์ด ์์ ์์๋ GET /users/john → ์ฌ์ฉ์ ์ด๋ฆ: JOHN ์ด ๋ฉ๋๋ค.
๐บ ๊ด๊ณ
์ด ์ง์ ์ ์ค๋ฌด ํ์ดํ ์ ์ฉ ์์๊ฐ ๋์ค๋ ๊ตฌ๊ฐ์ผ๋ก, ์ ๋์ผ์ค ํด๋ฆญ๋ฅ ์ด ๋์ ์์ญ์ ๋๋ค.
<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-XXXXXXX"
data-ad-slot="YYYYYYY"
data-ad-format="auto"
data-full-width-responsive="true"></ins>
3๏ธโฃ ValidationPipe – NestJS์ ์ ํจ์ฑ ๊ฒ์ฆ ํต์ฌ
class-validator์ class-transformer ํจํค์ง๋ฅผ ํจ๊ป ์ฌ์ฉํ์ฌ DTO ๊ธฐ๋ฐ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ํ ์ ์์ต๋๋ค.
์ค์น
npm install class-validator class-transformer
DTO ์์
import { IsString, IsInt, MinLength } from 'class-validator';
export class CreateUserDto {
@IsString()
@MinLength(2)
name: string;
@IsInt()
age: number;
}
Controller์ ์ ์ฉ
@Post()
create(@Body(new ValidationPipe()) body: CreateUserDto) {
return body;
}
- ์์ฒญ Body๊ฐ DTO ์กฐ๊ฑด์ ๋ง์ง ์์ผ๋ฉด 400 ์๋ฌ ๋ฐํ
- ์๋์ผ๋ก ํ์ ๋ณํ๋ ์ํ (transform: true ์ต์ ์)
๊ธ๋ก๋ฒ ํ์ดํ ์ ์ฉ (์ ์ญ ์ ํจ์ฑ ๊ฒ์ฌ)
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(
new ValidationPipe({
transform: true,
whitelist: true, // DTO์ ์ ์๋ ๊ฐ๋ง ํ์ฉ
forbidNonWhitelisted: true, // ์ ์๋์ง ์์ ํ๋๋ ์๋ฌ ์ฒ๋ฆฌ
}),
);
await app.listen(3000);
}
์ค๋ฌด์์๋ global-pipe + DTO + class-validator ์กฐํฉ์ด ๊ฑฐ์ ํ์ค์ ๋๋ค.
4๏ธโฃ Built-in Pipes (NestJS ๊ธฐ๋ณธ ์ ๊ณต ํ์ดํ๋ค)
Pipe ์ค๋ช
ParseIntPipe | ๋ฌธ์์ด์ ์ ์๋ก ๋ณํ |
ParseBoolPipe | ๋ฌธ์์ด์ boolean์ผ๋ก ๋ณํ |
ParseArrayPipe | ๋ฌธ์์ด์ ๋ฐฐ์ด๋ก ๋ณํ |
DefaultValuePipe | ๊ฐ์ด undefined์ผ ๊ฒฝ์ฐ ๊ธฐ๋ณธ๊ฐ ์ค์ |
ValidationPipe | DTO ๊ธฐ๋ฐ ์ ํจ์ฑ ๊ฒ์ฆ |
5๏ธโฃ ์ปค์คํ Pipe ์ค๋ฌด ์์ – ํ๊ตญ ์ ํ๋ฒํธ ํ์ ํํฐ
@Injectable()
export class PhoneNumberPipe implements PipeTransform {
transform(value: string): string {
if (!/^01[0-9]-\d{3,4}-\d{4}$/.test(value)) {
throw new BadRequestException('์๋ชป๋ ์ ํ๋ฒํธ ํ์์
๋๋ค');
}
return value;
}
}
๐ง ์ค๋ฌด ์์ฝ ์ ๋ต
์์น Pipe ์ ์ฉ ์ค๋ช
@Param() | ParseIntPipe ๋ฑ์ผ๋ก ๊ฒฝ๋ก ๋งค๊ฐ๋ณ์ ์ฒ๋ฆฌ | |
@Query() | ์ฟผ๋ฆฌ ๋ฌธ์์ด์ ํ์ ๋ณํ | |
@Body() | DTO + ValidationPipe → ์์ ํ ์ ๋ ฅ ๊ฒ์ฆ ์์คํ | |
Global | app.useGlobalPipes(...)๋ก ์ ์ญ ์ ์ฉ |
๐ ๋ง๋ฌด๋ฆฌ ์์ฝ
- Pipe๋ NestJS์ ๊ฐ๋ ฅํ ์ ์ฒ๋ฆฌ ์ ํจ์ฑ ๊ฒ์ฌ ๋๊ตฌ
- DTO + class-validator๋ก ํ์ ๊ฒ์ฆ ๊ฐ๋ฅ
- ์ปค์คํ Pipe๋ก ์ ์ฐํ ๋น์ฆ๋์ค ๋ก์ง ์ ์ฉ
- ๊ธ๋ก๋ฒ Pipe ์ค์ ์ ํตํ ์ ์ญ ์ผ๊ด์ฑ ์ ์ง
NestJS Pipe,NestJS ValidationPipe,NestJS ์ ํจ์ฑ๊ฒ์ฌ,NestJS DTO ๊ฒ์ฆ,NestJS class-validator,NestJS ๊ธ๋ก๋ฒ ํ์ดํ,NestJS Pipe ์ค๋ฌด ์์ ,NestJS ํ์ ๋ณํ,NestJS ์์ฒญ ๊ฒ์ฆ,NestJS ๋ฐฑ์๋ ๋ณด์
'framework > NestJS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
- Total
- Today
- Yesterday
- CI/CD
- App Router
- seo ์ต์ ํ 10๊ฐ
- nextJS
- ํ๋ก ํธ์๋
- Docker
- fastapi
- AI์ฑ๋ด
- ๋ฐฑ์๋๊ฐ๋ฐ
- JAX
- NestJS
- nodejs
- ํ์ด์ฌ ์๊ณ ๋ฆฌ์ฆ
- SEO์ต์ ํ
- SEO ์ต์ ํ
- Prisma
- Ktor
- ๋ฅ๋ฌ๋
- ๊ฐ๋ฐ๋ธ๋ก๊ทธ
- llm
- kotlin
- ํ๋ก ํธ์๋๋ฉด์
- ์น๊ฐ๋ฐ
- Webpack
- Python
- Next.js
- gatsbyjs
- rag
- PostgreSQL
- REACT
์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |