当前位置: 首页 > 工具软件 > YARP > 使用案例 >

Yarp网关代理地址的自定义操作

蔚桐
2023-12-01

上次测试了下Yarp这个微软自己家的网关,性能确实比ocelot要好不少。所以继续测试其他功能,在配置的时候,如果我有设置两个ClusterId分别要代理到两个不同的地址上去,如下的配置

  "ReverseProxy": {
    "Routes": {
      "route2": {
        "ClusterId": "cluster_product",
        "Match": {
          "Path": "/upm/{*all}"
        },
        "Transforms": [
          {}
        ]
      },
      "routeBaidu": {
        "ClusterId": "cluster_customer",
        "Match": {
          "Path": "/crm/{**catch-all}"
        }
      }
    },
    "Clusters": {
      "cluster_product": {
        "Destinations": {
          "first_destination": {
            "Address": "http://localhost:5001"
          },
          "two_destination": {
            "Address": "http://localhost:5001"
          }
        }
      },
      "cluster_customer": {
        "Destinations": {
          "baidu": {
            "Address": "http://localhost:5002"
          }
        }
      }
    }
  }

比如我想实现

请求A: http://localhost:5003/upm/user/getuser?userid=123代理到http://localhost:5001/api/user/getuser?userid=123  这个地址

请求B: http://localhost:5003/crm/user/getuser?id=123代理到 http://localhost:5002/api/user/getuser?userid=123这个地址

可是按照上面的配置如果不做什么其他改动的话,他都会分别代理到

http://localhost:5001/upm/user/getuser?userid=123

http://localhost:5002/crm/user/getuser?userid=123

 这样两个地址的,这是不我想要的地址。

后来查资料发现可以通过实现ITransformProvider来进行请求地址的自定义实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Yarp.ReverseProxy.Transforms.Builder;
using Yarp.ReverseProxy.Transforms;

namespace YarpGateWay {
    public class CutomerTransformProvider : ITransformProvider {
        public void Apply(TransformBuilderContext context) {
            context.AddRequestTransform(transformContext => {
                var pathArr = transformContext.Path.Value.Split("/").Where(b=>!string.IsNullOrEmpty(b)).Select(b=>b).ToList();
                string apiPath = "";
                switch (pathArr[0]) {
                    case "upm":
                        pathArr[0] = "api";
                        break;
                    case "crm":
                        pathArr[0] = "api";
                        break;
                    default:
                        break;
                }
                transformContext.Path = "/"+string.Join("/", pathArr);
                //transformContext.ProxyRequest.RequestUri = new Uri($"{transformContext.DestinationPrefix}/{apiPath}/{pathArr[1]}");
                return new ValueTask();
            });
        }

        public void ValidateCluster(TransformClusterValidationContext context) {
            //throw new NotImplementedException();
        }

        public void ValidateRoute(TransformRouteValidationContext context) {
            //throw new NotImplementedException();
        }
    }
}

然后在startup中服务注册下

        public void ConfigureServices(IServiceCollection services) {
            // Add the reverse proxy to capability to the server
            var proxyBuilder = services.AddReverseProxy();
            // Initialize the reverse proxy from the "ReverseProxy" section of configuration
            proxyBuilder.LoadFromConfig(_configuration.GetSection("ReverseProxy"))
                .AddTransforms<CutomerTransformProvider>();//自定义转换请求的地址
        }

这样就可以实现我要的代理请求了

 类似资料: