Middlewares
RA.Utilities.Api provides a collection of ASP.NET Core middlewares designed to solve common cross-cutting concerns in API development — including HTTP request/response logging, default header enforcement, and request context enrichment.
These middlewares were previously available in the now-deprecated RA.Utilities.Api.Middlewares standalone package and have been consolidated into RA.Utilities.Api for simpler dependency management.
🎯 Purpose
This middleware suite solves three common API challenges:
- Observability: The
LoggingMiddlewarecaptures full HTTP request/response details — method, path, headers, body, status code, and duration — using structured logging for easy querying in tools like Seq, Splunk, or Elasticsearch. - Traceability: The
DefaultHeadersMiddlewareenforces required headers (likeX-Request-Id) on every request, ensuring every operation can be traced across distributed services. - Context Propagation: The
ContextLoggingMiddlewareenriches log scopes with the request's correlation ID so downstream logs carry the context they need for debugging.
✨ Key Features
- High-Performance Logging — Uses
Microsoft.IO.RecyclableMemoryStreamto pool memory buffers, minimizing GC pressure in high-throughput applications - Structured Logging — Request/response bodies are parsed as JSON for structured log output
- Configurable Exclusion — Ignore specific paths (e.g.,
/swagger,/health) to reduce noise - Flexible Header Enforcement — Define required headers, auto-generate missing values, and echo headers back in responses
- Standardized Error Responses — Missing headers produce consistent
400 Bad Requestresponses usingRA.Utilities.Api.Response
🛠️ Getting Started
Prerequisites
- .NET 10.0 or later
- The
RA.Utilities.Apipackage (the middlewares ship as part of it — no separate install needed)
Installation
.NET CLI
dotnet add package RA.Utilities.Api
Package Manager Console
Install-Package RA.Utilities.Api
PackageReference (csproj)
<PackageReference Include="RA.Utilities.Api" Version="10.2.2" />
Hello World
Register and use the logging middleware in a few lines:
using RA.Utilities.Api.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddLoggingMiddleware();
var app = builder.Build();
app.UseLoggingMiddleware();
app.MapGet("/", () => "Hello, World!");
app.Run();
No additional setup is required — the middleware is ready to go with sensible defaults.
🧠 Core Concepts
| Middleware | Purpose | Registration |
|---|---|---|
LoggingMiddleware | Logs HTTP requests and responses with structured data | AddLoggingMiddleware() / UseLoggingMiddleware() |
DefaultHeadersMiddleware | Enforces required headers on incoming requests | AddDefaultHeadersMiddleware() / UseDefaultHeadersMiddleware() |
ContextLoggingMiddleware | Enriches log scopes with the request's correlation ID | AddRequestContextLoggingMiddleware() / UseContextLoggingMiddleware() |
All three middlewares implement IMiddleware, meaning they are activated by the DI container and support constructor injection. They are registered via extension methods in the RA.Utilities.Api.Extensions namespace.
How They Work Together
Incoming Request
│
▼
┌────────────────────────────┐
│ GlobalExceptionHandler │ ← catches exceptions from everything below
└────────────────────────────┘
│
▼
┌────────────────────────────┐
│ DefaultHeadersMiddleware │ ← validates required headers
└────────────────────────────┘
│
▼
┌────────────────────────────┐
│ LoggingMiddleware │ ← logs request/response
│ (or ContextLoggingMiddleware)│
└────────────────────────────┘
│
▼
┌────────────────────────────┐
│ Your Application Logic │
└────────────────────────────┘
│
▼
Outgoing Response
LoggingMiddleware and ContextLoggingMiddleware both create a request log scope. Register one of them, not both.
Terminology
- Middleware: A component in the ASP.NET Core request pipeline that can inspect, modify, or short-circuit requests and responses
- Structured Logging: Logging data as key-value pairs rather than plain strings, enabling powerful querying
- Required Header: An HTTP header that must be present on every request — if missing, the middleware returns a
400 Bad Request
📖 How-To Guides
Log Every Request and Response
using RA.Utilities.Api.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddLoggingMiddleware(options =>
{
options.MaxBodyLogLength = 16384; // 16 KB max body size to log
options.WarningThresholdMilliseconds = 2000; // Warn if response > 2s
options.PathsToIgnore.Add("/health"); // Skip health checks
options.ExcludedHeaders.Add("Authorization"); // Redact sensitive headers
});
var app = builder.Build();
app.UseLoggingMiddleware();
app.MapControllers();
app.Run();
Enforce Required Headers
using RA.Utilities.Api.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDefaultHeadersMiddleware(options =>
{
// x-request-id is required by default (auto-generated and echoed).
// Add another header that the caller must provide.
options.RequiredHeaders.Add(new RequiredHeaderDefinition
{
Name = "X-Tenant-Id",
AutoGenerate = false,
ErrorMessage = "X-Tenant-Id header is required for multi-tenant routing."
});
options.PathsToIgnore.Add("/health");
});
var app = builder.Build();
app.UseDefaultHeadersMiddleware();
app.MapControllers();
app.Run();
Enrich Logs with Request Context
using RA.Utilities.Api.Extensions;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRequestContextLoggingMiddleware();
var app = builder.Build();
app.UseContextLoggingMiddleware();
app.MapControllers();
app.Run();
⚙️ Configuration
LoggingMiddleware Options
| Option | Type | Default | Description |
|---|---|---|---|
MaxBodyLogLength | int | 32768 | Maximum request/response body size (in bytes) to log before truncating |
WarningThresholdMilliseconds | double | 0 | Write an additional Warning log entry when response time exceeds this duration in ms (0 = disabled) |
PathsToIgnore | ISet<string> | [] | Request paths to skip (e.g., /swagger, /health) |
ExcludedHeaders | ISet<string> | [] | Header names to redact from logs (e.g., Authorization) |
DefaultHeadersMiddleware Options
| Option | Type | Default | Description |
|---|---|---|---|
RequiredHeaders | ICollection<RequiredHeaderDefinition> | [x-request-id (auto-generated, echoed)] | Headers that must be present on incoming requests |
PathsToIgnore | ISet<string> | [] | Request paths to skip header validation for |
RequiredHeaderDefinition
| Property | Type | Default | Description |
|---|---|---|---|
Name | string | (required) | The header name (e.g., X-Request-Id) |
AutoGenerate | bool | false | If true, generates a GUID when header is missing |
EchoInResponse | bool | false | If true, includes the header value in the response |
ErrorMessage | string? | null | Custom error message when header is missing |
ContextLoggingMiddleware
This middleware has no configuration options. It reads the X-Request-Id header from the incoming request (falling back to HttpContext.TraceIdentifier if absent) and enriches the log scope automatically: every log entry within the request carries the x-request-id value and the TraceId. See the ContextLoggingMiddleware API reference for details.
🔄 Migration from RA.Utilities.Api.Middlewares
The standalone RA.Utilities.Api.Middlewares package is deprecated. If you're migrating to RA.Utilities.Api:
| Old (RA.Utilities.Api.Middlewares) | New (RA.Utilities.Api) |
|---|---|
dotnet add package RA.Utilities.Api.Middlewares | dotnet add package RA.Utilities.Api |
builder.Services.AddHttpLoggingMiddleware() | builder.Services.AddLoggingMiddleware() |
app.UseMiddleware<HttpLoggingMiddleware>() | app.UseLoggingMiddleware() |
builder.Services.AddDefaultHeadersMiddleware() | Same — no change |
app.UseMiddleware<DefaultHeadersMiddleware>() | app.UseDefaultHeadersMiddleware() |
Namespace RA.Utilities.Api.Middlewares | Namespace RA.Utilities.Api.Middlewares (unchanged) |
Extension namespace RA.Utilities.Api.Middlewares.Extensions | Extension namespace RA.Utilities.Api.Extensions |
No method-name changes are needed for the DefaultHeadersMiddleware registration — update the package reference and the using directive (RA.Utilities.Api.Extensions). For HttpLoggingMiddleware, rename to LoggingMiddleware and use the new extension methods.
🙌 Contributing & Support
Found a bug or have a suggestion?
- GitHub Issues: Report an issue
- Discussions: Start a discussion
Contributing
- Fork → 2. Branch → 3. Change → 4. PR
Links
| Resource | URL |
|---|---|
| NuGet | RA.Utilities.Api |
| Source | GitHub — RedonAlla/RA.Utilities |
| License | MIT |
| Build Status | GitHub Actions |
DefaultHeadersMiddleware
The DefaultHeadersMiddleware enforces the presence of required HTTP headers on incoming requests, ensuring consistency and traceability across your API. Unlike the deprecated package's version (which only enforced X-Request-Id), this implementation allows you to define any number of required headers with per-header configuration.
LoggingMiddleware
The LoggingMiddleware is a high-performance ASP.NET Core middleware that provides comprehensive structured logging for HTTP requests and responses. It captures the full request/response cycle — method, path, headers, body, status code, and processing duration — and logs it as structured data for easy querying in modern logging platforms.
ContextLoggingMiddleware
The ContextLoggingMiddleware enriches every log entry within a request's lifetime with the X-Request-Id correlation identifier. By establishing a logging scope at the very beginning of the pipeline, it ensures that all downstream log entries — from application code, other middlewares, or framework internals — automatically carry the request's identity.