NestJS 모듈에 대한 공부 기록이다.
모듈이란?
모듈이란 클래스나 함수 같은 소프트웨어 컴포넌트가 아닌,
여러 컴포넌트를 조합한 큰 작업을 수행할 수 있게 하는 단위이다.
가령 배달 서비스가 있다고 하면,
유저 관련 작업을 하는 UserModule, 주문 관련 작업을 하는 OrderModule 등의 여러 작업이 모여
서비스를 이루게 된다.
Nest에서는 하나의 루트 모듈이 존재하고 이 루트 모듈은 다른 모듈들로 구성된다.
모듈 생성
User 모듈을 추가한 App 모듈을 보자.
모듈은 Module 데커레이터를 사용하고, 인자로 ModuleMetadata를 전달받는다.
ModuleMetadata의 정의를 보자.
export interface ModuleMetadata {
imports?: Array<Type<any> | DynamicModule | Promise<DynamicModule> | ForwardReference>;
controllers?: Type<any>[];
providers?: Provider[];
exports?: Array<DynamicModule | Promise<DynamicModule> | string | symbol | Provider | ForwardReference | Abstract<any> | Function>;
}
- imports : 해당 모듈에서 사용하기 위해 프로바이더를 프로바이더를 가지고 있는 외부 모듈을 가져온다.
- controllers: 인스턴스화되어야 하는 컨트롤러의 집합
- providers : Nest Injector에 의해 인스턴스화되고 해당 모듈에서 공유될 수 있는 프로바이더
- export : 해당 모듈에서 제공하는 프로바이더 중 외부 모듈에서 사용해야 하는 프로바이더나 토큰의 집합
글로벌 모듈
Nest는 모듈 범위에서 프로바이더를 인스턴스화한다.
따라서 import 하지 않으면 외부 모듈의 프로바이더를 사용할 수 없다.
하지만 Global 데커레이터를 이용해 모듈을 글로벌로 생성할 수 있다.
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 {}
글로벌 모듈은 일반적으로 코어 모듈에 의해 한 번만 등록되어야 한다.
위의 CatsService 프로바이더를 주입하려는 모듈은 imports 배열에 CatsModule을 포함시키지 않아도 된다.
Global은 보일러 플레이트의 양을 줄이기 위해 주로 사용되므로
모든 module을 Global로 생성해서는 안 된다.
ex) DB 연결, helpers 등
유저 서비스의 모듈 분리
지금까지 만들어본 유저 서비스에 대해 모듈을 분리해 보자.
지금까지의 구조는
App, Users, Email 모듈이 있다.
App 모듈은 루트 모듈이고, Email 모듈은 Users 모듈의 기능 중 이메일 기능을 담당한다.
따라서 아래와 같이 모듈을 분리했다.
//app.module.ts
import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';
@Module({
imports: [UsersModule],
controllers: [],
providers: [],
})
export class AppModule {}
- UsersModule에서 EmailModule을 포함하기 때문에 UsersModule만 import 한다.
//users.module.ts
import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { EmailModule } from 'src/email/email.module';
@Module({
imports: [EmailModule],
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}
- EmailModule을 import 했다.
- EmailModule에서 providers를 제공하기 때문에 UsersModule에서 직접 제공할 필요가 없다.
//email.module.ts
import { Module } from '@nestjs/common';
import { EmailService } from './email.service';
@Module({
providers: [EmailService],
exports: [EmailModule],
})
export class EmailModule {}
- EmailService 파일로 provider를 제공한다.
- UsersModule에서 import 할 수 있게 export 해줬다.
참고
마치며
잘못된 정보에 대한 피드백은 환영입니다.
감사합니다.
'Backend > NestJS' 카테고리의 다른 글
[NestJS] NestJS 유효성 파이프 적용 이해하기(ValidationPipe) (0) | 2023.01.01 |
---|---|
[NestJS] User API 만들기(3) (파이프 Pipe 유효성 검사) (0) | 2022.12.30 |
[NestJS]User API 만들기(2) (Provider 프로바이더 회원가입 구현) (1) | 2022.12.29 |
[NestJS] User API 만들기(1)(Controller, 컨트롤러) (1) | 2022.12.28 |
[NestJS] 데커레이터 Decorator(합성, 클래스, 메서드, 매개변수) (0) | 2022.12.25 |