4장: 모듈 - 코드의 체계적인 정리와 캡슐화
모듈(Module)은 NestJS 애플리케이션의 아키텍처를 구성하는 기본 단위입니다. 관련된 기능(컨트롤러, 프로바이더 등)들을 하나의 모듈로 묶어 코드를 체계적으로 관리하고, 애플리케이션의 구조를 명확하게 만듭니다.
1. 핵심 개념
모듈 (
@Module):@Module()데코레이터가 붙은 클래스입니다. 이 데코레이터는 NestJS가 애플리케이션 구조를 구성하는 데 사용하는 메타데이터를 제공하는 객체를 인자로 받습니다.@Module데코레이터의 주요 속성:providers: 이 모듈 내에서 사용될 프로바이더(서비스 등)의 배열입니다. 여기에 등록된 프로바이더는 NestJS의 DI 컨테이너에 의해 인스턴스화되고, 이 모듈 내의 다른 구성 요소에 주입될 수 있습니다.controllers: 이 모듈에서 정의할 컨트롤러의 배열입니다.imports: 다른 모듈을 가져올 때 사용합니다.imports배열에 포함된 모듈에서export한 프로바이더들을 현재 모듈 내에서 사용할 수 있게 됩니다.exports: 현재 모듈의 프로바이더 중 일부를 다른 모듈에서 사용할 수 있도록 외부에 공개할 때 사용합니다.providers에 등록된 프로바이더만export할 수 있습니다.
기능 모듈 (Feature Modules): 특정 기능(예: 사용자, 게시물, 주문)과 관련된 컨트롤러, 프로바이더 등을 묶어놓은 모듈입니다. 애플리케이션을 기능 단위로 분리하여 유지보수성을 높입니다.
루트 모듈 (Root Module): 애플리케이션의 진입점이 되는 최상위 모듈입니다. 보통
AppModule이라고 부르며, 다른 모든 기능 모듈들을imports하여 애플리케이션 전체를 조립하는 역할을 합니다.
2. 모듈 생성 및 애플리케이션 조립
CLI로 모듈 생성:
users기능에 대한 컨트롤러와 서비스를 포함하는 모듈을 생성해봅시다.nest generate module users # 단축 명령어: nest g mo userssrc/users/users.module.ts파일이 생성됩니다.- CLI는 자동으로
AppModule의imports배열에UsersModule을 추가해줍니다.
기능 모듈 구성 (
users.module.ts):UsersController와UsersService를UsersModule에 등록합니다.// src/users/users.module.ts import { Module } from '@nestjs/common'; import { UsersController } from './users.controller'; import { UsersService } from './users.service'; @Module({ controllers: [UsersController], // UsersModule이 담당할 컨트롤러 providers: [UsersService] // UsersModule이 담당할 프로바이더 }) export class UsersModule {}루트 모듈 구성 (
app.module.ts): 루트 모듈에서는UsersModule을imports하기만 하면 됩니다.// src/app.module.ts import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { UsersModule } from './users/users.module'; // UsersModule 임포트 @Module({ imports: [UsersModule], // UsersModule을 가져와서 사용 controllers: [AppController], providers: [AppService], }) export class AppModule {}- 이제
AppModule은UsersModule의 존재를 알게 되고,UsersModule에 정의된/users관련 라우팅이 활성화됩니다.
- 이제
3. 예제: 모듈 간 프로바이더 공유
AuthModule에서 제공하는 AuthService를 UsersModule에서 사용하고 싶다고 가정해봅시다.
AuthModule에서 서비스export하기:// src/auth/auth.module.ts import { Module } from '@nestjs/common'; import { AuthService } from './auth.service'; @Module({ providers: [AuthService], exports: [AuthService] // AuthService를 다른 모듈에서 사용할 수 있도록 공개 }) export class AuthModule {}UsersModule에서AuthModuleimport하기:// src/users/users.module.ts import { Module } from '@nestjs/common'; import { UsersController } from './users.controller'; import { UsersService } from './users.service'; import { AuthModule } from '../auth/auth.module'; // AuthModule 임포트 @Module({ imports: [AuthModule], // AuthModule을 임포트하여 AuthService를 사용할 수 있게 됨 controllers: [UsersController], providers: [UsersService] }) export class UsersModule {}UsersService에서AuthService주입받아 사용하기:// src/users/users.service.ts import { Injectable } from '@nestjs/common'; import { AuthService } from '../auth/auth.service'; // AuthService 임포트 @Injectable() export class UsersService { // 생성자에서 AuthService를 주입받음 constructor(private readonly authService: AuthService) {} someMethod() { // 주입받은 authService의 메소드를 사용 this.authService.validateUser(); } }
4. 연습 문제
문제 1: PostsModule 만들기
- 요구사항: 3장에서 만들었던
PostsController와PostsService를 관리하는PostsModule을 만드세요. - 세부사항:
nest g mo posts명령어로PostsModule을 생성합니다.PostsModule의controllers배열에PostsController를,providers배열에PostsService를 등록합니다.- 루트 모듈인
AppModule의imports배열에PostsModule을 추가합니다. AppModule의controllers와providers배열에서는PostsController와PostsService를 제거합니다. (이제PostsModule이 관리하므로)
- 확인: 서버를 재시작하고, 이전에 만들었던
/posts관련 API가 정상적으로 동작하는지 확인합니다.
문제 1 정답 예시
// src/posts/posts.module.ts
import { Module } from '@nestjs/common';
import { PostsController } from './posts.controller';
import { PostsService } from './posts.service';
@Module({
controllers: [PostsController],
providers: [PostsService]
})
export class PostsModule {}
// src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { PostsModule } from './posts/posts.module'; // 임포트 추가
@Module({
imports: [PostsModule], // 여기에 PostsModule 추가
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
문제 2: 전역 모듈(Global Module) 만들기
- 개념:
@Global()데코레이터를 사용하여 모듈을 전역으로 만들 수 있습니다. 전역 모듈은 루트 모듈(AppModule)에 한 번만import하면, 다른 모든 모듈에서 별도로import하지 않아도 해당 모듈이export한 프로바이더를 사용할 수 있게 됩니다. - 요구사항: 애플리케이션 전반에서 사용될
ConfigService를 제공하는ConfigModule을 전역 모듈로 만들어보세요. - 세부사항:
nest g mo config및nest g s config로 모듈과 서비스를 생성합니다.ConfigService는 간단한 설정 값(예:get(key: string))을 반환하는 메소드를 가집니다.ConfigModule에서ConfigService를providers와exports에 등록합니다.ConfigModule클래스 위에@Global()데코레이터를 추가합니다.AppModule에ConfigModule을import합니다.- 이제
PostsModule이나UsersModule에서ConfigModule을import하지 않고도,PostsService나UsersService의 생성자에서ConfigService를 바로 주입받을 수 있는지 확인합니다.
- 언제 사용할까?: 설정, 데이터베이스 연결 등 애플리케이션 전반에서 한 번만 설정되고 널리 사용되는 프로바이더를 제공할 때 유용합니다. (남용하지 않도록 주의)
문제 2 정답 예시
// src/config/config.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class ConfigService {
private readonly envConfig = { API_KEY: '12345-secret' };
get(key: string): string {
return this.envConfig[key];
}
}
// src/config/config.module.ts
import { Module, Global } from '@nestjs/common';
import { ConfigService } from './config.service';
@Global() // 전역 모듈로 설정
@Module({
providers: [ConfigService],
exports: [ConfigService],
})
export class ConfigModule {}
// src/app.module.ts
// ...
import { ConfigModule } from './config/config.module';
@Module({
imports: [ConfigModule, UsersModule, PostsModule], // 루트에 한 번만 임포트
// ...
})
export class AppModule {}
// src/posts/posts.service.ts
import { Injectable } from '@nestjs/common';
import { ConfigService } from '../config/config.service'; // 타입 임포트는 필요
@Injectable()
export class PostsService {
// PostsModule에 ConfigModule을 임포트하지 않았지만 주입 가능
constructor(private readonly configService: ConfigService) {
console.log('API Key:', this.configService.get('API_KEY'));
}
// ...
}
'백엔드 > 네스트' 카테고리의 다른 글
| [NestJS] 9장: 설정 및 로깅 - 애플리케이션 환경 관리하기 (0) | 2025.09.19 |
|---|---|
| [NestJS] 8장: 인증 - 사용자를 확인하고 보호하기 (0) | 2025.09.19 |
| [NestJS] 7장: 실전 프로젝트 - Todo 리스트 API 서버 만들기 (0) | 2025.09.19 |
| [NestJS] 6장: 데이터베이스 연동 (with TypeORM) (0) | 2025.09.19 |
| [NestJS] 5장: 미들웨어, 파이프, 가드 - 요청 처리의 수문장들 (0) | 2025.09.19 |
| [NestJS] 3장: 프로바이더와 의존성 주입 - 로직의 분리와 재사용 (0) | 2025.09.18 |
| [NestJS] 2장: 컨트롤러와 라우팅 - 요청을 받아들이는 관문 (0) | 2025.09.18 |
| [NestJS] 1장: NestJS 소개 및 개발 환경 설정 (0) | 2025.09.18 |