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.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions