Provider

송민지·2023년 5월 7일
0

Nest.JS 공부하기

목록 보기
1/1

Nest.JS 공식문서에서 provider는 Nest의 기본 개념이다.

다양한 기본적인 Nest의 클래스들(레포지토리, 팩토리, 핼퍼 등등)은 provider로 다뤄질 수 있다.

provider의 핵심은 의존성을 주입할 수 있다는 점이다.
의존성을 주입하게 되면 많은 객체들은 각각 다양한 관계를 맺을 수 있고, 개체 인스턴스를 "연결"하는 기능은 대부분 Nest 런타임 시스템에 위임될 수 있다.

처음 공식문서를 봤을때는 이게 뭔소리여가 입으로 나왔다.

공식문서를 이해하기 위해서는 DI(Dependency Injection)와 IoC(Inversion of Control)에 대한 이해가 먼저 필요하다.

IoC

프레임워크를 사용하지 않고 개발할때는 객체 생성, 설정, 초기화, 기타의 흐름들을 프로그래머가 직접 관리하고 설정해주어야 한다.

하지만 프레임워크를 사용하면 객체의 생성 및 설정, 초기화 및 기타의 사항들은 프레임워크가 대신 호출하고 제어한다.

이처럼 개발자가 작성한 객체의 제어를 개발자가 아니라 프레임워크에 위임하는 설계 원칙을 제어의 역전이라 한다.

DI

기본적인 의미는 하나의 객체가 다른 객체의 의존성을 제공(service)하는 것이다.
의존성 주입의 의도는 객체의 생성과 사용의 관심을 분리하는 것이다. 이는 가독성과 코드 재사용을 높혀준다.

무슨 뜻인지는 코드를 보면서 이해하면 좋다

지금부터 '나'는 햄버거 가게 사장이다. '나'만의 레시피를 가지고 있고, 이를 코드로 구현하면 다음과 같다.

class Hamberger{
  constructor(bun, patty, cheese, lettuce, tomato,mayonnaise) {
    this.bun = bun;
    this.patty = patty;
    this.cheese = chseese;
    this.lettuce = lettuce;
    this.toamto = tomato;
    this.mayonnaise = mayonnaise;
  }
}

const hamberger = new Hamberger()

기본적인 빵 사이에 고기패티, 치즈1장, 토마토1개, 마요네즈 소스, 양상추1장이 들어가는 레시피다.

그런데 손님이 고기패티 대신 식물성 패티를 넣어달라고 요청했다.
하지만 '나'의 레시피에는 정해진 재료가 있기때문에 외부에서 요청이 들어와도 바꾸지 못한다.
이처럼 '나'는 햄버거를 만들때 '레시피'에 의존한다.
위의 경우처럼 의존성이 강하면 생성자 변경이 필요하고
다른 제품을 판매하기 위해 중복되는 코드가 왕왕 발생한다.

하지만, '나'의 햄버거 레시피를 외부에서 제공받는다면 말이 달라진다.


// hamberger dto
export dto hamburger {
 
}

export dto CheeseBurber extends hamburger{
}


///Hamberger controller
import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateHamburgerDto } from './dto/create-cat.dto';
import { HamburgerService } from './cats.service';

@Controller('hamburger')
export class HamburgerController {
  constructor(private hamburgerService: HamburgerService) {}

  @Post()
 // 1. 다양한 햄버거 dto를 받아 service로 보내기
  //3. 넘어온 햄버거 제작 완료
  
//Hamberger service
import { Injectable } from '@nestjs/common';

@Injectable()
export class HambergerService {
  private readonly hamburger: Hamburger[] =[];

//2. controller에서 받은 레시피를 제작하여 다시 controller로 넘기기
 
}

이처럼 의존성을 주입하면 코드의 재사용이 가능하고 유연성이 높아진다.
또한 클래스를 수정했을때 다른클래스도 수정해야하는 번거로움이 없다.
유지보수역시 쉬워지고 테스트도 쉽다.
dto가 추가됨에 따라 확장이 가능하다.

이제 공식문서에 있는 예시코드를 다시 읽어보자.

//cats.service.ts
import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';

@Injectable()
export class CatsService {
  private readonly cats: Cat[] = [];

  create(cat: Cat) {
    this.cats.push(cat);
  }

  findAll(): Cat[] {
    return this.cats;
  }
}

//interfaces/cat.interface.ts
export interface Cat {
  name: string;
  age: number;
  breed: string;
}

// cats.controller.ts
import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';

@Controller('cats')
export class CatsController {
  constructor(private catsService: CatsService) {}

  @Post()
  async create(@Body() createCatDto: CreateCatDto) {
    this.catsService.create(createCatDto);
  }

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}

의존성을 주입하기 위한 방법은 크게 3가지가 있다.

생성자를 이용한 의존성 주입(Constructor Injection)
수정자를 이용한 의존성 주입(Setter Injection)
필드를 이용한 의존성 주입(Field Injection)
Nest에서는 주로 생성자를 이용한 의존성 주입을 권장한다.

(혹시 코드에 잘못된 부분이 있으면 댓글 남겨주세요 😃 )


쉽게 풀어쓴 Nest.js
의존성 주입
의존관계 주입 쉽게 이해하기
[DI] 의존성 주입(Dependency Injection) 의 개념과 방법 및 장단점
제어의 역전
[Spring] 의존성 주입(Dependency Injection, DI)이란? 및 Spring이 의존성 주입을 지원하는 이유
https://bitkunst.tistory.com/entry/NestJS-Provider-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85DI

profile
기록하는 일상

0개의 댓글