본문 바로가기
Frameworks/Nest.js

[Nest.js] Provider

by junseokoo 2025. 4. 9.

  • Provider는 Nest의 기본 개념이다. 이는 의존성을 주입할 수 있다. 즉, 객체가 서로 다양한 관계를 만들 수 있으며 객체의 배선 기능을 Nest 런타임 시스템에 크게 위임할 수 있다.
  • Provider는 클래스 선언 앞에 @Injectable() 데코레이터가 있다.

계층형 구조 (Layerd Architecture)

  • 복잡해 보이는 작업도 그 작업을 나우고 각 작업마다 역량을 집중해 해결이 가능하다. (관심사 분리)
  • 3-Tier-Architecture
    • Presentation Tier
      • 사용자 인터페이스 혹은 외부와의 통신 담당
    • Application Tier
      • Logic Tier라고도 하며, Middle Tier라고도 한다. 주로 비즈니스 로직을 여기서 구현하고 Presentation Tier와 Data Tier 사이를 연결해준다.
    • Data Tier
      • 데이터베이스에 데이터를 읽고 쓰는 역할
        • Nest에서 Presentation Tier는 Controller, Apllication Tier는 Service, Data Tier는 Repository 여기서 Service는 비즈니스 로직을 담당한다.
        • Nest는 컨트롤러와 그 하위 계층을 Provider라는 이름으로 구분하고 응집도는 높이고 결합도는 낮춘다.

제어의 역전 (IoC, Inversion of Control)

  • 프레임워크가 대신 제어한다. 라는 의미이다.
  • Nest는 providers안에 클래스 또는 값을 설정하면 Nest.js 내부 Ioc Container에 등록이 된다.
  • 즉, UserService를 생성하면 자동으로 providers에 등록이 된다.
  • 이로써 new 키워드를 통해 따로 UserService를 생성하지 않아도 이미 도메인 모듈에 생성이 되어 있기 때문에 호출해서 Controller에서 바로 사용이 가능하다.

의존성 주입 (DI, Dependenct Injection)

  • 프레임워크가 주체가 되어 필요한 클래스 등을 대신 관리해 준다.
  • new 없이 선언해도 마치 인스턴스처럼 사용할 수 있게 된다.
  • @Injectable(), @Service 등 데코레이터를 사용하면 의존성 주입의 대상이 된다.
  • public, private, protected, readonly 의 키워드를 constructor 변수 앞에 기입하면 이 변수가 실제로 이름과 값을 가지는 클래스의 속성이 된다.

Service

// user.service.ts
import { Injectable } from '@nestjs/common';
import { User } from './interfaces/user.interface';

@Injectable()
export class UserService {
  private user: User[] = [];

  async signUp(user: User) {
      return await this.user.push(user);
  }
}
  • 이는 하나의 클래스와 하나의 메서드를 가진 기본 클래스이다.
  • @Injectable() 데코레이터는 메타 데이터를 첨부해 UserService가 Nest IoC 컨테이너에서 관리할 수 있는 클래스임을 선언한다.
// user.controller.ts
import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UserService } from './user.service';
import { User } from './interfaces/user.interface';

@Controller('user')
export class UserController {
  constructor(private userService: UserService) {}

  @Post()
  async create(@Body() createUserDto: CreateUserDto) {
    return await this.userService.create(createUserDto);
  }
  • constructor 부분은 생성자를 생성하는 것이다.
  • 의존성을 주입하는 방법
    • 생성자를 이용한 주입 (Constructor Injection)
    • 수정자를 이용한 주입 (Setter Injection)
    • 필드를 이용한 주입 (Field Injection)
  • Nest는 생성자를 이용한 의존성 주입을 권장한다.

Scopes

  • Nest 프로그램이 부트 스트랩될 때 모든 종속성을 해결해야 하므로 모든 Provider가 인스턴스화 된다.
  • 종료되면 각 프로바이더가 메모리에서 삭제 된다.
  • 수명을 요청 단위로 제한도 할 수 있지만, 성능상 문제로 기본적으론 기본 설정 수명주기를 사용하자.

선택적 Provider(Optional)

  • 클래스는 구성 객체에 의존할 수 있지만 아무것도 전달되지 않으면 기본값을 사용해야 한다.
  • 이 경우 Provider가 없어도 오류가 발생하지 않으므로 종속성은 선택사항이 된다.
  • 이를 나타내려면 생성자를 생성할 때 @Optional() 데코레이터를 사용하자.

속성 기반 주입 (Property-based injection)

  • Field를 이용한 의존성 주입니다.
  • 이것을 사용할 때에는 최상위 클래스가 하나 또는 여러 프로바이더에 종속되어 있는 경우 생성자에서 하위 클래스의 super()를 호출하여 해당 클래스를 끝까지 전달하는 것은 힘들다. 이를 방지하려면 속성 수준에서 @Inject() 데코레이터를 사용할 수 있다.
  • 하지만 프로바이더를 확장하지 않는 이상 반드시 생성자를 이용한 의존성 주입을 사용하자.

Provider 등록

  • @Module() 데코레이터 안에 providers 배열에 추가 해주면 된다.

 

'Frameworks > Nest.js' 카테고리의 다른 글

[Nest.js] Module  (0) 2025.04.09
[Nest.js] Controller  (0) 2025.04.09
[Nest.js] MySQL Connect  (0) 2025.04.09
[Nest.js] Start  (0) 2025.04.09