NestJS의 Custom Decorators
반복적인 로직을 재사용 가능하게 만들고, 코드의 가독성을 높이기 위해 사용함
NestJS에서 제공하는 기본 데코레이터(@Body(), @Query(), @Param() 등) 외에 사용자가 직접 커스텀 데코레이터 정의
Custom Decorator의 필요성
1. 반복되는 코드 제거: 컨트롤러에서 동일한 로직을 적용할 때 유용
2. 코드 가독성 향상: req.user.id 같은 접근 방식을 단순화 가능
3. Middleware 또는 Guard와 조합 가능: 사용자 인증, 권한 체크 등에 활용
Custom Decorator 사용법
1. 메소드 매개변수용 데코레이터
컨트롤러에서 매개변수 값 추출 및 변환을 쉽게 하기 위한 데코레이터
@GetUser() 데코레이터를 만들어서, JWT 인증 유저를 가져오는 예제
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
// 사용자 요청에서 user 객체를 추출하는 커스텀 데코레이터
export const GetUser = createParamDecorator(
(data: string | undefined, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return data ? request.user?.[data] : request.user;
},
);
import { Controller, Get } from '@nestjs/common';
import { GetUser } from './get-user.decorator';
@Controller('users')
export class UserController {
@Get('profile')
getProfile(@GetUser() user: any) {
return user; // request.user 반환
}
@Get('email')
getUserEmail(@GetUser('email') email: string) {
return { email }; // request.user.email 반환
}
}
GET /users/profile 요청 시 -> request.user 전체 반환
GET /users/email 요청 시 -> request.user.email 값 반환
2. 클래스/메소드용 데코레이터
특정 권한(Authorization)이나 로그 기능을 자동으로 적용할 때 유용함
@SetMetadata()를 사용해 메타데이터를 추가하고, Guard에서 활용 가능
@Roles() 데코레이터(역할 기반 권한 부여) 예제
import { SetMetadata } from '@nestjs/common';
// 역할(Role) 기반 권한 제어를 위한 커스텀 데코레이터
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
'roles'라는 키를 사용해 메타 데이터를 추가함
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.get<string[]>('roles', context.getHandler());
if (!requiredRoles) return true; // 역할 정보가 없으면 그냥 통과
const request = context.switchToHttp().getRequest();
const user = request.user; // JWT 인증된 사용자
return user && requiredRoles.includes(user.role);
}
}
@Roles() 데코레이터를 활용해 Roles Guard 구현
@Roles() 데코레이터에 @SetMetadata로 추가한 'roles' 키 값을 확인해서 역할을 확인함
RolesGuard에서 역할을 체크해 접근을 제어할 수 있음
import { Controller, Get, UseGuards } from '@nestjs/common';
import { Roles } from './roles.decorator';
import { RolesGuard } from './roles.guard';
@Controller('admin')
@UseGuards(RolesGuard) // Guard에서 역할을 확인
export class AdminController {
@Get()
@Roles('admin') // "admin" 역할을 가진 사용자만 접근 가능
getAdminData() {
return { message: 'Admin data' };
}
}
Controller에 적용한 부분
@Roles('admin')이 있는 컨트롤러 메소드에서는 RolesGuard가 역할을 확인하고
"admin" 역할이 있는 경우만 요청을 허용함
출처
[1] NestJS 공식 Docs. Custom Route Decorators https://docs.nestjs.com/custom-decorators
[2] Toss Tech 블로그. NestJS 환경에 맞는 Custom Decorator 만들기. https://toss.tech/article/nestjs-custom-decorator
[3] GPT에게 커스텀 데코레이터에 대해 묻다
'개발자 강화 > 백엔드' 카테고리의 다른 글
[매일메일] 스케일 아웃 & 스케일 업 (BE.250210) (0) | 2025.02.10 |
---|---|
🌟[공부, 개발] NestJS의 Pipes란? (0) | 2025.02.08 |
[매일메일] 캐싱 전략 (BE.250205) (0) | 2025.02.08 |
[매일메일] ACID란? (BE.250207) (0) | 2025.02.08 |
[매일메일] 동시성 제어(BE.250114/250115/250205/250106 통합) (0) | 2025.02.06 |