Module 은 @Module() 데코레이터를 사용한 class 로 NestJS 가 응용프로그램 구조를 생성하는데 사용하는 MetaData 제공체이다.
각 어플리케이션에는 적어도 하나의 root module 이 존재하며 해당 root module 은 NestJS 가 어플리케이션 구조를 구성하는 시작점이 된다.
즉, NestJS 가 관계 및 의존성을 해결하기 위해 사용하는 Meta Data!
작은 크기의 프로그램의 경우 기능별 군집된 각각의 루트 모듈로 충분하지만, 큰 크기의 프로그램의 경우 의존성 끼리 묶어낸 트리의 각 노드별 Module 을 정의해 사용하는 것이 옳다고 한다.
Module 은 @Module() 데코레이터를 통해 하나의 객체를 취하는데, 해당 객체는 모듈의 필요 프로퍼티를 명시해야 한다.
모듈 클래스는 Provider Class 의 주입이 가능하다.
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
@Module({
controllers: [CatsController],
providers: [CatsService],
})
export class CatsModule {
constructor(private catsService: CatsService) {} // 모듈에 catService (provider) 주입
}
그러나 모듈 클래스 자체는 순환 종속성 으로 인해 공급자로 삽입 될 수 없다!
NestJs 는 선언된 모듈내에서 Provider 를 캡슐화 한다. (비의존성 차단)
캡슐화한 모듈을 먼저 Import 해야 해당 모듈의 Provider 를 사용 할 수 있다.
만약, 전역에서 즉시 사용하고자 하는 모듈이 있다면, @Global() 데코레이터를 사용한 모듈 정의로 모듈을 전역화해야한다.
@Global() // 모듈의 전역화
@Module({
controllers: [CatsController],
providers: [CatsService],
exports: [CatsService],
})
export class CatsModule {}
NestJS 가 내장한 강력한 모듈 기능이다. 해당 기능을 사용해 Provider 를 동적으로 등록하고 구성 할 수 있는 사용자 지정 모듈을 쉽게 생성 할 수 있다.
import { Module, DynamicModule } from '@nestjs/common';
import { createDatabaseProviders } from './database.providers';
import { Connection } from './connection.provider';
@Module({
providers: [Connection],
})
export class DatabaseModule {
static forRoot(entities = [], options?): DynamicModule { // 다이나믹 모듈을 리턴명시
const providers = createDatabaseProviders(options, entities);
return {
// 해당 Provider 는 다른 Provider에게 자신의 인수값을 삽입한 결과값을 인자로 받는다.
module: DatabaseModule, // 자신을 리턴한다 어떤의미??
global: true, // 전역으로 내보내고자 한다면..
// 즉 인스턴스의 생성 주기를 유심히 봐야한다.
// 핵심은 이 사용자 지정모듈 또한 간단히 정의하고 타 인스턴스를 불러오는 모듈을
// 동적으로 구성 할 수 있다는 점이다.
providers: providers,
exports: providers,
};
}
}
위에서 내보낸 DatabaseModule(동적 사용자 지정 모듈)을 사용하는 코드는?
import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';
@Module({
imports: [DatabaseModule.forRoot([User])], // 모듈 내부에서 사용하는 인수를 넘겨 import
// 함으로서 인스턴스 생성 가능
})
export class AppModule {}