본문 바로가기
World/Nest.js

nestjs_공급자(provider)와 DI(Dependency Injection)

by RIEM 2023. 4. 4.
728x90

공급자, 소비자에 대해 알아보고 또 공급자의 상품이 어떻게 소비자에게 주입되는 지 알아보자. 여기서 상품은 비유적인 표현인데, 현실 세계와 유사하기에 이런 표현을 쓴 것이다. 현실 세상에서는 물건을 공급자로부터 주입 받는다면, 코드 상에서는 인스턴스를 주입 받는다.

 

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();
  }
}

nest.js의 코드는 왜 이런 모양인가? 왜 바로 서비스를 제공하지 않고 의존성 주입으로 서비스를 추상화시켜서 제공하는가?

장점
- 유지보수가 쉬워진다
- 가독성이 좋아진다. 서비스 로직이 컨트롤러 단에 복잡하게 나열되어있으면 그 컨트롤러의 역할을 한눈에 파악하기가 힘들어진다
- 디자인 패턴에 맞게 적용할 수 있다
- nest.js의 모듈 구조에 적합한 분자 구조다

위에서 말한 의존성 주입은 더 정확히 말하면 생성자 주입이다. 클래스 내 의존관계를 가진 인스턴스를 내부에서 생성하는 것이 아니라 왜부에서 생성한 뒤 주입한다. 

여기서 AppController는 소비자(Consumer)이고, Provider로부터 appService를 제공받는 Consumer-Provider 구조다.

https://docs.nestjs.com/providers

공급자(provider)의 핵심은 종속성(dependency)으로서 주입이 가능하다는 점이다.

 

// app.controller
import { Body, Controller, Get, Param, Req } from '@nestjs/common';
import { AppService } from './app.service';
import { Request } from 'express';

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

  @Get(':id')
  getHello(@Req() req: Request, @Body() Body, @Param() param): string {
    console.log(param);
    return this.appService.getHello();
  }
}

간단한 AppController를 만들었다고 보자. 이 AppController는 appService를 소비하는 consumer이다.

// app.service
import { Injectable } from '@nestjs/common';

@Injectable() // can be managed by Nest IoC container
export class AppService {
  getHello(): string {
    console.log('hello');
    return 'Hello World!';
  }
}

이 app.service가 provider 역할을 하고 있다. 이를 확인하기 위해선 모듈을 보면 된다.

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

@Module({
  imports: [],
  // 소비자(Consumer)는 AppController
  controllers: [AppController],
  // 공급자(Provider)는 AppService
  providers: [AppService],
})
export class AppModule {}
728x90

댓글