> 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/fundamentals/injection-scopes.md).

# Injection scopes

## Injection scopes

다른 언어를 사용하는 사람들에게는 Nest에서 거의 모든 것이 들어오는 요청에서 공유되는 것이 어색할 수 있습니다. 우리는 데이터베이스에 대한 연결 풀, 전역 상태등의 싱글 톤 서비스를 가지고 있습니다. 일반적으로 Node.js는 모든 요청이 별도의 스레드에 의해 처리되는 요청/응답 다중 스레드 상태 비 저장 모델을 따르지 않습니다. 따라서 싱글 톤 인스턴스를 사용하는 것은 애플리케이션에 **안전**합니다.

그러나 컨트롤러의 요청 기반 수명이 의도적인 동작 (예: GraphQL 애플리케이션의 요청별 캐시, 요청 추적 또는 다중 테넌시) 일 수 있는 경우가 있습니다. 어떻게 처리 할 수 있습니까?

## Scopes

기본적으로 모든 공급자는 싱글 톤으로 작동하고 요청 범위를 설정하며 임시 모드로 전환 할 수 있습니다. 차이점을 이해하려면 다음 표를 참조하십시오.

| `SINGLETON` | 각 공급자는 여러 클래스에서 **공유**할 수 있습니다. 공급자 수명은 응용 프로그램 수명주기와 밀접한 관련이 있습니다. 응용 프로그램이 부트 스트랩되면 모든 공급자가 이미 인스턴스화됩니다. 싱글 톤 범위가 기본적으로 사용됩니다. |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `REQUEST`   | 요청 처리가 완료된 후 수신되는 모든 **요청**및 가비지에 대해 제공자의 새 인스턴스가 독점적으로 작성됩니다.                                                                   |
| `TRANSIENT` | 일시적인 제공자는 제공자간에 공유 할 수 없습니다. 다른 공급자가 Nest 컨테이너에 특정 임시 공급자를 요청할 때마다 컨테이너는 새로운 전용 인스턴스를 만듭니다.                                      |

> info **힌트** 싱글 톤 스코프를 사용하는 것이 항상 **권장되는** 방법입니다. 요청간에 공급자를 공유하면 메모리 소비가 줄어들어 애플리케이션 성능이 향상됩니다 (매번 클래스를 인스턴스화하지 않아도 됨).

## Usage

다른 주입 범위로 전환하려면`@Injectable()`데코레이터에 인수를 전달해야 합니다.

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

@Injectable({ scope: Scope.REQUEST })
export class CatsService {}
```

[custom provider](https://app.gitbook.com/fundamentals/custom-providers)의 경우 추가`scope` 속성을 설정해야합니다.

```typescript
{
  provide: 'CACHE_MANAGER',
  useClass: CacheManager,
  scope: Scope.TRANSIENT,
}
```

컨트롤러에 관해서는 `ControllerOptions` 객체를 전달하십시오 :

```typescript
@Controller({
  path: 'cats',
  scope: Scope.REQUEST,
})
export class CatsController {}
```

> warning **알림** 게이트웨이는 단일 범위 역할을 하므로 요청 범위 공급자에 의존해서는 안됩니다. 하나의 게이트웨이는 내부의 실제 소켓을 캡슐화하며 여러번 인스턴스화 할 수 없습니다.

## Per-request injection

요청 범위의 공급자는 매우 신중하게 사용해야합니다. 스코프는 **인젝션 체인**에서 실제로 버블링됨을 명심하십시오. 컨트롤러가 요청 범위의 공급자에 의존하는 경우 컨트롤러도 실제로 요청 범위입니다.

`CatsController<-CatsService<-CatsRepository` 체인을 상상해 보십시오. `CatsService`가 요청 범위 (및 나머지는 이론적으로 싱글 톤) 인 경우, `CatsController`도 요청 범위가 됩니다 (요청 범위가 지정된 인스턴스는 새로 작성된 컨트롤러에 삽입되어야하기 때문에). 반면에 `CatsRepository`는 싱글 톤으로 남아 있을 것입니다.

> **경고** 이 경우 순환 종속성은 매우 고통스러운 부작용으로 이어질 수 있으므로 부작용을 일으키지 않아야 합니다.

## Request provider

HTTP 애플리케이션에서 요청 범위 제공자를 사용하면 원래 요청 참조를 삽입 할 수 있습니다.

```typescript
import { Injectable, Scope, Inject } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(REQUEST) private readonly request: Request) {}
}
```

그러나 이 기능은 마이크로 서비스 또는 GraphQL 응용 프로그램에서는 작동하지 않습니다. [GraphQL](https://app.gitbook.com/graphql/quick-start) 애플리케이션에서 대신 `CONTEXT`를 삽입 할 수 있습니다.

```typescript
import { Injectable, Scope, Inject } from '@nestjs/common';
import { CONTEXT } from '@nestjs/graphql';

@Injectable({ scope: Scope.REQUEST })
export class CatsService {
  constructor(@Inject(CONTEXT) private readonly context) {}
}
```

그런 다음 `context` 값 (`GraphQLModule`)을 구성하여 `request`를 특성으로 포함할 수 있습니다.

## Performance

요청 범위 공급자를 사용하면 분명히 응용 프로그램 성능에 영향을 미칩니다. Nest가 가능한 한 많은 메타 데이터를 캐시하려고 시도하더라도 각 요청마다 클래스의 인스턴스를 작성해야 합니다. 따라서 평균 응답 시간과 전반적인 벤치마킹 결과가 느려집니다. 공급자가 반드시 요청 범위를 지정할 필요가 없다면 싱글 톤 범위를 고수해야합니다.
