

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 將 API 階段連線至 REST API 自訂網域名稱的路由規則
<a name="rest-api-routing-rules"></a>

路由規則是一組條件，若符合條件，則會調用動作。例如，規則可以將包含 `Hello:World` 標頭且包含基本路徑 `users` 之自訂網域名稱的任何傳入請求，路由傳送至 REST API 的 `production` 階段。

規則會依優先順序加以評估，若您將路由模式設定為 `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 的階段。  
每一項規則可以有一個動作。

**Priority**  
優先順序決定評估規則的順序，從最低值到最高值。規則不可具有相同的優先順序。  
您可以設定的優先順序範圍為 1 到 1,000,000。如果規則的優先順序為 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>

下節說明路由規則條件類型。API Gateway 只有在所有條件都為 true 時才符合規則。

### 比對標頭條件
<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_tw/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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_tw/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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_tw/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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_tw/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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_tw/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/rest-api-routing-rules.html)  | 
|  `x-version: *`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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_tw/apigateway/latest/developerguide/rest-api-routing-rules.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/rest-api-routing-rules.html)  | 
|  `Accept: *json*`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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 映射，則不支援路由規則。
+ 最大優先順序數字為 1,000,000。
+ 標頭限制：
  + 每一項 `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 個字元。
  + infix 比對的標頭 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 個字元。
  + 基本路徑只能包含字母、數字和下列字元：`$-_.+!*'()/`。

    規則表達式 (regex) 不支援這些字元。
  + 基本路徑的開頭或結尾不可為反斜線 (`\`)。

# 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  |  Priority  |  條件  |  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  |  Priority  |  條件  |  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_tw/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` 階段。  |  請求符合空白路徑 `(none)` 的 API 映射。  | 

## 範例 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  |  Priority  |  條件  |  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  |  Priority  |  條件  |  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. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 從主要導覽窗格中，選擇 **Custom Domain Names (自訂網域名稱)**。

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. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 從主要導覽窗格中，選擇 **Custom Domain Names (自訂網域名稱)**。

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. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 從主要導覽窗格中，選擇 **Custom Domain Names (自訂網域名稱)**。

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. 在以下網址登入 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) 命令，從包含路由規則 ID `abc123` 的日誌群組 `access-log-group-orders` 取得日誌事件。

   ```
   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.
```

如果目前或過去有拒絕存取 [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) 的 IAM 政策，則會收到此錯誤。當您針對自訂網域名稱啟用路由規則時，雖然您的政策會繼續拒絕對 `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` 的存取。