You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

YARP中多路由指向同一目标地址的实现及路径前缀移除方案

在YARP中实现多路由复用转发逻辑及优雅移除路径前缀

一、复用转发逻辑处理多路由

你可以通过两种方式避免重复代码,实现多个路由指向同一转发逻辑:

方式1:封装转发逻辑为独立委托

先把重复的转发逻辑抽成单独的RequestDelegate实例,再给多个路由绑定该实例:

// 封装通用转发逻辑
var googleMapsForward = new RequestDelegate(async httpContext =>
{
    var error = await forwarder.SendAsync(httpContext, "https://maps.googleapis.com/maps/api/",
        httpClient, requestConfig, transformer);
    if (error != ForwarderError.None)
    {
        var errorFeature = httpContext.GetForwarderErrorFeature();
        var exception = errorFeature.Exception;
        // 可在此添加异常处理逻辑
    }
});

// 给多个路由绑定同一个转发逻辑
endpoints.Map("/place/{**catch-all}", googleMapsForward);
endpoints.Map("/geocode/{**catch-all}", googleMapsForward);

方式2:用正则路由模板匹配多路径

如果路径规则统一,直接使用路由模板的正则约束,一次注册即可匹配多个目标路径:

// 同时匹配/place/xxx和/geocode/xxx格式的所有请求
endpoints.Map("/{segment:regex(place|geocode)}/{**catch-all}", async httpContext =>
{
    var error = await forwarder.SendAsync(httpContext, "https://maps.googleapis.com/maps/api/",
        httpClient, requestConfig, transformer);
    if (error != ForwarderError.None)
    {
        var errorFeature = httpContext.GetForwarderErrorFeature();
        var exception = errorFeature.Exception;
        // 异常处理逻辑
    }
});

二、优雅移除路径前缀(如/proxyme/)

当请求带有前置前缀(例如/proxyme/place/xxx),无需手动字符串切割,可通过以下两种优雅方式处理:

方式1:自定义Transformer实现前缀剥离

在自定义的HttpTransformer中,利用ASP.NET Core内置的PathString.StartsWithSegments方法处理:

public class CustomPrefixTransformer : HttpTransformer
{
    public override async ValueTask TransformRequestAsync(HttpContext httpContext,
        HttpRequestMessage proxyRequest, string destinationPrefix)
    {
        // 先执行默认转换逻辑
        await base.TransformRequestAsync(httpContext, proxyRequest, destinationPrefix);

        // 定义需要移除的前缀
        var targetPrefix = "/proxyme";
        if (httpContext.Request.Path.StartsWithSegments(targetPrefix, out var remainingPath))
        {
            // 更新当前请求路径
            httpContext.Request.Path = remainingPath;
            // 更新代理请求的目标Uri
            proxyRequest.RequestUri = new Uri(destinationPrefix + remainingPath);
        }
    }
}

方式2:利用YARP内置转换配置

注册转发时,直接通过AddTransforms配置前缀移除规则:

var requestConfig = new ForwarderRequestConfig();
// 添加路径转换规则:自动移除/proxyme前缀
requestConfig.AddTransforms(transforms =>
{
    transforms.AddPathRemovePrefix("/proxyme");
});

// 绑定带前缀的路由并使用该配置
endpoints.Map("/proxyme/{segment:regex(place|geocode)}/{**catch-all}", async httpContext =>
{
    var error = await forwarder.SendAsync(httpContext, "https://maps.googleapis.com/maps/api/",
        httpClient, requestConfig, transformer);
    // 异常处理逻辑
});

内容的提问来源于stack exchange,提问作者BeniaminoBaggins

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 00:53:27