@Injectable({ scope: Scope.REQUEST })
export class TenantContext {
constructor(@Inject(REQUEST) private req: Request) {}
}
Nest has three injection scopes:
DEFAULT: one shared instance for the whole app, created at bootstrap. This is the recommended choice.REQUEST: a new instance for each incoming request. Nest throws it away after the request finishes. You can inject the request object with theREQUESTtoken.TRANSIENT: every consumer that injects the provider gets its own instance.
The cost of request scope: it bubbles up the injection chain. If a controller depends on a request-scoped service, the controller also becomes request-scoped. So does everything in between. Nest then creates all those objects on every request. This slows the app down and creates more memory work for the garbage collector.
Also, lifecycle hooks (like onModuleInit) are not called for request-scoped providers.
When you can, pass request data explicitly instead, or use AsyncLocalStorage.
DEFAULTscope is a singleton, and it is the recommended choice.REQUESTscope creates a new instance per request and can injectREQUEST.TRANSIENTscope creates a new instance per consumer.- Request scope bubbles up to everything that depends on it.
- Creating instances on every request costs performance.
Read more