Nguon: Microsoft Learn · .NET 8.0

YARP Query Parameter Based Routing (Định tuyến dựa trên Query Parameter trong YARP)

Nguồn: YARP Query Parameter Based Routing

Các proxy route (tuyến đường proxy) được chỉ định trong config hoặc qua code phải bao gồm ít nhất một path (đường dẫn) hoặc host để match (khớp). Ngoài ra, một route cũng có thể chỉ định một hoặc nhiều query parameters (tham số truy vấn) phải có trong yêu cầu.

Precedence (Thứ tự ưu tiên)

Thứ tự match route mặc định là:

  1. path (đường dẫn)
  2. method (phương thức)
  3. host (máy chủ)
  4. headers (tiêu đề)
  5. query parameters (tham số truy vấn)

Điều đó có nghĩa là một route chỉ định methods và không có query parameters sẽ match trước một route chỉ định query parameters và không có methods. Điều này có thể được ghi đè bằng cách đặt thuộc tính Order trên một route (xem ví dụ trong config properties).

Configuration (Cấu hình)

Query Parameters được chỉ định trong phần Match của một proxy route.

Nếu nhiều query parameter rules được chỉ định trên một route thì tất cả phải match để route được chọn. Logic OR phải được triển khai trong một query parameter rule hoặc dưới dạng các route riêng biệt.

Cấu hình:

json
"Routes": {
  "route1" : {
    "ClusterId": "cluster1",
    "Match": {
      "Path": "{**catch-all}",
      "QueryParameters": [
        {
          "Name": "queryparam1",
          "Values": [ "value1" ],
          "Mode": "Exact"
        }
      ]
    }
  },
  "route2" : {
    "ClusterId": "cluster1",
    "Match": {
      "Path": "{**catch-all}",
      "QueryParameters": [
        {
          "Name": "queryparam2",
          "Values": [ "1prefix", "2prefix" ],
          "Mode": "Prefix"
        }
      ]
    }
  },
  "route3" : {
    "ClusterId": "cluster1",
    "Match": {
      "Path": "{**catch-all}",
      "QueryParameters": [
        {
          "Name": "queryparam3",
          "Mode": "Exists"
        }
      ]
    }
  },
  "route4" : {
    "ClusterId": "cluster1",
    "Match": {
      "Path": "{**catch-all}",
      "QueryParameters": [
        {
          "Name": "queryparam4",
          "Values": [ "value1", "value2" ],
          "Mode": "Exact"
        },
        {
          "Name": "queryparam5",
          "Mode": "Exists"
        }
      ]
    }
  },
  "route5" : {
    "ClusterId": "cluster1",
    "Match": {
      "Path": "{**catch-all}",
      "QueryParameters": [
        {
          "Name": "queryparam5",
          "Values": [ "value1", "value2" ],
          "Mode": "Contains"
        },
        {
          "Name": "queryparam6",
          "Mode": "Exists"
        }
      ]
    }
  },
   "route6" : {
    "ClusterId": "cluster1",
    "Match": {
      "Path": "{**catch-all}",
      "QueryParameters": [
        {
          "Name": "queryparam6",
          "Values": [ "value1", "value2" ],
          "Mode": "NotContains"
        },
        {
          "Name": "queryparam7",
          "Mode": "Exists"
        }
      ]
    }
  }
}

Code:

csharp
var routes = new[]
{
    new RouteConfig()
    {
        RouteId = "route1",
        ClusterId = "cluster1",
        Match = new RouteMatch
        {
            Path = "{**catch-all}",
            QueryParameters = new[]
            {
                new RouteQueryParameter()
                {
                    Name = "QueryParam1",
                    Values = new[] { "value1" },
                    Mode = QueryParameterMatchMode.Exact
                }
            }
        }
    },
    new RouteConfig()
    {
        RouteId = "route2",
        ClusterId = "cluster1",
        Match = new RouteMatch
        {
            Path = "{**catch-all}",
            QueryParameters = new[]
            {
                new RouteQueryParameter()
                {
                    Name = "QueryParam2",
                    Values = new[] { "1prefix", "2prefix" },
                    Mode = QueryParameterMatchMode.Prefix
                }
            }
        }
    },
    new RouteConfig()
    {
        RouteId = "route3",
        ClusterId = "cluster1",
        Match = new RouteMatch
        {
            Path = "{**catch-all}",
            QueryParameters = new[]
            {
                new RouteQueryParameter()
                {
                    Name = "QueryParam3",
                    Mode = QueryParameterMatchMode.Exists
                }
            }
        }
    },
    new RouteConfig()
    {
        RouteId = "route4",
        ClusterId = "cluster1",
        Match = new RouteMatch
        {
            Path = "{**catch-all}",
            QueryParameters = new[]
            {
            new RouteQueryParameter()
                {
                    Name = "QueryParam4",
                    Values = new[] { "value1", "value2" },
                    Mode = QueryParameterMatchMode.Exact
                },
                new RouteQueryParameter()
                {
                    Name = "QueryParam5",
                    Mode = QueryParameterMatchMode.Exists
                }
            }
        }
    },
    new RouteConfig()
    {
        RouteId = "route5",
        ClusterId = "cluster1",
        Match = new RouteMatch
        {
            Path = "{**catch-all}",
            QueryParameters = new[]
            {
                new RouteQueryParameter()
                {
                    Name = "QueryParam5",
                    Values = new[] { "value1", "value2" },
                    Mode = QueryParameterMatchMode.Contains
                }
            }
        }
    },
    new RouteConfig()
    {
        RouteId = "route6",
        ClusterId = "cluster1",
        Match = new RouteMatch
        {
            Path = "{**catch-all}",
            QueryParameters = new[]
            {
                new RouteQueryParameter()
                {
                    Name = "QueryParam6",
                    Values = new[] { "value1", "value2" },
                    Mode = QueryParameterMatchMode.NotContains
                }
            }
        }
    }
};

Contract (Hợp đồng)

RouteQueryParameter định nghĩa code contract và được ánh xạ từ cấu hình.

Name (Tên)

Tên query parameter cần kiểm tra trong yêu cầu. Cần có giá trị không rỗng. Trường này không phân biệt chữ hoa chữ thường.

Values (Các giá trị)

Danh sách các giá trị có thể để tìm kiếm. Query parameter phải match ít nhất một trong các giá trị này theo Mode được chỉ định ngoại trừ 'NotContains'. Cần ít nhất một giá trị trừ khi Mode được đặt thành Exists.

Mode (Chế độ)

QueryParameterMatchMode chỉ định cách match các giá trị với request query parameter. Mặc định là Exact.

IsCaseSensitive (Phân biệt chữ hoa/thường)

Cho biết liệu việc match giá trị có nên thực hiện phân biệt chữ hoa chữ thường hay không. Mặc định là false, không phân biệt.

Encoding (Mã hóa)

Query string của yêu cầu sẽ được phân tích và decode trước khi matching với các route rules.

json
   "route8" : {
    "ClusterId": "cluster1",
    "Match": {
      "Path": "{**catch-all}",
      "QueryParameters": [
        {
          "Name": "queryparam8",
          "Values": [ "another value" ],
          "Mode": "Exact"
        }
      ]
    }

Match với:

code
?queryparam8=another%20value

hoặc

code
?queryparam8=another+value

Examples (Ví dụ)

Các ví dụ này sử dụng cấu hình được chỉ định ở trên.

Kịch bản 1 - Exact Query Parameter Match (Khớp query parameter chính xác)

Một yêu cầu với query parameter sau sẽ match route1.

code
?QueryParam1=Value1

Nếu nhiều query parameter có cùng tên, mỗi cái sẽ được match riêng biệt. Yêu cầu sau sẽ match vì ít nhất một giá trị khớp.

code
?QueryParam1=Value1&QueryParam1=Value2

Kịch bản 2 - Multiple Values (Nhiều giá trị)

Route2 định nghĩa nhiều giá trị để tìm kiếm trong query parameter ("1prefix", "2prefix"), bất kỳ giá trị nào cũng chấp nhận được. Nó cũng chỉ định ModePrefix, vì vậy bất kỳ query parameter nào bắt đầu bằng những giá trị đó đều chấp nhận được.

Bất kỳ query parameter nào sau đây sẽ match route2.

code
?QueryParam2=1prefix
code
?QueryParam2=2prefix
code
?QueryParam2=1prefix-extra
code
?QueryParam2=2prefix-extra

Nếu nhiều query parameter có cùng tên, mỗi cái sẽ được match riêng biệt. Yêu cầu sau sẽ match vì ít nhất một giá trị khớp với một trong các prefix mong đợi.

code
?QueryParam2=foo&QueryParam2=1prefix&QueryParam2=2prefix

Kịch bản 3 - Exists (Tồn tại)

Route3 chỉ yêu cầu query parameter "QueryParam3" tồn tại với bất kỳ giá trị không rỗng nào.

Sau đây là ví dụ sẽ match route3.

code
?QueryParam3=value

Query parameter rỗng sẽ không match.

code
?QueryParam3
?QueryParam3=

Mode này hỗ trợ các query parameter có nhiều giá trị và nhiều query parameter có cùng tên vì nó không xem xét nội dung query parameter. Sau đây sẽ match.

code
?QueryParam3=value1&QueryParam3=value2

Kịch bản 4 - Multiple QueryParameters (Nhiều query parameter)

Route4 yêu cầu cả QueryParam4QueryParam5, mỗi cái match theo Mode đã chỉ định. Các query parameter sau sẽ match route4:

code
?QueryParam4=value1&QueryParam5=AnyValue
code
?QueryParam4=value2&QueryParam5=AnyValue

Những cái này sẽ không match route4 vì thiếu một trong các query parameter yêu cầu:

code
?QueryParam4=value2
code
?QueryParam5=AnyValue