.Net Core 使用反向代理-YARP

前言
在參考Clearn Architecture時,看到的一個有趣的東東 YARP 反向代理套件,用來實作Api Gateway架構(如下圖),將多個微服務集合起來,對外統一端點、負載平載、壓縮、緩存等。
圖片來源:微軟電子書

什麼是YARP
  微軟開源的專案,運用 .NET (.NET Core) 建置高效能反向代理,Y特點是容易自訂,用戶可以根據需求,自訂並且調整成來滿足特殊場景的需求。
提供了兩個主要使用和自訂的方向,第一個是作為一個全功能代理;另一種使用方式,則是將 YARP 用於高度自定義的環境,用戶可以直接呼叫 YARP 請求轉送程式,繞過路由和負載平衡等模組。開發者甚至可以在同一個程序中混合兩種方式,根據路由切換。(參考來源twMVC)

POC實作
本文將新增一個ApiGatewary專案及2個WebAPI專案,由ApiGatewary統一對外存取WebAPI。

1.新增ApiGatewary 專案
加入套件
Install-Package Yarp.ReverseProxy -Version 1.1.1
Program.cs  啟用YARP
builder.Services.AddReverseProxy()
    .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
..
app.MapReverseProxy();

2.新增 WebAPI專案-Product 回傳產品資訊
https://localhost:7298/api/products/Product
    [Route("api/products/[controller]")]
    public class ProductController : ControllerBase
    {
        [HttpGet]
        public IEnumerable<Product> Get()
        {
            List<Product> products = GeTestData();
            return products;
        }
..
...略

3.新增 WebAPI專案-Order 回傳訂單資訊
https://localhost:7033/api/orders/Order
    [Route("api/orders/[controller]")]
    public class OrderController : ControllerBase
    {
        [HttpGet()]
        public IEnumerable<Order> Get()
        {
            List<Order> orders = GetTestData();
            return orders;
        }
...略

4.ApiGatewary 加入組態
  • Routes :對外的端點路由
    • Transforms :將match的路徑,轉成實際對應WebAPI的路徑。例如:對外端點 /product-api/ 轉成api/products
  • Clusters : 路由匹配的目前主機
  "ReverseProxy": {
        "Routes": {
            "productsRoute": {
                "ClusterId": "productsCluster",
                "Match": {
                    "Path": "/product-api/{**catch-all}"
                },
                "Transforms": [
                    { "PathRemovePrefix": "/product-api" },
                    { "PathPrefix": "/api/products" },
                    { "RequestHeadersCopy": "true" },
                    { "RequestHeaderOriginalHost": "true" }
                ]
            },
            "ordersRoute": {
                "ClusterId": "ordersCluster",
                "Match": {
                    "Path": "/order-api/{**catch-all}"
                },
                "Transforms": [
                    { "PathRemovePrefix": "/order-api" },
                    { "PathPrefix": "/api/orders" },
                    { "RequestHeadersCopy": "true" },
                    { "RequestHeaderOriginalHost": "true" }
                ]
            }
        },
        "Clusters": {
            "productsCluster": {
                "Destinations": {
                    "destination1": {
                        "Address": "https://localhost:7298/"
                    }
                }
            },
            "ordersCluster": {
                "Destinations": {
                    "destination1": {
                        "Address": "https://localhost:7033/"
                    }
                }
            }
        }
    }
  • 組態也可以在Runtime時,使用程式配置,自訂Provider,完整請參考
      builder.Services.AddSingleton<IProxyConfigProvider>(new CustomProxyConfigProvider())

5.測試程式,透過ApiGateway 連到對應的WebApi


其它/參考

這個網誌中的熱門文章

IIS 設定只允許特定IP進入