레디스 캐싱 데코레이터를 만들다가 레디스 서비스를 데코레이팅 함수가 포함된 서비스에 inject해야 하는 번거로움이 있어 [블로그] 를 참고하여 해결하였다. 관련 개념을 정리하고 어떻게 해결하였는지 및 Nest.js 가 이를 어떻게 활용하는지 정리해보았다.

문제 상황

nestjs provider를 사용하는 데코레이터의 경우 데코레이터를 선언하는 것만으로는 정상 동작하지 않고, provider를 주입해주어야 함. 이를 주석과 문서화로 해결하기보다는 다른 방법을 찾기로 했다.

Reflection

런타임에 코드의 구조(클래스, 메서드, 속성 등)를 읽고 수정하는 기능
 

데코레이터

선언형 문법을 통해 클래스가 정의될 때 클래스 및 그 멤버들을 확장(augment)할 수 있는 기능

Reflect-metadata

weakmap을 이용하여 메타데이터 저장/조회 기능을 제공하는 라이브러리이다.

  • reflect 사용 예

해결 방법

레디스 캐싱 데코레이터 로직 내부에 데코레이트 할 대상 클래스에 특정 메타데이터를 추가하는 부분을 추가하고, 서버 구동 시 해당 메타데이터가 있는 클래스를 찾아 레디스 서비스를 주입하도록 했다.

구현상의 한계

데코레이터를 선언하면 맨 아래부터 동작하는데, 같은 메타데이터를 수정하는 여러 데코레이터를 적용하는 경우 경우 최상단의 데코레이터만 적용된다는 제한이 있다. 대표적인 예로 swagger의 apiHideProperty가 있다.

Nest.js 에서의 활용

Nest.js도 reflect-metadata를 활용한다. 대표적으로 Dependency Injection 과 swagger decorator 가 있다.
그 중 DI 과정을 요약하면 다음과 같다.
 

(참고) ECMA Script의 Reflect API

Proxy 생성 및 조작을 단순화하는 내장 객체이다. Reflect 객체는[[Get]], [[Set]]과 같은 ECMAScript 사양에서만 정의된 메서드로 직접 호출할 수 없는 내부메서드를 직접 호출할 수 있도록 도와둔다.

출처

 
 

+ Recent posts