REQUEST‑scoped Providers vs Custom Parameter Decorators for Per‑Request State
0 reputation · 17 Sept 2024, 12:30 UTC
0 reputation · 17 Sept 2024, 12:30 UTC
The goal is to decide whether to use NestJS REQUEST‑scoped providers or custom parameter decorators for handling request‑local data such as authenticated user identity.
Constraints include concurrent HTTP request handling, lifecycle management, and coupling between services. REQUEST‑scoped providers instantiate a new object per request and dispose of it after the response, while parameter decorators extract request metadata directly from the ExecutionContext without creating additional objects.
Uncertainty remains around how each approach propagates context into deeply nested services, the impact on garbage‑collection pressure under high concurrency, and compatibility with non‑HTTP contexts such as WebSocket or microservice message handling.
Specific questions:
Use a REQUEST‑scoped provider when the request‑local data must be shared across multiple nested services or injected into other classes that are part of the same request tree. This avoids passing the value manually through method arguments.
Use a custom parameter decorator when you only need read‑only access to request metadata (e.g., user ID, headers) inside a controller or a single service method, and the value does not need to be propagated to other dependencies.
For each incoming request NestJS creates a child DI container scoped to that request. When a REQUEST‑scoped provider is requested, NestJS instantiates a single instance and injects the same instance into every dependent class in the request’s dependency tree. If a singleton service tries to depend on that provider, NestJS throws a resolution error during bootstrap:
Error: Nest can't resolve dependencies of the SingletonService (?).
Please make sure that the argument RequestScopedDto at index [0] is available in the Root context.
This error occurs because singletons are created once at application start, before any request scope exists.
gc.pause_ms and heap used), will show the relative overhead.If you are unsure whether the request‑local state is large enough to affect GC, profile the average size of the object you intend to store (e.g., via process.memoryUsage() before and after creating it). If the size exceeds a few kilobytes per request, consider whether a parameter decorator combined with a lightweight service or a request‑scoped provider is more appropriate.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.