Providers

Providers

๊ณต๊ธ‰์ž๋Š” Nest์˜ ๊ธฐ๋ณธ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. ๋งŽ์€ ๊ธฐ๋ณธ Nest ํด๋ž˜์Šค๋Š” ์„œ๋น„์Šค, ์ €์žฅ์†Œ, ํŒฉํ† ๋ฆฌ, ํ—ฌํผ ๋“ฑ ๊ณต๊ธ‰์ž๋กœ ์ทจ๊ธ‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณต๊ธ‰์ž์˜ ์ฃผ์š” ์•„์ด๋””์–ด๋Š” ์˜์กด์„ฑ์„ ์ฃผ์ž… ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ๊ฐœ์ฒด๊ฐ€ ์„œ๋กœ ๋‹ค์–‘ํ•œ ๊ด€๊ณ„๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ฐœ์ฒด์˜ "๋ฐฐ์„ "๊ธฐ๋Šฅ์„ Nest ๋Ÿฐํƒ€์ž„ ์‹œ์Šคํ…œ์— ํฌ๊ฒŒ ์œ„์ž„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณต๊ธ‰์ž๋Š” ๋‹จ์ˆœํžˆ @Injectable()๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ์ฃผ์„์ด ๋‹ฌ๋ฆฐ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

์ด์ „ ์žฅ์—์„œ ์šฐ๋ฆฌ๋Š” ๊ฐ„๋‹จํ•œ CatsController๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์ปจํŠธ๋กค๋Ÿฌ๋Š” HTTP ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋” ๋ณต์žกํ•œ ์ž‘์—…์„ ๊ณต๊ธ‰์ž์—๊ฒŒ ์œ„์ž„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ณต๊ธ‰์ž๋Š” ํด๋ž˜์Šค ์„ ์–ธ ์•ž์— @Injectable() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๊ฐ€ ์žˆ๋Š” ์ผ๋ฐ˜ JavaScript ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.

info ํžŒํŠธ Nest๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ข€ ๋” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ข…์†์„ฑ์„ ๋””์ž์ธํ•˜๊ณ  ๊ตฌ์„ฑ ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ SOLID ์›์น™์„ ๋”ฐ๋ฅด๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

Services

๊ฐ„๋‹จํ•œ CatsService๋ฅผ ๋งŒ๋“ค์–ด ๋ด…์‹œ๋‹ค. ์ด ์„œ๋น„์Šค๋Š” ๋ฐ์ดํ„ฐ ์ €์žฅ ๋ฐ ๊ฒ€์ƒ‰์„ ๋‹ด๋‹นํ•˜๋ฉฐ CatsController์—์„œ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์œผ๋ฏ€๋กœ ๊ณต๊ธ‰์ž๋กœ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํด๋ž˜์Šค๋ฅผ @Injectable()์œผ๋กœ ์žฅ์‹ํ•ฉ๋‹ˆ๋‹ค.

@@filename(cats.service)
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;
  }
}
@@switch
import { Injectable } from '@nestjs/common';

@Injectable()
export class CatsService {
  constructor() {
    this.cats = [];
  }

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

  findAll() {
    return this.cats;
  }
}

info ํžŒํŠธ CLI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค๋ ค๋ฉด ๊ฐ„๋‹จํžˆ $nest g service cats ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์‹ญ์‹œ์˜ค.

์šฐ๋ฆฌ์˜ CatsService๋Š” ํ•˜๋‚˜์˜ ์†์„ฑ๊ณผ ๋‘ ๊ฐœ์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง„ ๊ธฐ๋ณธ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ์œ ์ผํ•œ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์€@Injectable() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. @Injectable() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒจ๋ถ€ํ•˜์—ฌ ์ด ํด๋ž˜์Šค๊ฐ€ Nest ๊ณต๊ธ‰์ž๋ผ๋Š” ๊ฒƒ์„ Nest์—๊ฒŒ ์•Œ๋ ค์ค๋‹ˆ๋‹ค. ๊ทธ๊ฑด ๊ทธ๋ ‡๊ณ , ์ด ์˜ˆ์ œ๋Š” Cat ์ธํ„ฐํŽ˜์ด์Šค๋„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์•„๋งˆ๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค:

export interface Cat {
  name: string;
  age: number;
  breed: string;
}

Cat๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ์„œ๋น„์Šค ํด๋ž˜์Šค๊ฐ€ ์ƒ๊ฒผ์œผ๋‹ˆ CatsController ์•ˆ์—์„œ ์‚ฌ์šฉํ•˜์ž:

@@filename(cats.controller)
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 readonly catsService: CatsService) {}

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

  @Get()
  async findAll(): Promise<Cat[]> {
    return this.catsService.findAll();
  }
}
@@switch
import { Controller, Get, Post, Body, Bind, Dependencies } from '@nestjs/common';
import { CatsService } from './cats.service';

@Controller('cats')
@Dependencies(CatsService)
export class CatsController {
  constructor(catsService) {
    this.catsService = catsService;
  }

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

  @Get()
  async findAll() {
    return this.catsService.findAll();
  }
}

CatsService๋Š” ํด๋ž˜์Šค ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ฃผ์ž…๋ฉ๋‹ˆ๋‹ค. private readonly ๊ตฌ๋ฌธ์˜ ์‚ฌ์šฉ์— ์ฃผ๋ชฉํ•˜์‹ญ์‹œ์˜ค. ์ด ์†๊ธฐ๋Š” ์šฐ๋ฆฌ๊ฐ€ ๋™์ผํ•œ ์œ„์น˜์—์„œ ์ฆ‰์‹œ catsService ๋ฉค๋ฒ„๋ฅผ ์„ ์–ธํ•˜๊ณ  ์ดˆ๊ธฐํ™” ํ•  ์ˆ˜์žˆ๊ฒŒ ํ•œ๋‹ค.

Dependency injection

Nest๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์ข…์† ์ฃผ์ž…์œผ๋กœ ์•Œ๋ ค์ง„ ๊ฐ•๋ ฅํ•œ ๋””์ž์ธ ํŒจํ„ด์„ ์ค‘์‹ฌ์œผ๋กœ ๊ตฌ์ถ•๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ณต์‹ Angular ๋ฌธ์„œ์—์„œ ์ด ๊ฐœ๋…์— ๋Œ€ํ•œ ํ›Œ๋ฅญํ•œ ๊ธฐ์‚ฌ๋ฅผ ์ฝ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

Nest์˜ TypeScript ๊ธฐ๋Šฅ ๋•๋ถ„์— ์ข…์†์„ฑ์€ ์œ ํ˜•๋ณ„๋กœ ํ•ด๊ฒฐ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ข…์†์„ฑ์„ ๊ด€๋ฆฌํ•˜๊ธฐ๊ฐ€ ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์˜ˆ์ œ์—์„œ Nest๋Š” CatsService์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•จ์œผ๋กœ์จ (๋˜๋Š” ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ ์‹ฑ๊ธ€ ํ†ค์˜ ๊ฒฝ์šฐ ์ด๋ฏธ ๋‹ค๋ฅธ ๊ณณ์— ์š”์ฒญ ๋œ ๊ฒฝ์šฐ ๊ธฐ์กด ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ) catsService๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ด ์ข…์†์„ฑ์€ ํ•ด๊ฒฐ๋˜์–ด ์ปจํŠธ๋กค๋Ÿฌ์˜ ์ƒ์„ฑ์ž์—๊ฒŒ ์ „๋‹ฌ๋˜๊ฑฐ๋‚˜ ํ‘œ์‹œ๋œ ์†์„ฑ์— ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.

constructor(private readonly catsService: CatsService) {}

Scopes

๊ณต๊ธ‰์ž๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ์ˆ˜๋ช…์ฃผ๊ธฐ์™€ ๋™๊ธฐํ™” ๋œ ์ˆ˜๋ช… ( ๋ฒ”์œ„)์„ ๊ฐ–์Šต๋‹ˆ๋‹ค. ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ๋ถ€ํŠธ ์ŠคํŠธ๋žฉ ๋  ๋•Œ ๋ชจ๋“  ์ข…์†์„ฑ์„ ํ•ด๊ฒฐํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋ชจ๋“  ๊ณต๊ธ‰์ž๋ฅผ ์ธ์Šคํ„ด์Šคํ™” ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด ์ข…๋ฃŒ๋˜๋ฉด ๊ฐ ๊ณต๊ธ‰์ž๊ฐ€ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ณต๊ธ‰์ž์˜ ์ˆ˜๋ช…์„ ์š”์ฒญ ๋ฒ”์œ„๋กœ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ธฐ์ˆ ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

Custom providers

Nest์—๋Š” ๊ณต๊ธ‰์ž๊ฐ„ ๊ด€๊ณ„๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ธฐ๋ณธ ์ œ๊ณต ์ œ์–ด ์—ญ์ „ ( "IoC") ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ์œ„์—์„œ ์„ค๋ช…ํ•œ ์ข…์†์„ฑ ์ฃผ์ž… ๊ธฐ๋Šฅ์˜ ๊ธฐ์ดˆ๊ฐ€ ๋˜์ง€๋งŒ ์‹ค์ œ๋กœ ์ง€๊ธˆ๊นŒ์ง€ ์„ค๋ช…ํ•œ ๊ฒƒ๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ•๋ ฅํ•ฉ๋‹ˆ๋‹ค. @Injectable() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋Š” ๋น™์‚ฐ์˜ ์ผ๊ฐ ์ผ ๋ฟ์ด๋ฉฐ ๊ณต๊ธ‰์ž๋ฅผ ์ •์˜ํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ์•„๋‹™๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ผ๋ฐ˜ ๊ฐ’, ํด๋ž˜์Šค ๋ฐ ๋น„๋™๊ธฐ ๋˜๋Š” ๋™๊ธฐ ํŒฉํ† ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋” ๋งŽ์€ ์˜ˆ๊ฐ€ ์—ฌ๊ธฐ์— ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค .

Optional providers

๋•Œ๋•Œ๋กœ, ๋ฐ˜๋“œ์‹œ ํ•ด๊ฒฐ ๋  ํ•„์š”๊ฐ€ ์—†๋Š” ์ข…์†์„ฑ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํด๋ž˜์Šค๋Š” ๊ตฌ์„ฑ ๊ฐ์ฒด์— ์˜์กดํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ „๋‹ฌ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๊ธฐ๋ณธ๊ฐ’์„ ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ๊ตฌ์„ฑ ๊ณต๊ธ‰์ž๊ฐ€ ์—†์œผ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ข…์†์„ฑ์ด ์„ ํƒ ์‚ฌํ•ญ์ด๋ฉ๋‹ˆ๋‹ค.

๊ณต๊ธ‰์ž๊ฐ€ ์„ ํƒ์ ์ž„์„ ๋‚˜ํƒ€๋‚ด๋ ค๋ฉด constructor ์„œ๋ช…์— @Optional() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

import { Injectable, Optional, Inject } from '@nestjs/common';

@Injectable()
export class HttpService<T> {
  constructor(
    @Optional() @Inject('HTTP_OPTIONS') private readonly httpClient: T
  ) {}
}

์œ„์˜ ์˜ˆ์—์„œ ์šฐ๋ฆฌ๋Š” ์ปค์Šคํ…€ ์ œ๊ณต์ž๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ์ด๊ฒƒ์ด ์šฐ๋ฆฌ๊ฐ€ HTTP_OPTIONS ์ปค์Šคํ…€ ํ† ํฐ์„ ํฌํ•จํ•˜๋Š” ์ด์œ ์ž…๋‹ˆ๋‹ค. ์ด์ „ ์˜ˆ์ œ๋Š” ์ƒ์„ฑ์ž์—์„œ ํด๋ž˜์Šค๋ฅผ ํ†ตํ•œ ์ข…์†์„ฑ์„ ๋‚˜ํƒ€๋‚ด๋Š” ์ƒ์„ฑ์ž ๊ธฐ๋ฐ˜ ์ฃผ์ž…์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ง€์ • ๊ณต๊ธ‰์ž ๋ฐ ๊ด€๋ จ ํ† ํฐ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

Property-based injection

์šฐ๋ฆฌ๊ฐ€ ์ง€๊ธˆ๊นŒ์ง€ ์‚ฌ์šฉํ•œ ๊ธฐ์ˆ ์€ ์ƒ์„ฑ์ž ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๊ณต๊ธ‰์ž๊ฐ€ ์ฃผ์ž…๋˜๋ฏ€๋กœ constuctor ๊ธฐ๋ฐ˜ ์ฃผ์ž…์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋งค์šฐ ํŠน์ •ํ•œ ๊ฒฝ์šฐ์—๋Š” ์†์„ฑ ๊ธฐ๋ฐ˜ ์ฃผ์ž…์ด ์œ ์šฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ตœ์ƒ์œ„ ํด๋ž˜์Šค๊ฐ€ ํ•˜๋‚˜ ์ด์ƒ์˜ ๊ณต๊ธ‰์ž์— ์˜์กดํ•˜๋Š” ๊ฒฝ์šฐ ์ƒ์„ฑ์ž์˜ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ super()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋ชจ๋“  ๊ณต๊ธ‰์ž๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์ง€๋ฃจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์†์„ฑ ๋ ˆ๋ฒจ์—์„œ @Inject()๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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

@Injectable()
export class HttpService<T> {
  @Inject('HTTP_OPTIONS')
  private readonly httpClient: T;
}

warning ๊ฒฝ๊ณ  ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ ์ œ๊ณต์ž๋ฅผ ํ™•์žฅํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ํ•ญ์ƒ ์ƒ์„ฑ์ž ๊ธฐ๋ฐ˜ ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

Provider registration

์ด์ œ ์šฐ๋ฆฌ๋Š” ๊ณต๊ธ‰์ž (CatsService)๋ฅผ ์ •์˜ํ–ˆ๊ณ , ๊ทธ ์„œ๋น„์Šค์˜ ์†Œ๋น„์ž (CatsController)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฏ€๋กœ, ์ฃผ์ž…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก Nest์— ์„œ๋น„์Šค๋ฅผ ๋“ฑ๋กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“ˆ ํŒŒ์ผ (app.module.ts)์„ ํŽธ์ง‘ํ•˜๊ณ  ์„œ๋น„์Šค๋ฅผ @Module() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์˜ providers ๋ฐฐ์—ด์— ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

@@filename(app.module)
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 {}

Nest๋Š” ์ด์ œ CatsController ํด๋ž˜์Šค์˜ ์˜์กด์„ฑ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • src

    • cats

      • dto

        • create-cat.dto.ts

      • interfaces

        • cat.interface.ts

      • cats.service.ts

      • cats.controller.ts

    • app.module.ts

    • main.ts

Last updated

Was this helpful?