NestJS 공식 문서 Custom decorators

GGAE99·2023년 6월 27일
0

NestJS 공식 문서

목록 보기
3/33

Custom route decorators

네스트는 데코레이터라는 언어 기능을 활용해서 만들어졌습니다.
데코레이터는 많은 프로그래밍 언어에서 사용되는 흔한 컨셉이지만, 자바스크립트에는 비교적 새롭습니다.
데코레이터가 어떻게 동작하는지 좀 더 잘 알아듣기 위해, 이 아티클을 읽어보는 것을 추천합니다.
간단하게 정의하면 아래와 같습니다.

ES2016 데코레이터는 함수를 반환하는 표현식으로, target, name, 그리고 property descriptor를 인자로 받을 수 있다. 데코레이터 앞에 @ 문자를 붙이고 데코레이트 하고자 하는 것의 위에 놓음으로써 적용할 수 있다. 데코레이터는 클래스/메서드/프로퍼티를 위해 정의되고 적용될 수 있다.

Nest는 HTTP 라우트 핸들러와 함께 사용할 수 있는 유용한 파라미터 데코레이터를 제공합니다.
거기에 추가적으로, 직접 커스텀 데코레이터를 만들어서 사용할 수 있습니다.

Node js 세계에서, req 객체에 프로퍼티를 추가적으로 붙이는 일이 굉장히 흔한 일입니다.
이후 이렇게 붙인 프로퍼티를 라우트 핸들러 단에서 추출하여 사용하게 됩니다.

const user = req.user;

코드의 가독성을 높이고, 투명하게 만들기 위해 데코레이터를 만들어 @User()모든 컨트롤러에서 재사용할 수 있습니다.

import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.user;
  },
);

Passing data

다음과 같은 유저를 사용한다고 가정해봅시다.

{
  "id": 101,
  "firstName": "Alan",
  "lastName": "Turing",
  "email": "alan@email.com",
  "roles": ["admin"]
}

속성 이름을 키로 사용하는 데코레이터를 정의하고, 존재하는 경우 (또는 존재하지 않는 경우 또는 사용자개체가 생성되지 않은 경우에는 정의되지 않은) 연관된 값을 반환합니다.

// user.decorator.ts
import { createParamDecorator, ExecutionContext } from '@nestjs/common';

export const User = createParamDecorator(
  (data: string, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    const user = request.user;

    return data ? user?.[data] : user;
  },
);
@Get()
async findOne(@User('firstName') firstName: string) {
  console.log(`Hello ${firstName}`);
}

Working with pipes

기본적으로 Nest는 커스텀 데코레이터에 Pipe를 적용해주지 않기 때문에, 따로 Pipe를 사용하는 설정이 필요합니다.

@Get()
async findOne(
  @User(new ValidationPipe({ validateCustomDecorators: true }))
  user: UserEntity,
) {
  console.log(user);
}

Decorator composition

네스트는 여러 데코레이터를 compose 할 수 있는 헬퍼 메서드를 제공해줍니다.
예를 들어, auth에 관련된 모든 데코레이터를 하나로 합치고 싶다면, 이런 방식을 사용할 수 있습니다.

// auth.decorator.ts
import { applyDecorators } from '@nestjs/common';

export function Auth(...roles: Role[]) {
  return applyDecorators(
    SetMetadata('roles', roles),
    UseGuards(AuthGuard, RolesGuard),
    ApiBearerAuth(),
    ApiUnauthorizedResponse({ description: 'Unauthorized' }),
  );
}

이후 커스텀 @Auth() 데코레이터를 다음과 같이 사용할 수 있습니다.

@Get('users')
@Auth('admin')
findAllUsers() {}

0개의 댓글