반응형
간단 소개
- Nest 버전 8에서 나온 최신 방법! 7미만이면 LazyModuleLoader를 불러오지도 못한다..
- lazyModuleLoader를 찾을 수 없다면 NestCLI의 버전을 체크하고 업데이트 해주길 바란다!
- 기존의 Module Load → Bootstrap과 동시에 모든 모듈 로드
- Lazy-loading Modules 기법 → 필요한 모듈만 로드하여 부트스트랩 시간 단축
사용 방법
// cats.service.ts
@Injectable()
export class CatsService {
constructor(private lazyModuleLoader: LazyModuleLoader) {}
}
Or
// main.ts
import { LazyModuleLoader, NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const lazyModuleLoader = app.get(LazyModuleLoader) // <- 이렇게도 호출 가능
await app.listen(3000);
}
bootstrap();
위와 같은 방법으로 lazyModuleLoader 객체를 얻는다.
그 후 공식 문서에 따르면 아래와 같은 방법으로 쓴다.
const { LazyModule } = await import('./lazy.module');
const moduleRef = await this.lazyModuleLoader.load(() => LazyModule);
여기서 나오는 moduleRef 는 공식문서의 바로 전 장에 나오는 Module Reference 에서 나오는 인스턴스로서 module reference라는 말의 의미 그대로 get() 메소드를 통해 해당 모듈에 인스터스화된 provider 등을 불러올 수 있다.
예제
//dog.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class DogService {
constructor() { }
bark(): string {
return 'wall wall'
}
}
import { Injectable } from '@nestjs/common';
import { LazyModuleLoader } from '@nestjs/core';
import { DogService } from 'src/dog/dog.service';
@Injectable()
export class CatService {
private service: DogService;
constructor(private lazyModuleLoader: LazyModuleLoader) { }
async dogBark(): Promise<any> {
await this.changeToDog()
return this.service.bark() // -> wall wall 출력
}
async changeToDog() {
const { DogModule } = await import('../dog/dog.module')
const moduleRef = await this.lazyModuleLoader.load(() => DogModule) // 이 순간 Load
this.service = moduleRef.get(DogService)
}
}
위 예제에서 dogModule은 app.module에 등록되어 있지 않아 첫 Bootstrap에 Load되지 않는다.
changeToDog 메소드 안의 lazyModuleLoader.load가 호출될 때 지정된 dogModule이 Load되어 캐싱된다.
즉 changeToDog 메소드가 다시호출되어 lazyModuleLoader.load가 다시 실행되더라도 dogModule은 이미 캐싱되어있기에 첫 호출보다 더 빠른 속도로 실행된다.
만약 dogService에 비동기적 요소가 들어가 있다면 공식문서에 나온 아래와 같은 방법을 사용하여 service를 불러오면 될 것 같다.
const { LazyService } = await import('./lazy.service');
const lazyService = moduleRef.get(LazyService);
주의사항
- Nest의 Controller(GraphQL의 resolver) 는 Lazy-Load 불가능
- app이 부트스트랩 된 후 route를 등록할 수 없다!
- pub/sub 패턴을 사용할 경우에도 연결 설정 전에 미리 구독/수신 해야함
- GraphQL은 모든 클래스 미리 로드해야함
- 메타데이터를 기반으로 즉석에서 GraphQL 스키마를 자동으로 생성하기 때문
결론
- Monolithic Architecture에서는 큰 의미를 가지지 않는다.
- 필요한 모듈만 로드하기 때문에 Serverless 환경에서 Bootstrap의 병목을 줄여준다!
Reference
반응형
'Node.js > Nest.js' 카테고리의 다른 글
NestJS - Decorator를 활용한 Discord봇 개발환경 개선 (0) | 2023.03.16 |
---|---|
[TypeORM] Active Recore & Data Mapper Pattern (0) | 2021.08.30 |
NestJS Provider(프로바이더) (0) | 2021.08.19 |