Sample: MicroservicesHttpGrpc¶
Scenario¶
Gateway receives HTTP traffic and calls:
- Service A over HTTP
- Service B over gRPC
Both paths must carry the same context model without duplicating mapping logic.
Why this matters¶
- mixed transport stacks are common in modern .NET systems
- teams often implement inconsistent header/metadata adapters
- debugging is easier when correlation model is shared
Context contract¶
public sealed class CorrelationContext
{
public string? TraceId { get; set; }
public string? SpanId { get; set; }
public List<string>? Tags { get; set; }
}
Registration¶
builder.Services.AddContextR(ctx =>
{
ctx.Add<CorrelationContext>(reg => reg
.UseInlineJsonPayloads<CorrelationContext>(o =>
{
o.MaxPayloadBytes = 256;
o.OversizeBehavior = ContextOversizeBehavior.SkipProperty;
})
.UseChunkingPayloads<CorrelationContext>()
.UseStrategyPolicy<CorrelationContext>(sp => policyContext =>
policyContext.Key == "X-Tags"
? ContextOversizeBehavior.ChunkProperty
: ContextOversizeBehavior.SkipProperty)
.MapProperty(c => c.TraceId, "X-Trace-Id")
.MapProperty(c => c.SpanId, "X-Span-Id")
.MapProperty(c => c.Tags, "X-Tags")
.UseAspNetCore()
.UseGlobalHttpPropagation()
.UseGlobalGrpcPropagation());
});
Flow¶
- HTTP middleware extracts context at gateway boundary.
- Outgoing HTTP handler injects mapped values for Service A.
- gRPC interceptors inject/extract same context for Service B.
- Oversize
Tagsfollow runtime strategy policy.
Suggested integration tests¶
- HTTP request round-trips trace/span across gateway and Service A
- gRPC call round-trips same trace/span to Service B
- oversize
Tagsare chunked and reassembled - malformed payload follows configured failure policy