프로바이더, 서비스

2025. 12. 31. 20:40·NestJS/NestJS 자체 문서화

프로바이더

프로바이더는 NestJS가 인스턴스를 생성 및 관리하는 클래스(가끔 값이나 함수)를 의미합니다.
프로바이더는 싱글톤입니다. 하나의 프로바이더 인스턴스를 앱 전역에서 공유합니다.

서비스

서비스는 프로바이더의 일종입니다. 모든 프로바이더가 서비스는 아니지만, 개발자가 작성하는 대부분의 프로바이더는 서비스입니다.
대부분의 핵심 로직은 서비스에 작성합니다.

생성 방법

# 프로바이더 생성
nest g provider 프로바이더명
nest g pr 프로바이더명 # 약어 사용
nest g pr 프로바이더명 --no-spec # 테스트 파일 생성을 원하지 않을 때

# 서비스 생성
nest g service 서비스명
nest g s 서비스명 # 약어 사용
nest g s 서비스명 --no-spec # 테스트 파일 생성을 원하지 않을 때

프로바이더 등록 및 사용 방법

NestJS에 프로바이더 등록 방법

클래스 등록

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

app.module.ts

import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
import { CatsService } from './cats/cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class AppModule {}

등록한 프로바이더 사용 방법

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 {
  /*
    타입스크립트의 문법적 설탕 기능을 사용하지 않을 때
    catsService: CatsService;
    
    constructor(catsService: CatsService) {
      this.catsService = catsService;
    }
  */
  
  // 타입스크립트의 문법적 설탕 기능을 사용 할 때
  constructor(private catsService: CatsService) {}

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

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

@Inject()

클래스가 아니라 값, 함수를 주입할 때에는 @Inject() 데코레이터를 사용합니다.
export class InjectClass {
  constructor() {
    @Inject('프로바이더이름')
    private readonly valueProvider
  }}
}

속성 기반 주입

부모 클래스를 상속해 자식 클래스를 만들 때 생성자 기반 주입을 사용하면 super() 메서드를 사용해 인스턴스를 전달해야 합니다.
이때 속성 기반 주입을 사용하면 super() 메서드를 사용하지 않아도 됩니다.

database.service.ts

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

@Injectable()
export class DatabaseService {
  connect() {
    return 'connection success';
  }
}

parent-cat.service.ts

부모 클래스를 프로바이더로 사용하지 않으면 @Injectable() 데코레이터를 사용하지 않아도 됩니다.
import { Inject } from '@nestjs/common';
import { DatabaseService } from './cat/database.service';

export class ParentCatService {
  @Inject(DatabaseService)
  private databaseService: DatabaseService;

  parentConnect() {
    return this.databaseService.connect();
  }
}

cat.service.ts

import { Injectable } from '@nestjs/common';
import { ParentCatService } from 'src/parent-cat.service';

@Injectable()
export class CatService extends ParentCatService {
  connect(): string {
    return this.parentConnect();
  }
}

사용자 정의 프로바이더

프로바이더는 보통 클래스지만, 값이나 팩토리(동적인 프로바이더를 만들기 위한 함수)도 프로바이더가 될 수 있습니다.

값 프로바이더

app.module.ts

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


@Module({
  controllers: [AppController],
  providers: [
    {
      provide: 'ValueProvider',
      useValue: {
        name: 'namsu',
      },
    },
  ],
  exports: ['ValueProvider'],
})
export class AppModule {}

app.controller.ts

import { Controller, Get, Inject } from '@nestjs/common';

@Controller()
export class AppController {
  constructor(
    @Inject('ValueProvider')
    private readonly valueProvider,
  ) {}

  @Get('value')
  getValueProvider() {
    return this.valueProvider;
  }
}

클래스 프로바이더

제공해야 하는 클래스를 동적으로 결정해야 할 때 클래스 프로바이더를 사용합니다.
클래스 프로바이더는 단독으로 쓰기보다 동적 모듈과 함께 쓸 듯??
const configServiceProvider = {
  provide: ConfigService,
  useClass:
    process.env.NODE_ENV === 'development'
      ? DevelopmentConfigService
      : ProductionConfigService,
};

@Module({
  providers: [configServiceProvider],
})
export class AppModule {}

팩토리 프로바이더

인스턴스를 동적으로 제공해야 할 때 팩토리 프로바이더를 사용합니다.
팩토리 함수는 값이나 인스턴스를 반환할 수 있습니다.
팩토리 함수는 다른 프로바이더를 사용할 수 있습니다.
팩토리 함수는 비동기로 실행할 수 있습니다.
const connectionProvider = {
  provide: 'CONNECTION',
  // 팩토리 함수의 매개변수는 사용할 프로바이더입니다.
  useFactory: async (optionsProvider: MyOptionsProvider, optionalProvider?: string) => {
    const options = await optionsProvider.get();
    return new DatabaseConnection(options);
  },
  inject: [
    MyOptionsProvider, // 필수 프로바이더
    { token: 'SomeOptionalProvider', optional: true }, // 선택적 프로바이더
  ], 
};

@Module({
  providers: [
    connectionProvider,
    MyOptionsProvider,
    // { provide: 'SomeOptionalProvider', useValue: 'anything' },
  ],
})
export class AppModule {}
저작자표시 (새창열림)

'NestJS > NestJS 자체 문서화' 카테고리의 다른 글

예외 필터  (0) 2025.12.31
파이프(Pipe), DTO  (0) 2025.12.31
컨트롤러  (0) 2025.12.31
모듈  (0) 2025.12.31
Nest CLI  (1) 2025.12.18
'NestJS/NestJS 자체 문서화' 카테고리의 다른 글
  • 예외 필터
  • 파이프(Pipe), DTO
  • 컨트롤러
  • 모듈
남느
남느
  • 남느
    요약 장인
    남느
  • 전체
    오늘
    어제
    • 분류 전체보기 (73)
      • 프로그래밍 (18)
      • 웹 기초 지식 (2)
      • Node.js 기초 (2)
      • 코딩테스트(자바스크립트) (6)
      • NestJS (18)
        • NestJS 자체 문서화 (11)
        • NestJS 예제 (5)
        • NestJS 레시피 (2)
      • Node.js ORM (5)
        • TypeORM (4)
      • 자바 (1)
      • 우분투 적응기 (8)
      • 리눅스 답은 하모니카다 (4)
      • 살다보니 드는 생각들 (3)
      • 도커 (1)
  • 블로그 메뉴

    • 홈
    • 태그
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백엔드
    웹
    프로그래머
    개발자
    취업
    신입
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
남느
프로바이더, 서비스
상단으로

티스토리툴바