Nest.js에서 커스텀 데코레이터를 만드는 방법을 포스팅 하였습니다.
데코레이터를 사용하면 메서드, 클래스, 파라미터 등에 메타데이터를 추가하여
다양한 기능을 쉽게 구현할 수 있습니다.
예를 들어, 특정 메서드의 매개변수를 커스텀하게 변환하거나,
특정 권한을 체크하는 등의 작업을 수행할 수 있습니다.
Nest.js에서는 @nestjs/common 모듈에서 제공하는 createParamDecorator 함수를 이용하여 커스텀 데코레이터를 만들 수 있습니다.
// custom-header.decorator.ts
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
export const CustomHeader = createParamDecorator(
(data: string, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return request.headers[data];
},
);
이 데코레이터는 요청 객체에서 data로 전달된 헤더 값을 추출합니다.
// app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { CustomHeader } from './custom-header.decorator';
@Controller('test')
export class AppController {
@Get()
getCustomHeader(@CustomHeader('authorization') authHeader: string): string {
return `Authorization Header: ${authHeader}`;
}
}
위의 코드에서 @CustomHeader('authorization')는 요청의 authorization 헤더 값을 authHeader 매개변수에 할당합니다.
커스텀 메서드 데코레이터는 특정 메서드에 추가적인 로직을 적용할 수 있습니다.
예를 들어, 메서드 실행 전/후에 특정 작업을 수행하도록 할 수 있습니다.
// logging.decorator.ts
import { SetMetadata } from '@nestjs/common';
export const Logging = (message: string) => SetMetadata('loggingMessage', message);
// app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { Logging } from './logging.decorator';
@Controller('test')
export class AppController {
@Get()
@Logging('This is a logging message')
getHello(): string {
return 'Hello World!';
}
}
위의 @Logging 데코레이터는 SetMetadata를 사용하여
loggingMessage 메타데이터를 설정합니다.
이 메타데이터를 Guard, Interceptor, Pipe 등에서 활용하여 원하는 로직을
구현할 수 있습니다
Nest.js의 Guards와 함께 커스텀 데코레이터를 사용하면 권한 관리 로직을 효율적으로 구현할 수 있습니다.
// roles.decorator.ts
import { SetMetadata } from '@nestjs/common';
export const Roles = (...roles: string[]) => SetMetadata('roles', roles);
// roles.guard.ts
import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const roles = this.reflector.get<string[]>('roles', context.getHandler());
if (!roles) {
return true;
}
const request = context.switchToHttp().getRequest();
const user = request.user;
return roles.some((role) => user.roles?.includes(role));
}
}
// app.controller.ts
import { Controller, Get, UseGuards } from '@nestjs/common';
import { Roles } from './roles.decorator';
import { RolesGuard } from './roles.guard';
@Controller('test')
@UseGuards(RolesGuard)
export class AppController {
@Get()
@Roles('admin')
getAdminContent(): string {
return 'Admin Content';
}
}
위의 코드는 @Roles 데코레이터를 사용하여 admin 권한이 있는 사용자만
접근할 수 있도록 설정합니다.
스텀 데코레이터를 만드는 것은 매우 간단하며, 다양한 기능을 구현하는 데 매우 유용합니다.
데코레이터와 Guard, Interceptor, Pipe 등의
기능을 함께 사용하면 복잡한 비즈니스 로직도 손쉽게 구현할 수 있다는것을 배웠습니다.