Modules

Moudles

@Module() 데코레이터는 어플리케이션 구성에 필요한 metadate를 공급한다.

애플리케이션은 최소 한개 이상의 모듈이 존재햐아 하고 구성 요소를 구성하는 효과적인 방법으로 모듈을 사용한다. 아주 작은 애플리케이션이 아닌 일반적인 애플리케이션은 여러가지 모듈을 가진다.

모듈은 provider 를 캡슐화 한다. 즉 현제 모듈의 일부도 아니고 가져온 모듈에서 내보낸 것도 아닌 provider 를 주입하는것은 불가능하다.

Feature modules

생성한 controller와 service 는 어떤 기능에 연관되 있기 때문에 하나의 모듈로 만들어서 관리하는 것이 좋다. netst g module <이름> 으로 모듈을 생성할 수 있다.

Shared modules

nest 에서 모듈은 기본적으로 singletons 이다. 따라서 같은 인스턴스를 다양한 모듈에서 공유할 수 있다. 여러 다른 모듈 간의 특정 모듈에 속해 있는 서비스를 공유하고 싶다면 @Module 데코레이터에서 exports 하여 특정 서비스를 내보내야 한다.

1
2
3
4
5
6
7
8
9
10
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
controllers: [CatsController],
providers: [CatsService],
exports: [CatsService]
})
export class CatsModule {}

CatService 를 내보내서 다른 모듈에서 같은 인스턴스를 사용하도록 한다.

Module re-exporting

특정 모듈을 임포트하고 다시 내보낼수도 있다. CommonModule은 CoreModule로 가져오거나 CoreModule에서 내보내어 이 모듈을 가져오는 다른 모듈에서 사용할 수 있다.

1
2
3
4
5
@Module({
imports: [CommonModule],
exports: [CommonModule],
})
export class CoreModule {}

Dependency injection

모듈은 Provider 도 주입할 수 있다. (구성 하기 위한 목적으로 )

1
2
3
4
5
6
7
8
9
10
11
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) {}
}

그러나 순환 참조가 될수 있기 때문에 모듈 자체를 Porivder로 주입하는 것은 불가능하다.

Global modules

모든 곳에서 import 하는 같은 모듈을 계속 import 하는 것은 바보같은 짓이다. 그러나 nest 에서는 Provider를 캡슐화 하기 때문에 Provider 를 가져오지 않고는 다른 곳에서 사용할 수 없다.

어느 곳에서나 접근 가능한 Provider 집합을 제공하려는 경우, @Global 데코레이터를 사용하여 사용해야 한다.

1
2
3
4
5
6
7
8
9
10
11
import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Global()
@Module({
controllers: [CatsController],
providers: [CatsService],
exports: [CatsService],
})
export class CatsModule {}

이렇게 하면 모듈을 global-scope 에 있도록 만들 수 있다. 전역 모듈은 일반적으로 루트 또는 코어 모듈에서 한번만 등록해야 한다. 이렇게 등록한 모듈 내에 있는 Provider 는 어떠한 다른 모듈에서 import 모듈에 등록할 필요 없이 inject 할 수 있다.

Dynamic modules

Nest 에서는 쉽게 등록 가능한 모듈을 동적으로 만들 수 있고, Provider를 구성할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 {
module: DatabaseModule,
providers: providers,
exports: providers,
};
}
}

forRoot 메서드는 동기식 또는 비동기식으로 모듈을 반환할 수 있다.

DatabaseModule 는 다음과 같은 방법으로 import 될 수 있다.

1
2
3
4
5
6
7
8
import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';

@Module({
imports: [DatabaseModule.forRoot([User])],
})
export class AppModule {}

동적 모듈을 다시 내보내려면 내보내기 배열에서 forRoot() 메서드 호출을 생략 할 수도 있다.