YARP Docsv2.3
文档/路由/基于查询参数的路由

基于查询参数的路由

无论是在配置中指定,还是通过代码指定,代理路由都必须至少包含一个用于匹配的路径或主机。

YARP 基于查询参数的路由

无论是在配置中指定,还是通过代码指定,代理路由都必须至少包含一个用于匹配的路径或主机。除此之外,路由还可以指定一个或多个必须出现在请求中的查询参数。

优先级

默认的路由匹配优先级顺序为:1)路径,2)方法,3)主机,4)标头,5)查询参数。这意味着,一个指定了方法但未指定查询参数的路由,会先于一个指定了查询参数但未指定方法的路由被匹配。可以通过在路由上设置 Order 属性来覆盖这一默认顺序。

配置

查询参数在代理路由的 Match 部分中指定。

如果在一个路由上指定了多条查询参数规则,则必须全部匹配,该路由才会被采用。若要实现"或"逻辑,则必须在单条查询参数规则内部实现,或者拆分为多个独立的路由来实现。

配置:

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:
C#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
                         }
                      }
                   }
    }
};

协定

RouteQueryParameter 定义了代码协定,并从配置中进行映射。

名称

要在请求上检查的查询参数名称。必须为非空值。该字段不区分大小写。

要查找的一组可能取值的列表。除 'NotContains' 之外,查询参数必须根据指定的 Mode 至少匹配这些值中的一个。除非 Mode 设置为 Exists,否则至少需要提供一个值。

模式

QueryParameterMatchMode 指定了应如何将这些值与请求中的查询参数进行匹配。默认值为 Exact。

Exact——查询参数必须完整匹配,是否区分大小写取决于 IsCaseSensitive 的值。仅支持单个查询参数;如果存在多个同名查询参数,则匹配失败。Prefix——查询参数必须按前缀匹配,是否区分大小写取决于 IsCaseSensitive 的值。仅支持单个查询参数;如果存在多个同名查询参数,则匹配失败。Exists——该查询参数必须存在且包含任意非空值。Contains——查询参数必须包含该值才算匹配,是否区分大小写取决于 IsCaseSensitive 的值。仅支持单个查询参数;如果存在多个同名查询参数,则匹配失败。NotContains——查询参数不得包含任何一个匹配值,是否区分大小写取决于 IsCaseSensitive 的值。仅支持单个查询参数;如果存在多个同名查询参数,则匹配失败。

IsCaseSensitive

指示值匹配是否区分大小写。默认值为 false,即不区分大小写。

编码

请求的查询字符串会先经过解析和解码,然后再与路由规则进行匹配。

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

匹配以下情况:

?queryparam8=another%20value

?queryparam8=another+value

示例

以下示例均使用上文指定的配置。

场景 1 - 精确查询参数匹配

带有以下查询参数的请求将匹配 route1。

?QueryParam1=Value1

目前不支持多个同名查询参数,因此不会匹配。

?QueryParam1=Value1&QueryParam1=Value2

场景 2 - 多个值

route2 为要在查询参数中查找的值定义了多个候选值("1prefix"、"2prefix"),其中任意一个都可以接受。它还将 Mode 指定为 Prefix,因此任何以这些值开头的查询参数都可以接受。以下任意一个查询参数都会匹配 route2。

?QueryParam2=1prefix

?QueryParam2=2prefix

?QueryParam2=1prefix-extra

?QueryParam2=2prefix-extra

目前不支持多个同名查询参数,因此不会匹配。

?QueryParam2=2prefix&QueryParam2=1prefix

场景 3 - Exists

route3 只要求查询参数 "QueryParam3" 存在且包含任意非空值。以下是一个会匹配 route3 的示例。

?QueryParam3=value

空查询参数不会匹配。

?QueryParam3 ?QueryParam3=

由于该模式并不检查查询参数的具体内容,因此它确实支持包含多个值的查询参数,以及多个同名查询参数。以下情况将会匹配。

?QueryParam3=value1&QueryParam3=value2

场景 4 - 多个查询参数

route4 要求 QueryParam4 和 QueryParam5 同时存在,并分别按照各自指定的 Mode 进行匹配。以下查询参数组合将匹配 route4:

?QueryParam4=value1&QueryParam5=AnyValue

?QueryParam4=value2&QueryParam5=AnyValue

以下查询参数组合不会匹配 route4,因为它们缺少其中一个必需的查询参数:

?QueryParam4=value2

?QueryParam5=AnyValue 注意:本文作者在 AI 的协助下创作本文。了解详情

改编自 Microsoft Learn ,遵循 CC BY 4.0 许可协议。