YARP Query Parameter Based Routing (Định tuyến dựa trên Query Parameter trong YARP)
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à:
- path (đường dẫn)
- method (phương thức)
- host (máy chủ)
- headers (tiêu đề)
- 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:
"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:
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.
- Exact - Bất kỳ query parameter nào có tên đã cho phải match hoàn toàn, tùy thuộc vào giá trị của
IsCaseSensitive. - Prefix - Bất kỳ query parameter nào có tên đã cho phải match bằng prefix (tiền tố), tùy thuộc vào giá trị của
IsCaseSensitive. - Exists - Query parameter phải tồn tại và chứa bất kỳ giá trị không rỗng nào. Nếu có nhiều query parameter có cùng tên, rule cũng sẽ match.
- Contains - Bất kỳ query parameter nào có tên đã cho phải chứa bất kỳ giá trị match nào, tùy thuộc vào giá trị của
IsCaseSensitive. - NotContains - Không có query parameter nào có tên đã cho có thể chứa bất kỳ giá trị match nào, tùy thuộc vào giá trị của
IsCaseSensitive.
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.
"route8" : {
"ClusterId": "cluster1",
"Match": {
"Path": "{**catch-all}",
"QueryParameters": [
{
"Name": "queryparam8",
"Values": [ "another value" ],
"Mode": "Exact"
}
]
}Match với:
?queryparam8=another%20value
hoặc
?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.
?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.
?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 Mode là Prefix, 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.
?QueryParam2=1prefix
?QueryParam2=2prefix
?QueryParam2=1prefix-extra
?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.
?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.
?QueryParam3=value
Query parameter rỗng sẽ không match.
?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.
?QueryParam3=value1&QueryParam3=value2
Kịch bản 4 - Multiple QueryParameters (Nhiều query parameter)
Route4 yêu cầu cả QueryParam4 và QueryParam5, mỗi cái match theo Mode đã chỉ định. Các query parameter sau sẽ match route4:
?QueryParam4=value1&QueryParam5=AnyValue
?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:
?QueryParam4=value2
?QueryParam5=AnyValue