RequestContextMiddleware: Request Context Management in Xeno
What Is RequestContextMiddleware?
Section titled “What Is RequestContextMiddleware?”RequestContextMiddleware is the first middleware registered by Xeno’s
MiddlewareModule. It extracts metadata from the incoming HTTP headers, maps
that metadata and the request transport data into a RequestContext, and runs
the remaining middleware chain inside IRequestContext.runAsync().
The context gives downstream middleware, Controllers, Handlers, and application services access to request-scoped information such as identity, network data, correlation IDs, request IDs, and tracing data.
How Does RequestContextMiddleware Work?
Section titled “How Does RequestContextMiddleware Work?”For each request, the middleware performs the following steps:
- It generates fallback values for
correlationId,requestId, andspanId. - It extracts metadata from the HTTP headers through
IServiceExtractor.extract(headers). - It merges the extracted metadata with the fallback identifiers.
- It maps the metadata, request path, transport object, and initial
GUESTidentity into a temporary request context throughContextMapper.map(). - It executes
next()insideIRequestContext.runAsync(). - It logs unsuccessful response data when the downstream response reports a failed result.
- It returns the downstream response to the transport adapter.
The middleware creates the execution boundary for the request. It does not
authenticate the caller itself. Authentication is handled later by
AuthenticationMiddleware.
Which Metadata Does It Extract?
Section titled “Which Metadata Does It Extract?”The injected IServiceExtractor returns Metadata from the request headers.
The metadata can provide request information used by the Xeno context, such as
correlation, request, span, network, and format data.
The middleware applies these fallback rules:
correlationId: extracted value or a newly generated identifier;requestId: extracted value or a newly generated identifier;spanId: extracted value or the generated correlation identifier;formatIndicator: the extracted value supplied inmeta.formatIndicator.
The current implementation initializes formatIndicator to
application/json for unexpected-error responses. It does not explicitly
replace a missing meta.formatIndicator in the mapped context with that local
fallback value.
How Is the Initial Identity Set?
Section titled “How Is the Initial Identity Set?”Before authentication runs, RequestContextMiddleware maps the initial identity
as GUEST. This establishes an unauthenticated identity for downstream request
processing.
AuthenticationMiddleware can later replace this identity by calling
IRequestContext.updateIdentity() after successful authentication.
How Is the Request Context Created?
Section titled “How Is the Request Context Created?”The middleware uses ContextMapper.map() to build the context from:
- extracted and generated metadata;
- the incoming request path;
- the request transport object;
- the initial
GUESTidentity.
It then passes the mapped context to IRequestContext.runAsync(). The callback
provided to runAsync() invokes next(), so every middleware and Handler after
RequestContextMiddleware executes inside the request context.
How Are Downstream Failures Logged?
Section titled “How Are Downstream Failures Logged?”After runAsync() resolves, the middleware checks the returned ResponseDto.
When result.ok is false and result.data.success is also false, it logs the
error message and response data through ILogger.error().
The middleware does not replace the downstream error response. It returns the original result after logging it.
How Are Unexpected Exceptions Handled?
Section titled “How Are Unexpected Exceptions Handled?”If metadata extraction, context mapping, context execution, or downstream processing throws an exception, the middleware catches it and logs:
RequestContextMiddleware encountered an errorIt then returns a system-error response with:
ERROR_CODES.SYSTEM_ERRORas the error code;- the standard system-error message;
- the request path and fatal system-error details;
- generated correlation, request, and span identifiers;
STATUS_CODES.INTERNAL_SERVER_ERRORas the HTTP status;application/jsonas theContent-Typevalue.
The current implementation does not expose the caught exception or stack trace
in the returned response and does not branch on NODE_ENV.
Which Dependencies Does It Use?
Section titled “Which Dependencies Does It Use?”RequestContextMiddleware receives these dependencies through constructor
injection:
IRequestContext<RequestContext, ApplicationRegistry<unknown>>, used to create the asynchronous context and provide the request-context boundary;IServiceExtractor<HttpHeaders, Metadata>, used to extract metadata from request headers;ILogger, used to record downstream failures and unexpected exceptions.
Where Does It Run in the Middleware Chain?
Section titled “Where Does It Run in the Middleware Chain?”MiddlewareModule adds RequestContextMiddleware first and then registers the
remaining enabled middleware with CompositeMiddleware:
RequestContextMiddleware -> OptionsMiddleware (when optionsMiddleware is true) -> MethodCheckMiddleware (when routeRegistry is defined) -> CsrfMiddleware (when csrf is defined) -> RateLimitMiddleware (when a rate-limit option is defined) -> AuthenticationMiddleware -> Controller or HandlerBecause it establishes the request context around next(), it must execute
before middleware that reads context values, including authentication, CSRF,
rate limiting, and method-check error handling.
Constraints and Limitations
Section titled “Constraints and Limitations”RequestContextMiddlewareinitializes the context but does not authenticate the request.- The initial identity is always
GUESTuntil another middleware updates it. - Fallback identifiers are generated per request when metadata does not provide them.
- Unexpected exceptions are converted into a
500 Internal Server Errorresponse. - Downstream error responses are logged but returned unchanged.
- The middleware depends on a correctly configured
IServiceExtractorto provide request metadata.
Support Us
Section titled “Support Us”Xeno is an MIT-licensed open source project. It can grow thanks to the support of these awesome people. If you’d like to join them, please read more at support section