-
Notifications
You must be signed in to change notification settings - Fork 904
Description
Title
Add ergonomic API for composing YARP proxy pipeline middleware outside MapReverseProxy(...)
Description
Today, customizing the YARP proxy pipeline requires configuring it inline:
app.MapReverseProxy(proxyPipeline =>
{
proxyPipeline.Use(async (context, next) =>
{
// policy / reroute / block
await next();
});
proxyPipeline.UseSessionAffinity();
proxyPipeline.UseLoadBalancing();
proxyPipeline.UsePassiveHealthChecks();
});This works, but it pushes a lot of logic into one large inline block and makes Program.cs harder to scan once multiple proxy-pipeline concerns exist (honeypot routing, IP/host rules, header policies, diagnostics, etc.).
For ASP.NET Core middleware, we can compose cleanly like:
app.UseMiddleware<A>();
app.UseMiddleware<B>();
app.UseMiddleware<C>();It would be a large readability improvement to support a similar pattern for the YARP proxy pipeline.
Proposed API
Allow registering proxy pipeline “middleware” in a composable way, and then mapping the proxy endpoint once:
app.UseReverseProxyPipelineMiddleware<HoneypotIpMiddleware>();
app.UseReverseProxyPipelineMiddleware<HoneypotHostMiddleware>();
app.UseReverseProxyPipelineMiddleware<BlockHeaderMiddleware>();
app.MapReverseProxy(); // maps endpoint using registered proxy-pipeline middlewares + defaultsOr alternatively:
app.UseReverseProxyPipeline(conventions =>
{
conventions.UseMiddleware<HoneypotIpMiddleware>();
conventions.UseMiddleware<HoneypotHostMiddleware>();
});
app.MapReverseProxy();Semantics
The key question is scope. Suggested semantics:
- Registered proxy-pipeline middlewares are applied to the next
MapReverseProxy()call (endpoint-scoped), similar to endpoint conventions. - (Optional) an overload to apply to all proxy endpoints if the app maps multiple reverse-proxy endpoints.
This avoids ambiguity and preserves the existing ability to create multiple reverse-proxy endpoints with different pipelines.
Why this helps
- Readability: keeps
Program.csslim and linear. - Encapsulation: each proxy step is a real middleware class (DI + unit testing friendly).
- Consistency: aligns with normal ASP.NET Core middleware composition patterns.
- Avoid inline lambdas: large proxy pipelines become manageable and reusable.
Workaround today
It’s possible to implement a custom extension that stores middleware types and applies them inside a custom MapReverseProxyWith... helper, but an official API would be more discoverable and avoid custom plumbing.