

# 将 API 阶段连接到 REST API 的自定义域名的路由规则
<a name="rest-api-routing-rules"></a>

路由规则是一组条件，匹配时会调用操作。例如，规则可以将任何传入的请求路由到自定义域名，该域名包含标头 `Hello:World` 并包含指向 REST API 的 `production` 阶段的基本路径 `users`。

规则按优先级顺序进行评估，如果您将路由模式设置为 `ROUTING_RULE_THEN_API_MAPPING`，则 API Gateway 将始终在评估任何 API 映射之前评估所有路由规则。以下列表描述了路由规则如何使用条件、操作和优先级。

**条件**  
当规则的条件满足时，将执行其操作。API Gateway 最多支持两个标头条件和一个路径条件。API Gateway 会一起评估标头条件和基本路径条件。  
您可以创建不带任何条件的规则。当 API Gateway 评估此规则时，将始终执行该操作。您可以创建不带任何条件的规则作为“捕获全部”规则。  
有关标头条件的更多信息，请参阅[匹配标头条件](#rest-api-routing-rules-condition-headers)。有关路径条件的更多信息，请参阅[匹配基本路径条件](#rest-api-routing-rules-condition-path)。

**操作**  
操作是将条件与路由规则匹配的结果。当前，唯一受支持的操作是调用 REST API 的阶段。  
每条规则可以有一个操作。

**优先级**  
优先级决定了评估规则的顺序（从最低值到最高值）。规则不能具有相同的优先级。  
您可以将优先级设置为 1-1000000。如果规则的优先级为 1，则 API Gateway 首先对其进行评估。我们建议在创建规则时，在优先级间添加间隔。这有助于您切换规则的优先级并添加新规则。有关更多信息，请参阅 [更改路由规则的优先级](apigateway-routing-rules-use.md#rest-api-routing-rules-change-priority)。

有关 API Gateway 如何评估路由规则的示例，请参阅[有关 API Gateway 如何评估路由规则的示例](rest-api-routing-rules-examples.md)。

## API Gateway 路由规则条件类型
<a name="rest-api-routing-rules-condition-types"></a>

下一节介绍路由规则条件类型。仅当所有条件均为 true 时，API Gateway 才会匹配规则。

### 匹配标头条件
<a name="rest-api-routing-rules-condition-headers"></a>

创建标头条件时，可以匹配标头名称和标头 glob 值，例如 `Hello:World`。API Gateway 使用文字匹配来验证匹配标头条件。您的条件最多可以使用两个标头，并在标头之间使用 `AND`。例如，如果传入的请求包含 `Hello:World` 和 `x-version:beta`，则条件可以匹配。

标头名称匹配不区分大小写，但标头 glob 值区分大小写。`Hello:World` 将匹配 `hello:World`，但不匹配 `Hello:world`。

有关受限标头值的列表，请参阅[限制](#rest-api-routing-rules-restrictions)。

#### 将通配符与标头条件结合使用
<a name="rest-api-routing-rules-condition-headers-wildcards"></a>

只能在标头 glob 值中使用通配符，并且通配符必须是 `*prefix-match`、`suffix-match*` 或 `*contains*`。下表显示了如何使用通配符来匹配标头条件的示例。


|  标头条件  |  与路由规则匹配的请求  |  与路由规则不匹配的请求  | 
| --- | --- | --- | 
|  `x-version: a*`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/rest-api-routing-rules.html)  | 
|  `x-version: *a`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/rest-api-routing-rules.html)  | 
|  `x-version: *a*`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/rest-api-routing-rules.html)  | 
|  `x-version: *a*` 和 `x-version: *b*`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/rest-api-routing-rules.html)  | 
|  `x-version: b*` 和 `x-version: *a`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/rest-api-routing-rules.html)  | 
|  `x-version: *`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  无  | 

如果您为多个标头值创建条件（例如 `Accept:application/json,text/xml`），我们建议您将 `*contains*` 用于标头条件，并避免使用逗号 (`,`) 字符创建条件。

由于 API Gateway 按字面匹配标头条件，因此可能会以不同的方式路由语义匹配。下表显示了路由规则结果的差异。


|  标头条件  |  与路由规则匹配的请求  |  与路由规则不匹配的请求  | 
| --- | --- | --- | 
|  `Accept: *json`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/rest-api-routing-rules.html)  | 
|  `Accept: *json*`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  无  | 

### 匹配基本路径条件
<a name="rest-api-routing-rules-condition-path"></a>

创建基本路径条件时，如果传入的请求包含您指定的路径，则匹配该规则。匹配区分大小写，因此路径 `New/Users` 将与 `new/users` 不匹配。

您只能为一条基本路径创建基本路径条件。

有关受限基本路径条件的列表，请参阅[限制](#rest-api-routing-rules-restrictions)。

#### 使用基本路径条件删除基本路径
<a name="rest-api-routing-rules-condition-path-split"></a>

创建基本路径条件时，可以选择剥离基本路径。当您删除基本路径时，API Gateway 会在调用目标 API 时移除传入的匹配基本路径。这与您使用 API 映射时的行为相同。当您不删除基本路径时，API Gateway 会将整个基本路径转发到目标 API。我们建议您仅在重新创建 API 映射时才删除基本路径。

下表显示了 API Gateway 如何评估删除基本路径条件的示例。


|  条件  | 删除基本路径 |  传入请求  |  结果  | 
| --- | --- | --- | --- | 
|  如果基本路径包含 `PetStoreShopper/dogs`  |  True  |  `GET https://example.com/PetStoreShopper/dogs`  |  API Gateway 调用 `/` 资源的 `GET` 方法。  | 
|  如果基本路径包含 `PetStoreShopper/dogs`。  |  False  |  `GET https://example.com/PetStoreShopper/dogs`  |  API Gateway 调用 `PetStoreShopper/dogs` 资源的 `GET` 方法。  | 
|  如果基本路径包含 `PetStoreShopper`  |  True  |  `GET https://example.com/PetStoreShopper/dogs`  |  API Gateway 调用 `dogs` 资源的 `GET` 方法。  | 
|  如果基本路径包含 `PetStoreShopper`  |  False  |  `GET https://example.com/PetStoreShopper/dogs`  |  API Gateway 调用 `PetStoreShopper/dogs` 资源的 `GET` 方法。  | 
|  如果基本路径包含 `PetStoreShopper`  |  True  |  `GET https://example.com/PetStoreShopper?birds=available`  |  API Gateway 使用查询字符串参数 `birds=available` 调用 `/` 资源的 `GET` 方法。  | 
|  如果基本路径包含 `PetStoreShopper`  |  False  |  `GET https://example.com/PetStoreShopper?birds=available`  |  API Gateway 使用查询字符串参数 `birds=available` 调用 `/PetStoreShopper` 资源的 `GET` 方法。  | 

## 限制
<a name="rest-api-routing-rules-restrictions"></a>
+ 目标 API 和自定义域名必须位于同一个 AWS 账户中。
+ 每条规则可以有一个目标 API。
+ 您只能为私有自定义域名创建指向私有 API 的路由规则，以及为公有自定义域名创建指向公有 API 的路由规则。您不能混合公有资源和私有资源。
+ 如果自定义域名具有到 REST 和 HTTP API 的 API 映射，则不支持路由规则。
+ 最大优先级数字为 1000000。
+ 标头限制：
  + 每个 `anyOf` 条件只能包含一个标头值。
  + [RFC 7230](https://datatracker.ietf.org/doc/html/rfc7230) 规定了标头名称和标头 glob 值支持的仅有字符，即 `a-z`、`A-Z`、`0-9` 和以下特殊字符：`*?-!#$%&'.^_`|~`。
  + 可以在标头 glob 值中使用通配符，但通配符必须为 `*prefix-match`、`suffix-match*` 或 `*contains*`。不能在标头 glob 值的中间使用 `*`。
  + 不支持通配符标头名称。
  + 标头名称必须少于 40 个字符。
  + 标头 glob 值必须少于 128 个字符。
  + 中缀匹配的标头 glob 值必须少于 40 个字符。
  + 不支持将以下标头作为条件：
    + `access-control-*`
    + `apigw-*`
    + `Authorization`
    + `Connection`
    + `Content-Encoding`
    + `Content-Length`
    + `Content-Location`
    + `Forwarded`
    + `Keep-Alive`
    + `Origin`
    + `Proxy-Authenticate`
    + `Proxy-Authorization`
    + `TE`
    + `Trailers`
    + `Transfer-Encoding`
    + `Upgrade`
    + `x-amz-*`
    + `x-amzn-*`
    + `x-apigw-api-id`
    + `X-Forwarded-For`
    + `X-Forwarded-Host`
    + `X-Forwarded-Proto`
    + `x-restAPI`
    + `Via`
+ 基本路径限制：
  + 基本名称长度必须少于 128 个字符。
  + 基本路径必须仅包含字母、数字和以下字符：`$-_.+!*'()/`。

    正则表达式不支持这些字符。
  + 基本路径不能以反斜杠 (`\`) 字符开头或结尾。

# 有关 API Gateway 如何评估路由规则的示例
<a name="rest-api-routing-rules-examples"></a>

下一节显示了有关 API Gateway 如何评估路由规则和 API 映射的四个示例。

## 示例 1：仅路由规则
<a name="rest-api-routing-rules-examples-rule-only"></a>

在此示例中，自定义域名 `https://petstore.example.com` 的路由模式设置为 `ROUTING_RULE_ONLY`，并具有以下路由规则和优先级。


|  规则 ID  |  优先级  |  条件  |  Action  | 
| --- | --- | --- | --- | 
|  `abc123`  |   10   |   如果请求包含标头：`Hello:World`  |   目标 API 1   | 
|  `zzz000`  |   50   |   如果请求包含标头：`Accept:image/webp` 和 `Pet:Dog-*` 且基本路径包含 `PetStoreShopper`  |   目标 API 2   | 
|  `efg456`  |   100   |  无  |   目标 API 3   | 

下表显示了 API Gateway 如何将之前的路由规则应用于示例请求。


| 请求 | 选定的 API | 说明 | 
| --- | --- | --- | 
|  `https://petstore.example.com -h "Hello:World"`  |  目标 API 1  |  请求与路由规则 `abc123` 匹配。  | 
|  `https://petstore.example.com/PetStoreShopper -h "Hello:World", "Pet:Dog-Bella", "Accept:image/webp"`  |  目标 API 1  |  API Gateway 按优先级顺序评估所有路由规则。路由规则 `abc123` 具有第一优先级且条件匹配，因此 API Gateway 调用目标 API 1。 尽管请求的条件也与路由规则 `zzz000` 匹配，但 API Gateway 在进行匹配后不会评估任何其它路由规则。  | 
|  `https://petstore.example.com/PetStoreShopper -h "Pet:Dog-Bella", "Accept:image/webp"`  |  目标 API 2  |  请求与路由规则 `zzz000` 匹配。之所以匹配，是因为 `Pet:Dog-Bella` 是 `Pet:Dog-*` 的字符串匹配  | 
|  `https://petstore.example.com/PetStoreShopper -h "Pet:Dog-Bella"`  |  目标 API 3  |  请求与路由规则 `abc123` 不匹配。请求与路由规则 `zzz000` 不匹配，因为所有必需的标头都不存在。下一个优先级规则匹配所有传入的请求，因此 API Gateway 调用目标 API 3。  | 

## 示例 2：路由规则和 API 映射
<a name="rest-api-routing-rules-examples-rule-and-mappings"></a>

在此示例中，自定义域名 `https://petstore.diagram.example.com` 的路由模式设置为 `ROUTING_RULE_THEN_API_MAPPING`，并具有以下路由规则和 API 映射。


|  规则 ID  |  优先级  |  条件  |  Action  | 
| --- | --- | --- | --- | 
|  `abc123`  |   1   |   如果请求包含基本路径 `pets`   |   调用 `PetStore` API 的 `Prod` 阶段。  | 
|  `000zzz`  |   5   |   如果请求包含标头：`Cookie`:`*ux=beta*` 且基本路径包含 `/refunds`  |   调用 `Refunds` API 的 `Beta` 阶段。  | 

下表显示 `https://petstore.backup.example.com` 的 API 映射。


|  API 映射  |  选定的 API  | 
| --- | --- | 
|   `/refunds`   |   调用 `Refunds` API 的 `Prod` 阶段。  | 
|   `(none)`   |   调用 `Search` API 的 `Prod` 阶段。  | 

下图显示了 API Gateway 如何将之前的路由规则和 API 映射应用于示例请求。示例请求汇总在此图之后的表格中。

![\[API Gateway 如何应用之前的路由规则和 API 映射的示意图。\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/images/rr-diagram.png)


下表说明了 API Gateway 如何将之前的路由规则和 API 映射应用于示例请求。


| 请求 | 选定的 API | 说明 | 
| --- | --- | --- | 
|  `https://petstore.diagram.com/pets`  |  `PetStore` API 的 `Prod` 阶段。  |  请求与路由规则 `abc123` 匹配。  | 
|  `https://petstore.diagram.example.com/refunds -h "Cookie:lang=en-us;ux=beta"`  |  `Refunds` API 的 `Beta` 阶段。  |  请求与路由规则 `000zzz` 匹配。`Cookie` 标头包含此条件的正确 `*contains*` 匹配和基本路径匹配。  | 
|  `https://petstore.diagram.example.com/refunds`  |  `Refunds` API 的 `Prod` 阶段。  |  该请求没有与路由规则 `zzz000` 匹配所需的标头。如果 API Gateway 无法成功地匹配路由规则，则它会回退到 API 映射。API Gateway 可以将基本路径映射到 `Refunds` API 的 `Prod` 阶段。  | 
|  `https://petstore.diagram.example.com/`  |  `Search` API 的 `Prod` 阶段。  |  该请求将 API 映射与空路径 `(none)` 匹配。  | 

## 示例 3：具有多个级别的路由规则和 API 映射
<a name="rest-api-routing-rules-examples-rule-and-mappings-with-multiple-levels"></a>

在此示例中，自定义域名 `https://petstore.backup.example.com` 的路由模式设置为 `ROUTING_RULE_THEN_API_MAPPING`，并具有以下路由规则和 API 映射。

下表显示了 `https://petstore.backup.example.com` 的路由规则。


|  规则 ID  |  优先级  |  条件  |  Action  | 
| --- | --- | --- | --- | 
|  `abc123`  |   10   |   如果请求包含标头：`Hello:World`  |   目标 API 1   | 
|  `000zzz`  |   50   |   如果请求包含标头：`Accept`:`image/webp` 和 `Pet:Dog-*` 且基本路径包含 `PetStoreShopper`  |  目标 API 2  | 

下表显示 `https://petstore.backup.example.com` 的 API 映射。


|  API 映射  |  选定的 API  | 
| --- | --- | 
|   `PetStoreShopper`   |   目标 API 3   | 
|   `PetStoreShopper/cats`   |   目标 API 4   | 

下表说明了 API Gateway 如何将之前的路由规则和 API 映射应用于示例请求。


| 请求 | 选定的 API | 说明 | 
| --- | --- | --- | 
|  `https://petstore.example.com/PetStoreShopper -h "Accept:image/webp", "Pet:Cats" `  |  目标 API 3  |  该请求没有与路由规则 `zzz000` 匹配所需的标头。如果 API Gateway 无法成功地匹配路由规则，则它会回退到 API 映射。API Gateway 可以将基本路径映射到目标 API 3。  | 
|  `https://petstore.example.com/PetStoreShopper/cats -h "Hello:World"`  |  目标 API 1  |  请求与路由规则 `abc123` 匹配。如果路由模式设置为 `ROUTING_RULE_THEN_API_MAPPING`，则路由规则的优先级始终高于 API 映射。  | 
|  `https://petstore.example.com/Admin -h "Pet:Dog-Bella"`  |  无  |  请求与任何路由规则或 API 映射都不匹配。由于没有默认路由规则，因此 API Gateway 会拒绝调用，并向调用方发送 `403 Forbidden` 状态代码。  | 

## 示例 4：通配符域名的路由规则
<a name="rest-api-routing-rules-examples-rule-for-wildcard-domains"></a>

在此示例中，自定义域名 `https://*.example.com` 是通配符域名。通配符支持路由回同一个域的所有子域名。以下示例路由规则更改了这一行为，以支持子域名使用 `Host` 标头路由到不同的目标 API。

下表显示了 `https://*.example.com` 的路由规则。


|  规则 ID  |  优先级  |  条件  |  Action  | 
| --- | --- | --- | --- | 
|  `abc123`  |   10   |   如果请求包含标头：`Host:a.example.com`  |   目标 API 1   | 
|  `000zzz`  |   50   |   如果请求包含标头：`Host:b.example.com`  |  目标 API 2  | 
|  `efg456`  |   500   |  无  |  目标 API 3  | 

下表显示了 API Gateway 如何将之前的路由规则应用于示例请求。


| 请求 | 选定的 API | 说明 | 
| --- | --- | --- | 
|  `https://a.example.com`  |  目标 API 1  |  `Host` 标头为 `a.example.com`。此请求与路由规则 `abc123` 匹配。  | 
|  `https://b.example.com`  |  目标 API 2  |  `Host` 标头为 `b.example.com`。此请求与路由规则 `000zzz` 匹配。  | 
|  `https://testing.example.com`  |  目标 API 3  |  这与“捕获全部”路由规则 `efg456` 匹配。  | 

# 如何使用路由规则
<a name="apigateway-routing-rules-use"></a>

可以使用 AWS 管理控制台、AWS CLI 或任何 AWS SDK 创建路由规则。创建规则后，可以更改其优先级。

## 创建路由规则
<a name="rest-api-routing-rules-create"></a>

以下过程说明如何在路由模式设置为 `ROUTING_RULE_THEN_API_MAPPING` 或 `ROUTING_RULE_ONLY` 的情况下，为自定义域名创建路由规则。

------
#### [ AWS 管理控制台 ]

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 从主导航窗格中选择**自定义域名**。

1. 选择自定义域名。

1. 在**路由详情**选项卡上，选择**添加路由规则**。

1. 选择**添加新条件**以添加新条件。

   您可以添加标头或基本路径条件。要将所有传入的请求与自定义域名匹配，请不要添加条件。

1. 对于**操作**，使用下拉列表来选择目标 API 和目标阶段。

1. 选择**下一步**。

1. 在优先级字段中，为优先级输入一个数字。

   API Gateway 按优先级顺序（从最低值到最高值）评估规则。

   如果您创建的规则没有条件，我们建议您使用高值优先级。

1. 选择**创建路由规则**。

------
#### [ AWS CLI ]

以下 [create-routing-rule](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-routing-rule.html) 命令创建优先级为 50 的路由规则。在此示例中，API Gateway 将任何具有标头 `Hello:World` 和 `x-version:beta` 以及基本路径 `PetStoreShopper` 的传入请求路由到目标 API `a1b2c3`。

```
 aws apigatewayv2 create-routing-rule \
  --domain-name 'api.example.com' \
  --priority 50 \
  --conditions '[
    {
      "MatchHeaders": {
        "AnyOf": [
          {
            "Header": "Hello",
            "ValueGlob": "World"
          }
        ]
      }
    },
    {
      "MatchHeaders": {
        "AnyOf": [
          {
            "Header": "x-version",
            "ValueGlob": "beta"
          }
        ]
      }
    },
    {
      "MatchBasePaths": {
        "AnyOf": [
          "PetStoreShopper"
        ]
      }
    }
  ]'\
  --actions '[
  {
    "InvokeApi": {
      "ApiId": "a1b2c3",
      "Stage": "prod"
    }
  }
 ]'
```

输出将与以下内容类似：

```
{
    "Actions": [
        {
            "InvokeApi": {
                "ApiId": "a1b2c3",
                "Stage": "prod",
                "StripBasePath": false
            }
        }
    ],
    "Conditions": [
        {
            "MatchHeaders": {
                "AnyOf": [
                    {
                        "Header": "Hello",
                        "ValueGlob": "World"
                    }
                ]
            }
        },
        {
            "MatchHeaders": {
                "AnyOf": [
                    {
                        "Header": "x-version",
                        "ValueGlob": "beta"
                    }
                ]
            }
        },
        {
            "MatchBasePaths": {
                "AnyOf": [
                    "PetStoreShopper"
                ]
            }
        }
    ],
    "Priority": 50,
    "RoutingRuleArn": "arn:aws:apigateway:us-west-2:111122223333:/domainnames/api.example.com/routingrules/abc123",
    "RoutingRuleId": "abc123"
}
```

------

## 更改路由规则的优先级
<a name="rest-api-routing-rules-change-priority"></a>

您可以更改路由规则的优先级。这将立即生效，并可能影响 API 使用者调用自定义域名的方式。我们建议您在设置路由规则的优先级时，在规则之间留出间隔。

例如，假设两个路由规则，规则 `abc123` 的优先级为 50，规则 `zzz000` 的优先级为 150。要更改规则的优先级，以便 API Gateway 首先评估 `zzz000` 规则，您可以将规则 `zzz000` 的优先级更改为 30。

------
#### [ AWS 管理控制台 ]

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 从主导航窗格中选择**自定义域名**。

1. 选择自定义域名。

1. 在**路由详情**选项卡上，选择路由规则，然后选择**编辑**。

1. 选择**下一步**。

1. 对于优先级，请输入新的优先级。

1. 选择**保存更改**。

------
#### [ AWS CLI ]

以下 [put-routing-rule](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/put-routing-rule.html) 命令更改路由规则 `abc123` 的优先级。

```
 aws apigatewayv2 put-routing-rule \
  --domain-name 'api.example.com' \
  --priority 30 \
  --routing-rule-id abc123 \
  --conditions '[
    {
      "MatchHeaders": {
        "AnyOf": [
          {
            "Header": "Hello",
            "ValueGlob": "World"
          }
        ]
      }
    },
    {
      "MatchHeaders": {
        "AnyOf": [
          {
            "Header": "x-version",
            "ValueGlob": "beta"
          }
        ]
      }
    },
    {
      "MatchBasePaths": {
        "AnyOf": [
          "PetStoreShopper"
        ]
      }
    }
  ]'\
  --actions '[
  {
    "InvokeApi": {
      "ApiId": "a1b2c3",
      "Stage": "prod"
    }
  }
 ]'
```

输出将与以下内容类似：

```
{
    "Actions": [
        {
            "InvokeApi": {
                "ApiId": "a1b2c3",
                "Stage": "prod",
                "StripBasePath": false
            }
        }
    ],
    "Conditions": [
        {
            "MatchHeaders": {
                "AnyOf": [
                    {
                        "Header": "Hello",
                        "ValueGlob": "World"
                    }
                ]
            }
        },
        {
            "MatchHeaders": {
                "AnyOf": [
                    {
                        "Header": "x-version",
                        "ValueGlob": "beta"
                    }
                ]
            }
        },
        {
            "MatchBasePaths": {
                "AnyOf": [
                    "PetStoreShopper"
                ]
            }
        }
    ],
    "Priority": 38,
    "RoutingRuleArn": "arn:aws:apigateway:us-west-2:111122223333:/domainnames/api.example.com/routingrules/abc123",
    "RoutingRuleId": "abc123"
}
```

------

# 使用路由规则重新创建 API 映射
<a name="rest-api-routing-rules-recreate-api-mapping"></a>

可以使用路由规则重新创建 API 映射。要重新创建 API 映射，请确保开启基本路径删除。这将保留 API 映射的行为。有关更多信息，请参阅 [使用基本路径条件删除基本路径](rest-api-routing-rules.md#rest-api-routing-rules-condition-path-split)。

以下教程展示了如何将 API 映射 `https:// api.example.com/orders/v2/items/categories/5` 重新创建为路由规则，以及如何更新访问日志以记录 API Gateway 用于向 API 发送流量的路由规则 ID。

------
#### [ AWS 管理控制台 ]

**将路由模式设置为 ROUTING\$1RULE\$1THEN\$1API\$1MAPPING**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 从主导航窗格中选择**自定义域名**。

1. 选择自定义域名。

1. 对于**域详细信息**，选择**编辑**。

1. 对于**路由模式**，请选择 **ROUTING\$1RULE\$1THEN\$1API\$1MAPPING**。

1. 选择**保存** 

设置路由模式后，可以创建路由规则。

**创建路由规则**

1. 在**路由详情**选项卡上，选择**添加路由规则**。

1. 选择**添加新条件**，然后选择**路径**。

1. 对于**路径**，输入 **orders/v2/items/categories/5**。

1. 对于**删除基本路径**，选择**活动**。

1. 对于**目标 API**，请选择目标 API。

1. 对于**目标阶段**，选择目标阶段。

1. 选择**下一步**。

1. 对于优先级，请输入优先级。

   即使您保留现有的 API 映射，API Gateway 也将始终使用新的路由规则，因为路由规则始终优先于 API 映射。

1. 选择**保存更改**。

创建路由规则后，更新阶段的访问日志格式或创建新日志，以确认 API Gateway 使用路由规则来将流量发送到 API。

**更新访问日志**

1. 通过以下网址登录到 Amazon API Gateway 控制台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 选择 API。

1. 在主导航窗格中，选择**阶段**。

1. 对于**日志和跟踪**，选择**编辑**。

   如果您没有日志组，请参阅[为 API Gateway 中的 REST API 设置 CloudWatch 日志记录](set-up-logging.md)。

1. 将 **\$1context.customDomain.routingRuleIdMatched** 添加到您的日志格式。

   此日志组记录 API Gateway 用来向 API 发送流量的路由规则 ID。有关更多信息，请参阅 [我不知道 API Gateway 是如何将流量发送到 API 的](rest-api-routing-rules-troubleshoot.md#rest-api-routing-rules-logging)。

1. 选择 **Save**。

更新访问日志后，调用自定义域名。以下是一个示例 curl 命令，用于调用基本路径为 `orders/v2/items/categories/5` 的自定义域名 `https://api.example.com`。

```
curl "https://api.example.com/orders/v2/items/categories/5"
```

成功调用自定义域名后，请确认 CloudWatch Logs 显示 `routingRuleIdMatched`。要了解如何使用 CloudWatch Logs 控制台来查看日志组，请参阅[在 CloudWatch 控制台中查看 API Gateway 日志事件](view-cloudwatch-log-events-in-cloudwatch-console.md)。

------
#### [ AWS CLI ]

1. 使用以下 [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-domain-name.html) 命令更新域名 `api.example.com` 以使用路由模式 `ROUTING_RULE_THEN_API_MAPPING`。

   ```
   aws apigatewayv2 update-domain-name \
     --domain-name 'api.example.com' \
     --routing-mode ROUTING_RULE_THEN_API_MAPPING
   ```

1. 使用以下 [create-routing-rule](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-routing-rule.html) 命令创建新的路由规则，以重新创建 API 映射 `https://api.example.com/orders/v2/items/categories/5`。

   ```
   aws apigatewayv2 create-routing-rule \
     --domain-name 'api.example.com' \
     --priority 50 \
     --conditions '[
     {
       "MatchBasePaths": {
         "AnyOf": [
           "orders/v2/items/categories/5"
         ]
       }
     }
   ]' \
     --actions '[
     {
       "InvokeApi": {
         "ApiId": "a1b2c3",
         "Stage": "prod",
         "StripBasePath": true
       }
     }
   ]'
   ```

1. 使用以下 [update-stage](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-stage.html) 命令更新访问日志格式以包含 `$context.customDomain.routingRuleIdMatched` 变量。此变量记录 API Gateway 用来向 API 发送流量的路由规则 ID。可以使用此日志来确认 API Gateway 是否使用路由规则将流量发送到 API。有关更多信息，请参阅 [我不知道 API Gateway 是如何将流量发送到 API 的](rest-api-routing-rules-troubleshoot.md#rest-api-routing-rules-logging)。

   ```
   aws apigateway update-stage \
     --rest-api-id a1bc2c3 \
     --stage-name prod \
     --patch-operations "op=replace,path=/accessLogSettings/format,value='\$context.path \$context.customDomain.routingRuleIdMatched \$context.requestId \$context.extendedRequestId'"
   ```

   如果您没有日志组，请参阅[为 API Gateway 中的 REST API 设置 CloudWatch 日志记录](set-up-logging.md)。

1. 使用以下示例 curl 命令来调用基本路径为 `orders/v2/items/categories/5` 的自定义域名。

   ```
   curl "https://api.example.com/orders/v2/items/categories/5
   ```

1. 使用以下 [filter-log-events](https://docs.aws.amazon.com/cli/latest/reference/logs/filter-log-events.html) 命令，来从日志组 `access-log-group-orders` 中获取包含路由规则 ID `abc123` 的日志事件。

   ```
   aws logs filter-log-events --log-group-name access-log-group-orders --filter-pattern abc123
   ```

    这确认 API Gateway 已使用路由规则向 API 发送流量。

------

# 对路由规则相关问题进行故障排除
<a name="rest-api-routing-rules-troubleshoot"></a>

以下故障排除指南可能有助于解决与路由规则相关的问题。

## 我不知道 API Gateway 是如何将流量发送到 API 的
<a name="rest-api-routing-rules-logging"></a>

您可以使用 REST API 阶段的访问日志来记录路由规则并对其进行故障排除。您可以使用 `$context.customDomain.routingRuleIdMatched` 变量来查看 API Gateway 用于向 API 发送流量的路由规则 ID。要查看 API Gateway 用来向 API 发送流量的 API 映射，请使用 `$context.customDomain.basePathMatched` 变量。

 要记录路由规则，您需要为您的账户配置[相应的 CloudWatch Logs 角色](set-up-logging.md#set-up-access-logging-permissions) ARN，然后创建一个日志组。

以下示例访问日志组可以检索相关信息，以便对路由规则和 API 映射进行故障排除。API Gateway 仅填充它使用的路由机制的上下文变量，否则上下文变量为 `-`。

------
#### [ CLF ]

```
$context.path $context.customDomain.routingRuleIdMatched $context.customDomain.basePathMatched $context.requestId $context.extendedRequestId
```

------
#### [ JSON ]

```
{"requestPath": "$context.path", "routingRuleId" : "$context.customDomain.routingRuleIdMatched", "API mapping" : "$context.customDomain.basePathMatched", "requestId":"$context.requestId", "extendedRequestId":"$context.extendedRequestId"}
```

------
#### [ XML ]

```
<request id="$context.requestId"> <requestPath>$context.path</requestPath> <ruleId>$context.customDomain.routingRuleIdMatched</ruleId> <ApiMapping>$context.customDomain.basePathMatched</ApiMapping> <extendedRequestId>$context.extendedRequestId</extendedRequestId> </request>
```

------
#### [ CSV ]

```
$context.path,$context.customDomain.routingRuleIdMatched,$context.customDomain.basePathMatched,$context.requestId,$context.extendedRequestId
```

------

我们还建议您确认自定义域名的路由模式。有关更多信息，请参阅 [为自定义域名设置路由模式](set-routing-mode.md)。

## 我无法对自定义域名启用路由规则
<a name="rest-routing-rules-access-denied"></a>

您可能会从 API Gateway 收到以下错误：

```
Your account doesn’t have permission to use RoutingRules.
This might be caused by an IAM policy in your account with a deny statement on BasePathMapping or ApiMapping.
To grant permission for this account to use RoutingRules, use the UpdateAccount API.
This will impact any existing IAM policies that deny access to BasePathMapping or ApiMapping.
See API Gateway documentation for further details.
```

如果 IAM 策略拒绝访问 [BasePathMapping](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonapigatewaymanagement.html#amazonapigatewaymanagement-resources-for-iam-policies) 或 [ApiMapping](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonapigatewaymanagementv2.html#amazonapigatewaymanagementv2-resources-for-iam-policies)，您将收到此错误。当您为自定义域名启用路由规则时，尽管策略将继续拒绝访问 `BasePathMapping` 或 `ApiMapping`，但可以使用相同的策略来访问 `RoutingRule`。这可能支持用户更改自定义域名的路由行为。

例如，如果您有类似以下内容的策略：

```
{
    "Sid": "DenyCreatingApiMappings",
    "Effect": "Deny",
    "Action": "apigateway:POST",
    "Resource": [
        "arn:aws:apigateway:us-west-2::/domainnames/example.com/apimappings"
    ]
}
```

当您为 `example.com` 启用路由规则时，此策略将继续拒绝旨在创建 `ApiMapping` 的访问，但不会拒绝旨在创建 `RoutingRule` 的访问。

我们建议您对账户中的 IAM 策略进行审计。以下示例策略将拒绝旨在创建 `ApiMapping`、`BasePathMapping` 和 `RoutingRule` 的访问：

```
{
    "Sid": "DenyCreatingBasePathMappingsApiMappings",
    "Effect": "Deny",
    "Action": "apigateway:POST",
    "Resource": [
        "arn:aws:apigateway:us-west-2::/domainnames/example.com/basepathmappings",
        "arn:aws:apigateway:us-west-2::/domainnames/example.com/apimappings"
    ]
},
{
    "Sid": "DenyCreatingRoutingRules",
    "Effect": "Deny",
    "Action": "apigateway:CreateRoutingRule",
    "Resource": [
        "arn:aws:apigateway:us-west-2:111122223333:/domainnames/example.com/routingrules/*"
    ]
}
```

确认所有策略都已更新后，您可以更新 API 的账户级设置，以便为区域启用路由规则。

使用以下 [update-account](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-account.html) 命令可针对区域更新 API 的账户级设置的设置：

```
aws apigateway update-account --patch-operations 'op=remove,path=/features,value=BlockedForRoutingRules' --region us-west-2
```

更新 API 的账户级设置后，您可以更改自定义域名的路由模式。也可以继续使用 IAM 策略来拒绝访问 `RoutingRules`、`ApiMapping` 或 `BasePathMapping`。