Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ServiceComposer/ServiceComposer.AspNetCore/llms.txt

Use this file to discover all available pages before exploring further.

EndpointsExtensions bridges the composition handler registry with ASP.NET Core’s endpoint routing. Calling MapCompositionHandlers scans every registered ICompositionRequestsHandler, ICompositionEventsSubscriber, and IEndpointScopedViewModelFactory, groups them by HTTP method and route template, and wires up the corresponding endpoints. The ComposedRequestIdHeader constant and HttpContextExtensions.EnsureRequestIdIsSetup give handlers a standard way to propagate and track a correlation ID across all downstream calls made during a single composed request.

EndpointsExtensions

Static class in the ServiceComposer.AspNetCore namespace.

MapCompositionHandlers

public static IEndpointConventionBuilder MapCompositionHandlers(
    this IEndpointRouteBuilder endpoints)
Inspects the CompositionMetadataRegistry (populated during AddViewModelComposition) and registers one endpoint per unique HTTP-method + route-template combination. By default, GET, POST, PUT, PATCH, and DELETE handlers are mapped. Write-method endpoints (POST, PUT, PATCH, DELETE) are omitted when ViewModelCompositionOptions.DisableWriteSupport() has been called. When EnableCompositionOverControllers is active, handlers whose templates match an existing controller endpoint are wired in as action filters rather than standalone endpoints, transparently composing additional ViewModel properties onto the controller’s response.
endpoints
IEndpointRouteBuilder
required
The route builder provided by WebApplication or IApplicationBuilder.UseEndpoints. Throws ArgumentNullException if null.
Returns IEndpointConventionBuilder — allows further endpoint metadata to be attached (e.g. authorization policies, OpenAPI metadata).
var builder = WebApplication.CreateBuilder();
builder.Services.AddRouting();
builder.Services.AddViewModelComposition();

var app = builder.Build();
app.MapCompositionHandlers();
app.Run();
With endpoint conventions
app.MapCompositionHandlers()
   .RequireAuthorization("CompositionPolicy");

ComposedRequestIdHeader

Static class in the ServiceComposer.AspNetCore namespace. Defines the standard HTTP header name used to pass a composed request correlation ID between the gateway and downstream services.

Key

public const string Key = "composed-request-id";
The header name "composed-request-id". Incoming requests that include this header have their value preserved and echoed in the response. When the header is absent ServiceComposer generates a new Guid-based ID. Downstream services should read this header to correlate log entries back to the originating composed request.
// Reading the header in a downstream service:
if (request.Headers.TryGetValue(ComposedRequestIdHeader.Key, out var requestId))
{
    logger.LogInformation("Processing composed request {RequestId}", requestId);
}

HttpContextExtensions

Static class in the ServiceComposer.AspNetCore namespace. Provides helpers that operate on HttpContext during request processing.

EnsureRequestIdIsSetup

public static string EnsureRequestIdIsSetup(this HttpContext context)
Checks the incoming request for the composed-request-id header. If the header is present its value is used as-is; if absent a new Guid string is generated. In both cases the value is appended to the response headers under the same composed-request-id key, and the string is returned so handlers can forward it to downstream HTTP calls.
context
HttpContext
required
The current HTTP context.
Returns string — the request correlation ID, either sourced from the incoming header or freshly generated.
public class ProductHandler : ICompositionRequestsHandler
{
    [HttpGet("/api/products/{id}")]
    public async Task Handle(HttpRequest request)
    {
        var requestId = request.HttpContext.EnsureRequestIdIsSetup();

        // Forward the ID to a downstream service
        using var client = httpClientFactory.CreateClient();
        client.DefaultRequestHeaders.Add(ComposedRequestIdHeader.Key, requestId);
        var response = await client.GetAsync($"https://catalog-service/products/{request.RouteValues["id"]}");
        // ...
    }
}
Note: MapCompositionHandlers automatically calls EnsureRequestIdIsSetup before invoking composition handlers, so handlers typically only need to read the returned value when they need to forward it to downstream services themselves.

Build docs developers (and LLMs) love