레디스 캐싱 데코레이터를 만들다가 레디스 서비스를 데코레이팅 함수가 포함된 서비스에 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 과정을 요약하면 다음과 같다.
- 데코레이터
- @Injectable()이 붙은 클래스(예: 서비스)를 DI 컨테이너에 등록
- https://github.com/nestjs/nest/blob/master/packages/common/decorators/core/injectable.decorator.ts
- 인젝터
- 클래스(예: 컨트롤러) 생성자의 매개변수 타입 정보를 reflect-metadata로 조회
- DI 컨테이너(moduleRef)에서 해당 타입(예: 서비스)의 인스턴스를 찾아 자동으로 생성하고 주입
- https://github.com/nestjs/nest/blob/master/packages/core/injector/injector.ts#L271
(참고) ECMA Script의 Reflect API
Proxy 생성 및 조작을 단순화하는 내장 객체이다. Reflect 객체는[[Get]], [[Set]]과 같은 ECMAScript 사양에서만 정의된 메서드로 직접 호출할 수 없는 내부메서드를 직접 호출할 수 있도록 도와둔다.
출처
- 모던자바스크립트 - proxy와 reflect (https://ko.javascript.info/proxy)
- reflect-metadata
'기술 조사 > 기타' 카테고리의 다른 글
| Elasticsearch 에 인덱싱할 때 CPU 이슈 (2) | 2026.02.24 |
|---|---|
| prisma의 마이그레이션 히스토리 관리와 개발 생산성 사이의 고민 (0) | 2026.02.08 |
| Nestjs(TypeScript) GraphQL 을 사용할 때 Enum 타입 아규먼트의 기본값 설정 이슈 (2) | 2025.04.12 |
| DataLoader 는 어떻게 GraphQL의 1+N 문제를 해결하는지 (7) | 2024.11.07 |