[NestJS] 커스텀 데코레이터 만들기

2022. 11. 21. 22:50·라이브러리 & 프레임워크/NestJS

데코레이터란?

데코레이터는 대다수의 프로그래밍 언어에 사용되는 잘 알려진 개념이지만 JavaScript 세계에서는 도입된지 얼마되지 않은 개념이라고 합니다.

데코레이터에 대해 공식 문서에서는 이렇게 정의하고 있습니다.

An ES2016 decorator is an expression which returns a function and can take a target, name and property descriptor as arguments. You apply it by prefixing the decorator with an @ character and placing this at the very top of what you are trying to decorate. Decorators can be defined for either a class, a method or a property.

데코레이터는 함수를 반환하며 인자로는 타겟, 이름, 프로퍼티 설명자를 가지는 표현식입니다.

데코레이터 앞에 @ 문자를 붙여 사용하면 되며, 이는 데코레이트하고자 하는 클래스, 메서드, 프로퍼티의 최상단에 위치시켜 줍니다.

데코레이터는 함수에서 코드를 바꾸지 않고 추가하거나 수정하고 싶을 때 사용하는 문법입니다.

데코레이터 실제 사용 예시

- 로그 남기기

- 접근 제어와 인증 처리

- API 로직 처리 시간 측정

- API 호출 수 제한

- 캐싱

데코레이터를 사용하는 이유?

기존에 만들어진 함수가 다른 곳에서 이미 많이 사용되고 있을 때 (= 함수 코드의 변경이 어려운 경우) 코드를 변경하지 않고, 필요한 내용을 추가하거나 수정하고 싶을 때 사용합니다.

// 컨트롤러 1 동작 흐름
A -> C -> D -> G
// 컨트롤러 2 동작 흐름
A -> B -> G
// 컨트롤러 3 동작 흐름
A -> E -> F -> C -> G

각 컨트롤러 별 동작 흐름을 살펴보면 공통적으로 포함되어 사용되는 A 와 G 가 있습니다.

DRY(Don't Repeat Yourself) 원칙에 따라 A와 G가 포함된 함수를 별도로 선언하고 사용되면 좋겠다고 느껴질 것입니다.

데코레이터는 코드의 중복을 제거해 코드의 재사용성을 높이기 위해 사용한다고 이해할 수 있습니다.

NestJS 에 존재하는 데코레이터

NestJS 에는 많은 데코레이터가 존재합니다.

대표적으로, @Body(), @Param(), @Query() 등 데코레이터를 통해 특정 요청에 대한 값을 가져올 수 있습니다.

예를 들어, 리퀘스트 바디 값을 가져오기 위해서는 이렇게 작성합니다.

Express 라면,

const data = req.body;

하지만 NestJS 에서는 좀 더 가독성을 높이고 req 에 대한 의존도를 줄이기 위해 @Body() 데코레이터를 사용할 수 있습니다.

joinUser(@Body('user') joinUserDto: JoinUserDto)

이런 식으로 req.body 안에 있는 user 의 값을 joinUserDto 라는 변수에 쉽게 저장할 수 있습니다.

커스텀 데코레이터

위에서 설명한 데코레이터를 커스텀하여 사용할 수 있습니다.

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

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

@nestjs/common 으로부터 createParamDecorator 를 사용하여 커스텀 데코레이터를 만들어주면 됩니다.

그리고 ctx.switchToHttp().getRequest(); 를 통해 request 에 접근할 수 있습니다.

참고) ExecutionContext 타입의 ctx 에 대하여
커스텀 데코레이터를 생성할 때 사용하는 createParamDecorator 함수에 인자로 들어가는 콜백 함수 안에서 ExecutionContext 타입의 ctx 를 통해 동시에 http, websocket, rpc 프로토콜 정보를 가져올 수 있습니다.

ctx 변수에는 현재 데코레이터가 어떤 환경에서 실행되고 있는지에 대한 정보가 컨텍스트 안에 들어 있습니다.

위 함수는 request 로부터 user 데이터만을 전달하는 데코레이터입니다.

 

방금 만든 데코레이터를 컨트롤러에 적용하면 다음과 같습니다.

@Post()
joinUser(@User() user) {
  console.log(user);
}

user 데코레이터를 만들어 두니 req.user 정보가 필요한 모든 컨트롤러에 적용 가능해서 코드 재사용성을 높일 수 있어서 좋습니다.

게다가 컨트롤러의 request 에 대한 의존성을 없애주어 테스트가 용이하게 되어 좋습니다.

정리

이번 시간을 통해 데코레이터가 무엇이고 언제 사용되고 왜 쓰이는지와 NestJS 에서 제공되는 데코레이터들, 커스텀 데코레이터를 만드는 방법에 대해 알아보았습니다.

이번 시간에 소개한 데코레이터들 외에 다양한 데코레이터가 있으니 자세한 사용방법은 nest js 공식문서를 참고해주시면 될 것 같습니다.

출처

https://www.inflearn.com/course/%EC%8A%AC%EB%9E%99%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9-%EB%B0%B1%EC%97%94%EB%93%9C 

https://devkhk.tistory.com/23 

 

[python] decorator 파이썬 데코레이터 이해하기

데코레이터는 함수에서 코드를 바꾸지 않고 추가하거나 수정하고 싶을 때 사용하는 문법이다. 처음 이해하기 조금 난해할 수 있지만 사용 이유, 단순하게 이해할 수 있는 순서 그리고 현실적인

devkhk.tistory.com

https://docs.nestjs.com/custom-decorators#param-decorators

 

Documentation | NestJS - A progressive Node.js framework

Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Progamming), FP (Functional Programming), and FRP (Functional Reac

docs.nestjs.com

 

'라이브러리 & 프레임워크 > NestJS' 카테고리의 다른 글

Exception filter  (0) 2022.11.28
Validation  (0) 2022.11.28
Mapped Types  (0) 2022.11.28
[TypeORM] 마이그레이션  (0) 2022.11.27
[TypeORM] TypeORM 엔티티 상속을 통한 중복 코드 제거  (0) 2022.11.26
'라이브러리 & 프레임워크/NestJS' 카테고리의 다른 글
  • Validation
  • Mapped Types
  • [TypeORM] 마이그레이션
  • [TypeORM] TypeORM 엔티티 상속을 통한 중복 코드 제거
rondeveloper
rondeveloper
  • rondeveloper
    Ron's learning record
    rondeveloper
  • 전체
    오늘
    어제
    • 분류 전체보기 (102)
      • k8s (2)
      • AWS (1)
      • 리눅스 (5)
      • Docker (8)
      • 라이브러리 & 프레임워크 (14)
        • React (2)
        • NestJS (8)
        • Spring (0)
        • Django (3)
        • FastAPI (1)
      • 웹 (2)
        • Nginx (1)
      • 프로그래밍 언어 (29)
        • HTML (0)
        • CSS (0)
        • JavaScript (21)
        • Python (3)
        • Node.js (0)
        • TypeScript (4)
        • Java (1)
      • Today I learned (9)
      • 알고리즘 (9)
        • 백준 (0)
        • 프로그래머스 (8)
        • 개념 (1)
      • 티끌모아 태산 (5)
        • 하루에 영단어 하나씩 (5)
        • 독서 (0)
      • 시행착오 (3)
      • 데이터베이스 (2)
        • MySQL (0)
      • 컴퓨터 과학 (8)
        • 네트워크 (2)
        • 운영체제 (0)
        • 데이터베이스 (2)
        • 자료구조 (4)
      • 포트폴리오 (4)
        • JJINCAFE IN SEOUL (4)
        • CODEUNICORN (0)
      • 회고 (0)
      • CICD (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Docker
    FastAPI
    Kubernetes
    Kubectl
    컨테이너
    네트워크
    기초
    생활코딩
    레벨2
    iterable
    django
    조인
    반복문
    모듈
    Til
    배열
    javascript
    Python
    IP 주소
    코딩테스트
    typeorm
    mysql
    자바스크립트
    도커
    리눅스
    typescript
    스택
    nestjs
    redis
    프로그래머스
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
rondeveloper
[NestJS] 커스텀 데코레이터 만들기
상단으로

티스토리툴바