(NestJS-기초강의) 6. 모듈(Module)

NestJS는 모듈을 조합하여 Application을 구성하는 형식으로 이루어져 있습니다.

이번 포스팅에서는 모듈에 대한 이론적 지식과 함께 어떻게 사용하는지 까지 학습해보겠습니다.

모듈이란 무엇인가?

NestJS는 모듈 기반의 구조를 가지고 있으며 모듈은 Application의 부분으로 독립적으로 동작 가능합니다.

모듈을 통하여 Application의 기능을 조직화하여 관리합니다.

이번 포스팅에서는 NestJS의 모듈에 대해 상세히 알아보고 모듈을 사용 및 관리하는 방법에 대해 다뤄보겠습니다.

특징

  • NestJS로 만든 Application은 여러 모듈의 집합입니다.
  • 하나 이상의 모듈이 반드시 있어야 합니다.
  • AppModule이 기본으로 생성됩니다.
  • 기능별로 모듈을 생성할 수 있습니다.
  • 생성된 모듈을 AppModule(Root Module 이라고도 불림)에 Import 해주어야 합니다.
    • СLI로 모듈을 생성하면 자동으로 AppModule에 import가 됩니다.
  • Export를 통해 외부에서 Module을 사용할 수 있게 할 수 있게 내보낼 수 있습니다.

예시) 다음 그림 처럼 Application은 각 종 모듈로 구성되고 각 모듈은 기능을 가진 모듈로 구조화 될 수 있습니다.

출처: https://docs.nestjs.com/modules

Module 구조

@Module 데코레이터는 모듈을 정의하고 설정하는데 사용됩니다.
Class위에 사용되며 모듈의 기능을 정의하고 모듈을 구성하는데 필요한 Metadata를 제공합니다.

각 모듈은 Class로 정의되고 해당 class 내에서 imports, controllers, providers, exports 등의 속성을 설정하여 모듈간의 의존성 및 기능을 관리합니다.

속성 (Properties)

  • imports (가져오기):
    • imports외부 모듈이나 NestJS에서 사용할 모듈을 가져오는 데 사용됩니다.
    • 이 속성은 현재 모듈이 의존하는 다른 모듈을 지정하는 데 사용되며, 이를 통해 현재 모듈에서 외부 모듈의 기능을 사용할 수 있게 합니다.
  • controllers (컨트롤러):
    • controllers는 현재 모듈에 속한 컨트롤러 클래스들을 정의합니다.
    • NestJS에서 컨트롤러는 URL에 대한 요청을 처리하고 응답을 반환하는 역할을 수행합니다.
    • 일반적으로 라우팅 및 HTTP 요청을 처리하며 비즈니스 로직과 상호 작용하여 클라이언트에게 응답합니다.
  • providers (제공자):
    • providers는 의존성 주입(Dependency Injection)을 위한 서비스, 클래스, 팩토리, 객체 또는 기타 요소들을 제공합니다.
    • 이 속성은 응용 프로그램 전체에서 사용되는 서비스를 정의하고 주입할 때 활용됩니다.
    • NestJS에서 제공자는 싱글톤으로 관리되며, 의존성 주입을 통해 여러 곳에서 사용됩니다.
  • exports (내보내기):
    • exports는 현재 모듈에서 외부에 공개할 요소들을 정의합니다.
    • 다른 모듈에서 해당 모듈에 포함된 기능을 사용하고자 할 때 exports를 활용하여 공유하고자 하는 부분을 외부에 노출시킬 수 있습니다.

NestJS Module 종류

NestJS에는 있는 주요 모듈에 대해 소개해드리겠습니다.

Root Module

  • 루트 모듈은 애플리케이션의 진입점 역할을 하며 AppModule이라고도 불립니다.
  • @Module() 데코레이터를 가지고 있고, 주로 애플리케이션을 초기화하고 설정합니다.

Feature Module

  • 기능 모듈은 특정 기능이나 비즈니스 영역을 위해 모듈입니다.
  • 애플리케이션을 작은 단위로 분리하여 모듈화하고, 재사용 가능한 모듈을 만드는 데 사용됩니다.

Shared Module

  • 공유 모듈은 애플리케이션 전반에서 재사용되는 기능이나 서비스를 포함하는 모듈입니다.
  • 중복 코드를 줄이고 의존성을 관리하기 위해 사용됩니다.

Core Module

  • 코어 모듈은 애플리케이션의 핵심적인 기능을 구현하고 다른 모듈들 간의 상호 작용을 조정합니다.
  • 애플리케이션의 전체적인 구조와 핵심적인 비즈니스 로직을 처리하는 데 사용됩니다.

예제(기본 생성 구조) 확인

예제로 기본 생성되는 AppModule에 대해 확인해보겠습니다.

파일 구조

├─ src
│ ├─ app.controller.spec.ts
│ ├─ app.controller.ts
│ ├─ app.module.ts
│ ├─ app.service.ts
│ └─ main.ts

main.ts

Application의 진입점(entry point)으로 NestFactory를 이용하여 Application을 인스턴스화 했습니다.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
AppModule (app.module.ts)

AppModule은 main.ts에서 Application을 인스턴스화 할 때 지정한 root module입니다.

controller와 provider를 각각 AppController와 AppService로 지정했습니다.

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

AppController(app.controller.ts)

Client 요청[getHello() 호출]에 따라 provider인 AppService에게 비즈니스 처리 요청을 보내고,
그 결과를 Client에게 응답 합니다.

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

AppService(app.service.ts)

Controller로 부터 요청 받은 비즈니스 로직을 수행한 후 결과를 반환합니다.

import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

Nest CLI를 이용한 자동생성

nest CLI를 이용하여 Module/Controller/Service를 자동생성 할 수 있다.

공식문서

Module 생성

cmd에서 다음 명령어를 통해 module을 생성합니다.

$ nest g module users // module_name: users
결과

UsersModule이 생성되고, AppModuleUsersModuleimport 되었습니다.

Controller 생성

cmd에서 다음 명령어를 통해 controller를 생성합니다.

$ nest g controller users // controller_name: users
결과

UsersController가 추가되고 UserModule에 연결되었습니다.

UsersController(users.controller.ts) 는 다음과 같이 @Controller 데코레이터를 사용해 /users path에 라우팅을 컨트롤 하도록 연결 되었습니다.

import { Controller } from '@nestjs/common';

@Controller('users')
export class UsersController {}

Service 생성

cmd에서 다음 명령어를 통해 service를 생성합니다.

$ nest g service users // service_name: users
결과

UsersService가 추가되고, UserModule에 Provider로 연결되었습니다.

UsersService는 다음과 같이 @Injectable() 데코레이터를 사용하고 있으므로

@Injectable()
export class UsersService {}

UsersController(users.controller.ts)에 다음과 같이 Service를 사용할 것에 선언해주면 필요한 시점에 자동으로 객체를 생성해줍니다.
이는 스프링의 DI(Dependency Injection)을 사용한 것과 같습니다.

import { Controller } from '@nestjs/common';
import { UsersService } from './users.service';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {} // add service
}

참고링크

Leave a Comment