Skip to main content

Middlewares

NuGet version NuGet Downloads

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:

  1. Observability: The LoggingMiddleware captures 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.
  2. Traceability: The DefaultHeadersMiddleware enforces required headers (like X-Request-Id) on every request, ensuring every operation can be traced across distributed services.
  3. Context Propagation: The ContextLoggingMiddleware enriches 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.RecyclableMemoryStream to 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 Request responses using RA.Utilities.Api.Response

🛠️ Getting Started​

Prerequisites​

  • .NET 10.0 or later
  • The RA.Utilities.Api package (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​

MiddlewarePurposeRegistration
LoggingMiddlewareLogs HTTP requests and responses with structured dataAddLoggingMiddleware() / UseLoggingMiddleware()
DefaultHeadersMiddlewareEnforces required headers on incoming requestsAddDefaultHeadersMiddleware() / UseDefaultHeadersMiddleware()
ContextLoggingMiddlewareEnriches log scopes with the request's correlation IDAddRequestContextLoggingMiddleware() / 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​

OptionTypeDefaultDescription
MaxBodyLogLengthint32768Maximum request/response body size (in bytes) to log before truncating
WarningThresholdMillisecondsdouble0Write an additional Warning log entry when response time exceeds this duration in ms (0 = disabled)
PathsToIgnoreISet<string>[]Request paths to skip (e.g., /swagger, /health)
ExcludedHeadersISet<string>[]Header names to redact from logs (e.g., Authorization)

DefaultHeadersMiddleware Options​

OptionTypeDefaultDescription
RequiredHeadersICollection<RequiredHeaderDefinition>[x-request-id (auto-generated, echoed)]Headers that must be present on incoming requests
PathsToIgnoreISet<string>[]Request paths to skip header validation for

RequiredHeaderDefinition​

PropertyTypeDefaultDescription
Namestring(required)The header name (e.g., X-Request-Id)
AutoGenerateboolfalseIf true, generates a GUID when header is missing
EchoInResponseboolfalseIf true, includes the header value in the response
ErrorMessagestring?nullCustom 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.Middlewaresdotnet 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.MiddlewaresNamespace RA.Utilities.Api.Middlewares (unchanged)
Extension namespace RA.Utilities.Api.Middlewares.ExtensionsExtension 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?​

Contributing​

  1. Fork → 2. Branch → 3. Change → 4. PR
ResourceURL
NuGetRA.Utilities.Api
SourceGitHub — RedonAlla/RA.Utilities
LicenseMIT
Build StatusGitHub Actions