Skip to content

UseReverseProxyPipelineMiddleware #2984

@carsten-riedel

Description

@carsten-riedel

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 + defaults

Or 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.cs slim 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type: IdeaThis issue is a high-level idea for discussion.needs-author-actionAn issue or pull request that requires more info or actions from the author.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions