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?