Careeroza
Provider Scopes
DEFAULT, REQUEST and TRANSIENT
| Scope | Instances | Use for |
|---|---|---|
DEFAULT (singleton) | One for the whole app | Almost everything (services, repositories) |
REQUEST | A new one for every HTTP request | Per-request data: tenant id, request id, current user |
TRANSIENT | A new one for every class that injects it | Stateful helpers like a logger with a context name |
import { Inject, Injectable, Scope } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import type { Request } from 'express';
@Injectable({ scope: Scope.REQUEST })
export class TenantContext {
constructor(@Inject(REQUEST) private readonly request: Request) {}
get tenantId() {
return this.request.headers['x-tenant-id'] as string;
}
}
@Injectable({ scope: Scope.TRANSIENT })
export class ContextLogger {
private context = 'App';
setContext(name: string) { this.context = name; }
log(msg: string) { console.log(`[${this.context}] ${msg}`); }
}Note: Request scope bubbles up: any provider or controller that injects a request-scoped provider also becomes request-scoped, and is created again for every request. That costs performance, so use it only when needed.
Scopes Simulated
Example
Three "requests" hit the app. Watch how many instances each scope creates:
type Scope = 'DEFAULT' | 'REQUEST' | 'TRANSIENT';
let created = 0;
class Thing {
readonly id = ++created;
constructor(readonly scope: Scope) {}
}
const singleton = new Thing('DEFAULT');
function handleRequest(reqNo: number): void {
const requestThing = new Thing('REQUEST'); // one per request
const consumers = ['OrdersService', 'PaymentsService'];
for (const consumer of consumers) {
const transient = new Thing('TRANSIENT'); // one per consumer
console.log(
'req', reqNo, consumer.padEnd(16),
'DEFAULT#' + singleton.id, 'REQUEST#' + requestThing.id, 'TRANSIENT#' + transient.id,
);
}
}
for (let i = 1; i <= 3; i++) handleRequest(i);
console.log('total instances created:', created);Output
req 1 OrdersService DEFAULT#1 REQUEST#2 TRANSIENT#3 req 1 PaymentsService DEFAULT#1 REQUEST#2 TRANSIENT#4 req 2 OrdersService DEFAULT#1 REQUEST#5 TRANSIENT#6 req 2 PaymentsService DEFAULT#1 REQUEST#5 TRANSIENT#7 req 3 OrdersService DEFAULT#1 REQUEST#8 TRANSIENT#9 req 3 PaymentsService DEFAULT#1 REQUEST#8 TRANSIENT#10 total instances created: 10