> For the complete documentation index, see [llms.txt](https://jakekwak.gitbook.io/nestjs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jakekwak.gitbook.io/nestjs/overview/untitled-4.md).

# Providers

## Providers

공급자는 Nest의 기본 개념입니다. 많은 기본 Nest 클래스는 서비스, 저장소, 팩토리, 헬퍼 등 공급자로 취급될 수 있습니다. 공급자의 주요 아이디어는 의존성을 **주입** 할 수 있다는 것입니다. 즉, 개체가 서로 다양한 관계를 만들 수 있으며 개체의 "배선"기능을 Nest 런타임 시스템에 크게 위임 할 수 있습니다. 공급자는 단순히 `@Injectable()`데코레이터로 주석이 달린 클래스입니다.

![](https://docs.nestjs.com/assets/Components_1.png)

&#x20;이전 장에서 우리는 간단한 `CatsController`를 만들었습니다. 컨트롤러는 HTTP 요청을 처리하고 더 복잡한 작업을 **공급자**에게 위임해야 합니다. 공급자는 클래스 선언 앞에 `@Injectable()` 데코레이터가 있는 일반 JavaScript 클래스입니다.

> info **힌트** Nest를 사용하면 좀 더 다양한 방법으로 종속성을 디자인하고 구성 할 수 있으므로 [SOLID](https://en.wikipedia.org/wiki/SOLID) 원칙을 따르는 것이 좋습니다.

## Services

간단한 `CatsService`를 만들어 봅시다. 이 서비스는 데이터 저장 및 검색을 담당하며 `CatsController`에서 사용하도록 설계되었으므로 공급자로 정의하는 것이 좋습니다. 따라서 클래스를 `@Injectable()`으로 장식합니다.

```typescript
@@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` 인터페이스도 사용하는데, 아마도 다음과 같이 보일 것입니다:

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

Cat를 검색하는 서비스 클래스가 생겼으니 `CatsController` 안에서 사용하자:

```typescript
@@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](https://angular.io/guide/dependency-injection) 문서에서 이 개념에 대한 훌륭한 기사를 읽는 것이 좋습니다.

Nest의 TypeScript 기능 덕분에 종속성은 유형별로 해결되기 때문에 종속성을 관리하기가 매우 쉽습니다. 아래 예제에서 Nest는 `CatsService`의 인스턴스를 생성하고 반환함으로써 (또는 일반적인 경우 싱글 톤의 경우 이미 다른 곳에 요청 된 경우 기존 인스턴스를 반환하여) `catsService`를 해결합니다. 이 종속성은 해결되어 컨트롤러의 생성자에게 전달되거나 표시된 속성에 할당됩니다.

```typescript
constructor(private readonly catsService: CatsService) {}
```

## Scopes

공급자는 일반적으로 응용 프로그램 수명주기와 동기화 된 수명 ( `범위`)을 갖습니다. 응용 프로그램이 부트 스트랩 될 때 모든 종속성을 해결해야 하므로 모든 공급자를 인스턴스화 해야 합니다. 마찬가지로 응용 프로그램이 종료되면 각 공급자가 삭제됩니다. 그러나 공급자의 수명을 **요청 범위**로 만드는 방법도 있습니다. 이러한 기술에 대한 자세한 내용은 [여기](https://app.gitbook.com/fundamentals/injection-scopes)를 참조하십시오.

## Custom providers

Nest에는 공급자간 관계를 해결하는 기본 제공 제어 역전 ( "IoC") 컨테이너가 있습니다. 이 기능은 위에서 설명한 종속성 주입 기능의 기초가 되지만 실제로 지금까지 설명한 것보다 훨씬 강력합니다. `@Injectable()` 데코레이터는 빙산의 일각 일 뿐이며 공급자를 정의하는 유일한 방법은 아닙니다. 실제로 일반 값, 클래스 및 비동기 또는 동기 팩토리를 사용할 수 있습니다. 더 많은 예가 [여기](https://app.gitbook.com/fundamentals/dependency-injection)에 제공됩니다 .

## Optional providers

때때로, 반드시 해결 될 필요가 없는 종속성이 있을 수 있습니다. 예를 들어 클래스는 **구성 객체**에 의존할 수 있지만 전달되지 않은 경우 기본값을 사용해야합니다. 이러한 경우 구성 공급자가 없으면 오류가 발생하지 않으므로 종속성이 선택 사항이됩니다.

공급자가 선택적임을 나타내려면 `constructor` 서명에 `@Optional()` 데코레이터를 사용하십시오.

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

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

위의 예에서 우리는 커스텀 제공자를 사용하고 있는데, 이것이 우리가 `HTTP_OPTIONS` 커스텀 **토큰**을 포함하는 이유입니다. 이전 예제는 생성자에서 클래스를 통한 종속성을 나타내는 생성자 기반 주입을 보여줍니다. 사용자 지정 공급자 및 관련 토큰에 대한 자세한 내용은 [여기](https://app.gitbook.com/fundamentals/custom-providers)를 참조하십시오.

## Property-based injection

우리가 지금까지 사용한 기술은 생성자 메서드를 통해 공급자가 주입되므로 constuctor 기반 주입이라고 합니다. 매우 특정한 경우에는 **속성 기반 주입**이 유용 할 수 있습니다. 예를 들어 최상위 클래스가 하나 이상의 공급자에 의존하는 경우 생성자의 하위 클래스에서 `super()`를 호출하여 모든 공급자를 전달하는 것은 매우 지루할 수 있습니다. 이를 피하기 위해 속성 레벨에서 `@Inject()`데코레이터를 사용할 수 있습니다.

```typescript
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` 배열에 추가하면 됩니다.

```typescript
@@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
