

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

# API Gateway HTTP API
<a name="http-api"></a>

REST API 和 HTTP API 都是 RESTful API 產品。REST API 支援比 HTTP API 更多的功能，而 HTTP API 的設計具有最少功能，因此它們能以較低的價格提供。如需更多詳細資訊，請參閱 [在 REST API 與 HTTP API 之間選擇](http-api-vs-rest.md)。

您可以使用 HTTP API 將請求傳送到 AWS Lambda 函數或任何可路由的 HTTP 端點。例如，您可以在後端建立與 Lambda 函數整合的 HTTP API。當用戶端呼叫您的 API 時，API Gateway 會將請求傳送到該 Lambda 函數並傳回該函數的回應給用戶端。

HTTP API 支援 [OpenID Connect](https://openid.net/developers/how-connect-works/) 和 [OAuth 2.0](https://oauth.net/2/) 授權。它們提供跨來源資源共享 (CORS) 和自動部署的內建支援。

您可以使用 AWS 管理主控台、AWS CLI、API、CloudFormation 或軟體開發套件來建立 HTTP API。

**Topics**
+ [在 API Gateway 中開發 HTTP API](http-api-develop.md)
+ [發布 HTTP API 以供客戶調用](http-api-publish.md)
+ [在 API Gateway 中保護您的 HTTP API](http-api-protect.md)
+ [在 API Gateway 中監控 HTTP API](http-api-monitor.md)
+ [疑難排解 API Gateway 中的 HTTP API 問題](http-api-troubleshooting.md)

# 在 API Gateway 中開發 HTTP API
<a name="http-api-develop"></a>

本節提供開發 API Gateway API 時所需的 API Gateway 功能的詳細資料。

在開發 API Gateway API 時，您可以決定 API 的許多特性。這些特性取決於 API 的使用案例。例如，您可能只允許特定用戶端呼叫您的 API，或是您可能希望讓所有人都可以使用它。您可能需要 API 呼叫來執行 Lambda 函數、進行資料庫查詢或呼叫應用程式。

**Topics**
+ [建立 HTTP API](#http-api-examples)
+ [在 API Gateway 中建立 HTTP API 的路由](http-api-develop-routes.md)
+ [API Gateway 中 HTTP API 的 IP 位址類型](http-api-ip-address-type.md)
+ [在 API Gateway 中控制和管理對 HTTP API 的存取](http-api-access-control.md)
+ [在 API Gateway 中建立 HTTP API 的整合](http-api-develop-integrations.md)
+ [在 API Gateway 中設定 HTTP API 的 CORS](http-api-cors.md)
+ [在 API Gateway 中轉換 HTTP API 的 API 請求和回應](http-api-parameter-mapping.md)
+ [在 API Gateway 中使用 HTTP API 的 OpenAPI 定義](http-api-open-api.md)

## 建立 HTTP API
<a name="http-api-examples"></a>

若要建立可操作的 API，您必須至少有一個路由、整合、階段和部署。

下列範例示範如何建立具有 AWS Lambda 或 HTTP 整合的 API、路由，以及設定為自動部署變更的預設階段。

本指南假設您已經熟悉 API Gateway 和 Lambda。如需更詳細的清單，請參閱[API Gateway 入門](getting-started.md)。

**Topics**
+ [使用 建立 HTTP API AWS 管理主控台](#apigateway-http-api-create.console)
+ [使用 CLI AWS 建立 HTTP API](#http-api-examples.cli.quick-create)

### 使用 建立 HTTP API AWS 管理主控台
<a name="apigateway-http-api-create.console"></a>

1. 開啟 [API Gateway 主控台](https://console.aws.amazon.com/apigateway)。

1. 選擇 **Create API** (建立 API)。

1. 在 **HTTP API** 下，選擇 **Build** (組建)。

1. 選擇 **Add integration** (新增整合)，然後選擇 AWS Lambda 函數或輸入 HTTP 端點。

1. 在 **Name** (名稱) 中，輸入 API 的名稱。

1. 選擇 **Review and create** (檢閱和建立)。

1. 選擇 **Create** (建立)。

現在您的 API 已準備好叫用。您可以透過在瀏覽器中輸入其調用 URL 或使用 Curl 來測試您的 API。

```
curl https://api-id.execute-api.us-east-2.amazonaws.com
```

### 使用 CLI AWS 建立 HTTP API
<a name="http-api-examples.cli.quick-create"></a>

您可以使用快速建立來建立具有 Lambda 或 HTTP 整合的 API、預設的全部捕獲路由，以及設定為自動部署變更的預設階段。以下 [create-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api.html) 命令會使用快速建立來建立 API，以便與後端的 Lambda 函式整合。

**注意**  
若要叫用 Lambda 整合，API Gateway 必須具有必要的許可。您可以使用以資源為基礎的政策或 IAM 角色來授與 API Gateway 叫用 Lambda 函數的許可。若要進一步了解，請參閱《 * AWS Lambda 開發人員指南*》中的[AWS Lambda 許可](https://docs.aws.amazon.com/lambda/latest/dg/lambda-permissions.html)。

**Example**  

```
aws apigatewayv2 create-api --name my-api --protocol-type HTTP --target arn:aws:lambda:us-east-2:123456789012:function:function-name
```

現在您的 API 已準備好叫用。您可以透過在瀏覽器中輸入其調用 URL 或使用 Curl 來測試您的 API。

```
curl https://api-id.execute-api.us-east-2.amazonaws.com
```

# 在 API Gateway 中建立 HTTP API 的路由
<a name="http-api-develop-routes"></a>

將直接傳入的 API 請求路由到後端資源。路由由兩部分組成：HTTP 方法和資源路徑，例如 `GET /pets`。您可以為您的路由定義特定的 HTTP 方法。或者，您可以使用 `ANY` 方法來比對您尚未為資源定義的所有方法。您可以建立一個 `$default` 路由，充當不與任何其他路由搭配的請求的全部捕獲。

**注意**  
API Gateway 會先解碼 URL 編碼的請求參數，然後再將其傳遞至後端整合。

## 使用路徑變數
<a name="http-api-routes-path-variables"></a>

您可以在 HTTP API 路由中使用路徑變數。

例如，`GET /pets/{petID}` 路由會擷取用戶端提交給 `https://api-id.execute-api.us-east-2.amazonaws.com/pets/6` 的 `GET` 請求。

*Greedy 路徑變數*會擷取路由的所有子資源。若要建立 Greedy 路徑變數，請將 `+` 新增至變數名稱，例如 `{proxy+}`。Greedy 路徑變數必須位於資源路徑結尾。

## 使用查詢字串參數
<a name="http-api-routes-query-string-parameters"></a>

根據預設，API Gateway 會將查詢字串參數傳送至您的後端整合 (如果它們包含在對 HTTP API 的請求中)。

例如，當用戶端傳送要求給 `https://api-id.execute-api.us-east-2.amazonaws.com/pets?id=4&type=dog` 時，查詢字串參數 `?id=4&type=dog` 會傳送至您的整合。

## 使用 `$default` 路由
<a name="http-api-develop-routes.default"></a>

`$default` 路由會擷取未明確與 API 中其他路由相符的請求。

當 `$default` 路由收到請求時，API Gateway 會將完整的請求路徑傳送到整合。例如，您可以建立僅使用 `$default` 路由的 API，並將其與 `https://petstore-demo-endpoint.execute-api.com` HTTP 端點整合在 `ANY` 方法上。當您將請求傳送給 `https://api-id.execute-api.us-east-2.amazonaws.com/store/checkout` 時，API Gateway 會將請求傳送給 `https://petstore-demo-endpoint.execute-api.com/store/checkout`。

若要進一步了解 HTTP 整合，請參閱[為 HTTP API 建立 HTTP 代理整合](http-api-develop-integrations-http.md)。

## 路由傳送 API 請求
<a name="http-api-develop-routes.evaluation"></a>

當用戶端傳送 API 請求時，API Gateway 會先決定要將請求路由傳送到哪個[階段](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-stages.html)。如果請求明確符合階段，API Gateway 會將請求傳送至該階段。如果沒有任何階段完全符合請求，API Gateway 會將請求傳送到 `$default` 階段。如果沒有 `$default` 階段，則 API 會傳回 `{"message":"Not Found"}` 且不會產生 CloudWatch 日誌。

選擇階段後，API Gateway 就會選擇路由。API Gateway 會使用下列優先順序來選取具有最特定相符項目的路由：

1. 完全相符的路由和方法。

1. 使用貪婪路徑變量 (`{proxy+}`) 配對路由和方法。

1. `$default` 路由。

如果沒有路由與請求相符，API Gateway 會將 `{"message":"Not Found"}` 傳回用戶端。

例如，假設具有 `$default` 階段的 API，以及下列範例路由：

1. `GET /pets/dog/1`

1. `GET /pets/dog/{id}`

1. `GET /pets/{proxy+}`

1. `ANY /{proxy+}`

1. `$default`

   下表摘要說明 API Gateway 路由傳送請求到範例路由的方式。


| 要求 | 選取的路由 | 說明 | 
| --- | --- | --- | 
|  `GET https://api-id.execute-api.region.amazonaws.com/pets/dog/1`  |  `GET /pets/dog/1`  |  請求完全匹配此靜態路由。  | 
|  `GET https://api-id.execute-api.region.amazonaws.com/pets/dog/2`  |  `GET /pets/dog/{id}`  |  請求完全與此路由相符。  | 
|  `GET https://api-id.execute-api.region.amazonaws.com/pets/cat/1`  |  `GET /pets/{proxy+}`  |  請求不完全與路由相符。具備 `GET` 方法和貪婪路徑變量的路由會擷取這個請求。  | 
| `POST https://api-id.execute-api.region.amazonaws.com/test/5` | `ANY /{proxy+}` |  `ANY` 方法與您尚未為路由定義的所有方法相符。貪婪路徑變量的路由具有比 `$default` 路由更高的優先順序。  | 

# API Gateway 中 HTTP API 的 IP 位址類型
<a name="http-api-ip-address-type"></a>

建立 API 時，您可以指定可調用 API 的 IP 位址類型。您可以選擇 IPv4 來解析 IPv4 位址以調用 API，也可以選擇雙堆疊，以同時允許 IPv4 和 IPv6 位址調用您的 API。您可能會希望將 IP 位址類型設定為雙堆疊，以緩解 IP 空間耗盡或用於安全狀態。如需雙堆疊 IP 位址類型優點的詳細資訊，請參閱 [AWS 上的 IPv6](https://docs.aws.amazon.com/whitepapers/latest/ipv6-on-aws/internet-protocol-version-6.html)。

## IP 位址類型的考量事項
<a name="http-ip-address-type-considerations"></a>

下列考量事項可能會影響您使用 IP 位址類型：
+ HTTP API 的預設 IP 位址類型為 IPv4。
+ 如果您將現有 API 的 IP 位址類型從 IPv4 變更為雙堆疊，請確認控制存取 API 的任何政策都已更新，以便進行 IPv6 呼叫。當您變更 IP 位址類型時，變更會立即生效。
+ 您的 API 可以對應至與您的 API 具有不同 IP 位址類型的自訂網域名稱。如果您停用預設 API 端點，則可能會影響呼叫方調用 API 的方式。

## 變更 HTTP API 的 IP 位址類型
<a name="http-ip-address-type-change"></a>

您可以藉由更新 API 的組態來變更 IP 位址類型。您可以使用 AWS 管理主控台、AWS CLI、CloudFormation 或 AWS SDK 來更新 API 的組態。如果您變更 API 的 IP 位址類型，您不需重新部署 API 讓變更生效。

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

**若要變更 HTTP API 的 IP 位址類型**

1. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 選擇一個 HTTP API。

1. 針對 **API 設定**，選擇**編輯**。

1. 針對 IP 位址類型，選取 **IPv4** 或**雙堆疊**。

1. 選擇**儲存**。

   對 API 組態的變更會立即生效。

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

以下 [update-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-api.html) 命令會將 API 更新為雙堆疊 IP 位址類型：

```
aws apigatewayv2 update-api \
    --api-id abcd1234 \
    --ip-address-type dualstack
```

輸出將如下所示：

```
{
    "ApiEndpoint": "https://abcd1234.execute-api.us-east-1.amazonaws.com",
    "ApiId": "abcd1234",
    "ApiKeySelectionExpression": "$request.header.x-api-key",
    "CreatedDate": "2025-02-04T22:20:20+00:00",
    "DisableExecuteApiEndpoint": false,
    "Name": "My-HTTP-API",
    "ProtocolType": "HTTP",
    "RouteSelectionExpression": "$request.method $request.path",
    "Tags": {},
    "NotificationUris": [],
    "IpAddressType": "dualstack"
}
```

------

# 在 API Gateway 中控制和管理對 HTTP API 的存取
<a name="http-api-access-control"></a>

API Gateway 支援多種機制來控制和管理 HTTP API 的存取：
+ **Lambda 授權方** 會使用 Lambda 函數來控制 API 存取權。如需詳細資訊，請參閱[使用 AWS Lambda 授權方控制對 HTTP APIs存取](http-api-lambda-authorizer.md)。
+ **JWT 授權方**會使用 JSON 網路字符來控制對 API 的存取。如需詳細資訊，請參閱[使用 API Gateway 中的 JWT 授權方來控制對 HTTP API 的存取](http-api-jwt-authorizer.md)。
+ **標準 AWS IAM 角色和政策**提供靈活且強大的存取控制。您可以使用 IAM 角色和政策來控制誰可以建立和管理您的 API，以及誰可以叫用它們。如需詳細資訊，請參閱[使用 API Gateway 中的 IAM 授權控制對 HTTP API 的存取](http-api-access-control-iam.md)。

為了改善您的安全狀態，建議您為 HTTP API 上的所有路由設定授權方。您可能需要這樣做，才能符合各種合規架構。如需詳細資訊，請參閱《AWS Security Hub 使用者指南》**中的 [Amazon API Gateway 控制項](https://docs.aws.amazon.com/securityhub/latest/userguide/apigateway-controls.html)。

# 使用 AWS Lambda 授權方控制對 HTTP APIs存取
<a name="http-api-lambda-authorizer"></a>

您可以使用 Lambda 授權方來使用 Lambda 函數，以控制對 HTTP API 的存取權。然後，當用戶端呼叫您的 API 時，API Gateway 會叫用您的 Lambda 函數。API Gateway 會使用 Lambda 函數的回應來判斷用戶端是否可以存取您的 API。

## 裝載格式版本
<a name="http-api-lambda-authorizer.payload-format"></a>

授權方承載格式版本會指定 API Gateway 傳送到 Lambda 授權方的資料格式，以及 API Gateway 如何解釋 Lambda 的回應。如果您未指定承載格式版本， 預設 AWS 管理主控台 會使用最新版本。如果您使用 AWS CLI CloudFormation或 SDK 建立 Lambda 授權方，則必須指定 `authorizerPayloadFormatVersion`。支援的值為 `1.0` 和 `2.0`。

 如果您需要與 REST API 相容，請使用 `1.0` 版。

下列範例顯示每個裝載格式版本的結構。

------
#### [ 2.0 ]

```
{
  "version": "2.0",
  "type": "REQUEST",
  "routeArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request",
  "identitySource": ["user1", "123"],
  "routeKey": "$default",
  "rawPath": "/my/path",
  "rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
  "cookies": ["cookie1", "cookie2"],
  "headers": {
    "header1": "value1",
    "header2": "value2"
  },
  "queryStringParameters": {
    "parameter1": "value1,value2",
    "parameter2": "value"
  },
  "requestContext": {
    "accountId": "123456789012",
    "apiId": "api-id",
    "authentication": {
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "domainName": "id.execute-api.us-east-1.amazonaws.com",
    "domainPrefix": "id",
    "http": {
      "method": "POST",
      "path": "/my/path",
      "protocol": "HTTP/1.1",
      "sourceIp": "IP",
      "userAgent": "agent"
    },
    "requestId": "id",
    "routeKey": "$default",
    "stage": "$default",
    "time": "12/Mar/2020:19:03:58 +0000",
    "timeEpoch": 1583348638390
  },
  "pathParameters": { "parameter1": "value1" },
  "stageVariables": { "stageVariable1": "value1", "stageVariable2": "value2" }
}
```

------
#### [ 1.0 ]

```
{
  "version": "1.0",
  "type": "REQUEST",
  "methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request",
  "identitySource": "user1,123",
  "authorizationToken": "user1,123",
  "resource": "/request",
  "path": "/request",
  "httpMethod": "GET",
  "headers": {
    "X-AMZ-Date": "20170718T062915Z",
    "Accept": "*/*",
    "HeaderAuth1": "headerValue1",
    "CloudFront-Viewer-Country": "US",
    "CloudFront-Forwarded-Proto": "https",
    "CloudFront-Is-Tablet-Viewer": "false",
    "CloudFront-Is-Mobile-Viewer": "false",
    "User-Agent": "..."
  },
  "queryStringParameters": {
    "QueryString1": "queryValue1"
  },
  "pathParameters": {},
  "stageVariables": {
    "StageVar1": "stageValue1"
  },
  "requestContext": {
    "path": "/request",
    "accountId": "123456789012",
    "resourceId": "05c7jb",
    "stage": "test",
    "requestId": "...",
    "identity": {
      "apiKey": "...",
      "sourceIp": "...",
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "resourcePath": "/request",
    "httpMethod": "GET",
    "apiId": "abcdef123"
  }
}
```

------

## Lambda 授權方回應格式
<a name="http-api-lambda-authorizer.payload-format-response"></a>

承載格式版本會決定 Lambda 函數必須傳回的回應結構。

### 格式 1.0 的 Lambda 函數回應
<a name="http-api-lambda-authorizer.v1"></a>

如果您選擇 `1.0` 格式版本，Lambda 授權方必須傳回允許或拒絕存取 API 路由的 IAM 政策。您可以在政策中使用標準 IAM 政策語法。如需 IAM 政策範例，請參閱[控制對 API 的呼叫存取權](api-gateway-control-access-using-iam-policies-to-invoke-api.md)。您可以使用 `$context.authorizer.property` 將內容屬性傳遞給 Lambda 整合或存取日誌。`context` 物件為選擇性，`claims`是保留的預留位置，不能用作內容物件。如需詳細資訊，請參閱 [自訂 HTTP API 存取日誌](http-api-logging-variables.md)。

**Example**    
****  

```
{
  "principalId": "abcdef", 
  "policyDocument": {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow|Deny",
        "Resource": "arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
      }
    ]
  },
  "context": {
    "exampleKey": "exampleValue"
  }
}
```

### 格式 2.0 的 Lambda 函數回應
<a name="http-api-lambda-authorizer.v2"></a>

如果您選擇 `2.0` 格式版本，則可以從 Lambda 函數傳回布林值或使用標準 IAM 政策語法的 IAM 政策。要傳回一個布林值，請啟用授權方的簡易回應。下列範例會示範您必須編碼 Lambda 函數才能傳回的格式。該 `context` 物件是選用的物件。您可以使用 `$context.authorizer.property` 將內容屬性傳遞給 Lambda 整合或存取日誌。如需進一步了解，請參閱[自訂 HTTP API 存取日誌](http-api-logging-variables.md)。

------
#### [ Simple response ]

```
{
  "isAuthorized": true/false,
  "context": {
    "exampleKey": "exampleValue"
  }
}
```

------
#### [ IAM policy ]

****  

```
{
  "principalId": "abcdef", 
  "policyDocument": {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow|Deny",
        "Resource": "arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
      }
    ]
  },
  "context": {
    "exampleKey": "exampleValue"
  }
}
```

------

## 範例 Lambda 授權方函數
<a name="http-api-lambda-authorizer.example-code"></a>

下列範例 Node.js Lambda 函數會示範您需要從 Lambda 函數傳回的 `2.0` 承載格式版本的必要回應格式。

------
#### [ Simple response - Node.js ]

```
export const handler = async(event) => {
    let response = {
        "isAuthorized": false,
        "context": {
            "stringKey": "value",
            "numberKey": 1,
            "booleanKey": true,
            "arrayKey": ["value1", "value2"],
            "mapKey": {"value1": "value2"}
        }
    };
    
    if (event.headers.authorization === "secretToken") {
        console.log("allowed");
        response = {
            "isAuthorized": true,
            "context": {
                "stringKey": "value",
                "numberKey": 1,
                "booleanKey": true,
                "arrayKey": ["value1", "value2"],
                "mapKey": {"value1": "value2"}
            }
        };
    }

    return response;

};
```

------
#### [ Simple response - Python ]

```
import json


def lambda_handler(event, context):
    response = {
        "isAuthorized": False,
        "context": {
            "stringKey": "value",
            "numberKey": 1,
            "booleanKey": True,
            "arrayKey": ["value1", "value2"],
            "mapKey": {"value1": "value2"}
        }
    }

    try:
        if (event["headers"]["authorization"] == "secretToken"):
            response = {
                "isAuthorized": True,
                "context": {
                    "stringKey": "value",
                    "numberKey": 1,
                    "booleanKey": True,
                    "arrayKey": ["value1", "value2"],
                    "mapKey": {"value1": "value2"}
                }
            }
            print('allowed')
            return response
        else:
            print('denied')
            return response
    except BaseException:
        print('denied')
        return response
```

------
#### [ IAM policy - Node.js ]

```
export const handler = async(event) => {
  if (event.headers.authorization == "secretToken") {
    console.log("allowed");
    return {
      "principalId": "abcdef", // The principal user identification associated with the token sent by the client.
      "policyDocument": {
        "Version": "2012-10-17",		 	 	 
        "Statement": [{
          "Action": "execute-api:Invoke",
          "Effect": "Allow",
          "Resource": event.routeArn
        }]
      },
      "context": {
        "stringKey": "value",
        "numberKey": 1,
        "booleanKey": true,
        "arrayKey": ["value1", "value2"],
        "mapKey": { "value1": "value2" }
      }
    };
  }
  else {
    console.log("denied");
    return {
      "principalId": "abcdef", // The principal user identification associated with the token sent by the client.
      "policyDocument": {
        "Version": "2012-10-17",		 	 	 
        "Statement": [{
          "Action": "execute-api:Invoke",
          "Effect": "Deny",
          "Resource": event.routeArn
        }]
      },
      "context": {
        "stringKey": "value",
        "numberKey": 1,
        "booleanKey": true,
        "arrayKey": ["value1", "value2"],
        "mapKey": { "value1": "value2" }
      }
    };
  }
};
```

------
#### [ IAM policy - Python ]

```
import json


def lambda_handler(event, context):
    response = {
        # The principal user identification associated with the token sent by
        # the client.
        "principalId": "abcdef",
        "policyDocument": {
            "Version": "2012-10-17",		 	 	 
            "Statement": [{
                "Action": "execute-api:Invoke",
                "Effect": "Deny",
                "Resource": event["routeArn"]
            }]
        },
        "context": {
            "stringKey": "value",
            "numberKey": 1,
            "booleanKey": True,
            "arrayKey": ["value1", "value2"],
            "mapKey": {"value1": "value2"}
        }
    }

    try:
        if (event["headers"]["authorization"] == "secretToken"):
            response = {
                # The principal user identification associated with the token
                # sent by the client.
                "principalId": "abcdef",
                "policyDocument": {
                    "Version": "2012-10-17",		 	 	 
                    "Statement": [{
                        "Action": "execute-api:Invoke",
                        "Effect": "Allow",
                        "Resource": event["routeArn"]
                    }]
                },
                "context": {
                    "stringKey": "value",
                    "numberKey": 1,
                    "booleanKey": True,
                    "arrayKey": ["value1", "value2"],
                    "mapKey": {"value1": "value2"}
                }
            }
            print('allowed')
            return response
        else:
            print('denied')
            return response
    except BaseException:
        print('denied')
        return response
```

------

## 身分識別來源
<a name="http-api-lambda-authorizer.identity-sources"></a>

您可以選擇性地指定 Lambda 授權方的身分來源。身分來源會指定授權請求所需的資料位置。例如，您可以指定標頭或查詢字串值做為身分來源。如果您指定身分來源，用戶端必須將其包含在請求中。如果用戶端的請求不包含身分來源，則 API Gateway 不會叫用您的 Lambda 授權方，且用戶端會收到 `401` 錯誤。

下表說明適用於 Lambda 授權方的支援身分來源。


| **類型** | **範例** | **備註** | 
| --- | --- | --- | 
| 標頭值 | \$1request.header.name | 網域名稱需區分大小寫。 | 
| 查詢字串值 | \$1request.querystring.name | 查詢字串名稱區分大小寫。 | 
| 環境變數 | \$1context.variableName | 支援的[內容變數](http-api-logging-variables.md)值。 | 
| 階段變數 | \$1stageVariables.variableName | [階段變數](http-api-stages.stage-variables.md)的值。 | 

您也可以直接從 Lambda 函式傳回 ` {"errorMessage" : "Unauthorized"}`，以將 `401` 錯誤傳回至用戶端。如果您直接從 Lambda 函式將 `401` 錯誤傳回至用戶端，則請勿在建立 Lambda 授權方時指定任何身分來源。

## 快取授權方回應
<a name="http-api-lambda-authorizer.caching"></a>

您可藉由指定 [authorizerResultTtlInSeconds](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers.html#apis-apiid-authorizers-prop-createauthorizerinput-authorizerresultttlinseconds) 來啟用 Lambda 授權方的快取。啟用授權方的快取時，API Gateway 會使用授權方的身分來源做為快取金鑰。如果用戶端在設定的 TTL 內的身分來源中指定相同的參數，則 API Gateway 會使用快取的授權方結果，而不是叫用您的 Lambda 函數。

若要啟用快取，您的授權方必須至少有一個身分來源。

如果您為授權方啟用簡單回應，授權方的回應會完全允許或拒絕符合快取身分來源值的所有 API 請求。如需更精細的許可，請停用簡易回應並傳回 IAM 政策。根據您的授權方而定，您的 IAM 政策可能需要控制多方的存取權。

預設情況下，API Gateway 會使用快取授權回應 API 的所有路由使用授權。若要快取每個路由的回應，請新增 `$context.routeKey` 至授權方的身分來源。

## 建立 Lambda 授權方
<a name="http-api-lambda-authorizer.example-create"></a>

當您建立 Lambda 授權方時，您會指定可供 API Gateway 使用的 Lambda 函數。您必須授予 API Gateway 使用 Lambda 函數的資源政策或 IAM 角色叫用該函數的許可。以下 [create-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-authorizer.html) 命令會建立 Lambda 授權方：

```
aws apigatewayv2 create-authorizer \
    --api-id abcdef123 \
    --authorizer-type REQUEST \
    --identity-source '$request.header.Authorization' \
    --name lambda-authorizer \ 
    --authorizer-uri 'arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:my-function/invocations' \
    --authorizer-payload-format-version '2.0' \
    --enable-simple-responses
```

以下 [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) 命令會更新 Lambda 函式的資源政策，以授予 API Gateway 調用函式的許可。如果 API Gateway 沒有叫用函數的許可，用戶端會收到 `500 Internal Server Error`。

```
aws lambda add-permission \
    --function-name my-authorizer-function \
    --statement-id apigateway-invoke-permissions-abc123 \ 
    --action lambda:InvokeFunction \
    --principal apigateway.amazonaws.com \
    --source-arn "arn:aws:execute-api:us-west-2:123456789012:api-id/authorizers/authorizer-id"
```

在您建立了一個授權方並授予 API Gateway 叫用它的許可後，請更新您的路由以使用授權方。以下 [update-route](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-route.html) 命令會將 Lambda 授權方新增至路由。如果您的 Lambda 授權方使用授權快取，請務必更新政策以控制其他路由的存取。

```
aws apigatewayv2 update-route \
    --api-id abcdef123 \
    --route-id abc123 \
    --authorization-type CUSTOM \
    --authorizer-id def123
```

## Lambda 授權方疑難排解
<a name="http-api-lambda-authorizer.troubleshooting"></a>

如果 API Gateway 無法叫用您的 Lambda 授權方，或者您的 Lambda 授權方傳回無效格式的回應，則用戶端會收到 `500 Internal Server Error`。

若要故障排除錯誤，請[啟用 API 階段的存取記錄](http-api-logging.md)。在 `$context.authorizer.error` 記錄格式中包含日誌變數。

如果記錄表示 API Gateway 沒有叫用函數的許可，請更新函數的資源政策或提供 IAM 角色，以授予 API Gateway 叫用授權方的許可。

如果日誌指出您的 Lambda 函數傳回無效的回應，請確認 Lambda 函數傳回[所需格式](#http-api-lambda-authorizer.payload-format-response)的回應。

# 使用 API Gateway 中的 JWT 授權方來控制對 HTTP API 的存取
<a name="http-api-jwt-authorizer"></a>

您可以使用 JSON Web Tokens (JWT) 做為 [OpenID Connect (OIDC)](https://openid.net/specs/openid-connect-core-1_0.html) 和 [OAuth 2.0](https://oauth.net/2/) 框架的一部分來限制用戶端存取您的 API。

如果您為 API 的路由設定 JWT 授權方，API Gateway 會驗證用戶端使用 API 請求提交的 JWT。API Gateway 會根據字符驗證，並選擇性地根據字符中的範圍，來允許或拒絕請求。如果您設定某個路由的範圍，字符至少必須包含其中一個路由的範圍。

您可以為 API 的每個路由設定不同的授權方，或為多個路由使用相同的授權方。

**注意**  
將 JWT 存取字符與其他類型的 JWT (如 OpenID Connect ID 字符) 加以區分並無標準機制。除非您需要 API 授權的 ID 字符，否則建議您將路由設定為需要授權範圍。您也可以將 JWT 授權方設定為僅在發行 JWT 存取字符時要求身分提供者使用的發行者或對象。

## 使用 JWT 授權方來授予 API 請求權限
<a name="http-api-jwt-authorizer.evaluation"></a>

API Gateway 使用下列一般工作流程來授權請求對設定為使用 JWT 授權方的路由。

1. 檢查權杖的 [https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers-authorizerid.html#apis-apiid-authorizers-authorizerid-prop-authorizer-identitysource](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers-authorizerid.html#apis-apiid-authorizers-authorizerid-prop-authorizer-identitysource)。`identitySource` 只能包含字符，或字首加上 `Bearer` 的字符。

1. 解碼字符

1. 使用從發行者的 `jwks_uri` 獲取的公開金鑰檢查字符的演算法和簽章。目前只支援以 RSA 為基礎的演算法。API Gateway 可以快取公有金鑰兩小時。最佳作法是，當您輪換金鑰時，允許寬限期，在此期間，舊金鑰和新金鑰都有效。

1. 驗證宣告。API Gateway 會評估下列權杖宣告：
   +  [https://datatracker.ietf.org/doc/html/rfc7517#section-4.5](https://datatracker.ietf.org/doc/html/rfc7517#section-4.5) – 權杖必須有符合簽署權杖之 `jwks_uri` 中金鑰的標頭宣告。
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.1) – 必須符合為授權方設定的 [https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers-authorizerid.html#apis-apiid-authorizers-authorizerid-model-jwtconfiguration](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers-authorizerid.html#apis-apiid-authorizers-authorizerid-model-jwtconfiguration)。
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3) 或 `client_id` – 必須符合為授權方設定的其中一個 [https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers-authorizerid.html#apis-apiid-authorizers-authorizerid-model-jwtconfiguration](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers-authorizerid.html#apis-apiid-authorizers-authorizerid-model-jwtconfiguration) 項目。API Gateway 僅於 `aud` 不存在時驗證 `client_id`。當 `aud` 和 `client_id` 同時存在時，API Gateway 會評估 `aud`。
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.4) – 必須在目前時間 (以 UTC 表示) 之後。
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5) – 必須在目前時間 (以 UTC 表示) 之前。
   + [https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.6) – 必須在目前時間 (以 UTC 表示) 之前。
   + [https://datatracker.ietf.org/doc/html/rfc6749#section-3.3](https://datatracker.ietf.org/doc/html/rfc6749#section-3.3) 或 `scp` – 權杖至少必須包含路由的 [https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-routes-routeid.html#apis-apiid-routes-routeid-prop-updaterouteinput-authorizationscopes](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-routes-routeid.html#apis-apiid-routes-routeid-prop-updaterouteinput-authorizationscopes) 的其中一個範圍。

如果上述任何步驟失敗，API Gateway 會拒絕 API 請求。

驗證 JWT 後，API Gateway 會將字符中的宣告傳遞給 API 路由的整合。後端資源 (例如 Lambda 函數) 可以存取 JWT 宣告。例如，如果 JWT 包含身分宣告 `emailID`，則可在 `$event.requestContext.authorizer.jwt.claims.emailID` 中供 Lambda 整合使用。如需 API Gateway 傳送至 Lambda 整合之承載的詳細資訊，請參閱[在 APIs AWS Lambda 代理整合](http-api-develop-integrations-lambda.md)。

## 建立一個 JWT 授權器
<a name="http-api-jwt-authorizer.create"></a>

建立 JWT 授權方之前，您必須向身分提供者註冊用戶端應用程式。您還必須建立一個 HTTP API。如需建立 HTTP API 的範例，請參閱[建立 HTTP API](http-api-develop.md#http-api-examples)。

### 使用主控台建立 JWT 授權方
<a name="http-api-jwt-authorizer.create.console"></a>

下列步驟顯示如何使用主控台建立 JWT 授權方。

**使用主控台建立 JWT 授權方**

1. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 選擇一個 HTTP API。

1. 在主要導覽窗格中，選擇**授權**。

1. 選擇**管理授權方**標籤。

1. 選擇**建立**。

1. 對於**授權方類型**，選擇 **JWT**。

1. 設定您的 JWT 授權方，並指定定義字符來源的**身分來源**。

1. 選擇**建立**。

#### 使用 建立 JWT 授權方 AWS CLI
<a name="http-api-jwt-authorizer.create.cli"></a>

以下 [create-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-authorizer.html) 命令會建立 JWT 授權方。對於 `jwt-configuration`，為您的身分提供者指定 `Audience` 和 `Issuer`。如果您使用 Amazon Cognito 做為身分提供者，則 `IssuerUrl` 為 `https://cognito-idp.us-east-2.amazonaws.com/userPoolID`。

```
aws apigatewayv2 create-authorizer \
    --name authorizer-name \
    --api-id api-id \
    --authorizer-type JWT \
    --identity-source '$request.header.Authorization' \
    --jwt-configuration Audience=audience,Issuer=IssuerUrl
```

##### 使用 建立 JWT 授權方 AWS CloudFormation
<a name="http-api-jwt-cfn.create"></a>

下列 CloudFormation 範本會使用 Amazon Cognito 做為身分提供者的 JWT 授權方來建立 HTTP API。

 CloudFormation 範本的輸出是 Amazon Cognito 託管 UI 的 URL，用戶端可以在其中註冊和登入以接收 JWT。用戶端登入後，會使用 URL 中的存取字符重新導向至您的 HTTP API。若要使用存取字符調用 API，請將 URL 中的 `#` 變更為 `?`，以使用字符做為查詢字串參數。

##### 範本範例 CloudFormation
<a name="http-api-jwt-cfn-example"></a>

```
AWSTemplateFormatVersion: '2010-09-09'
Description: |
  Example HTTP API with a JWT authorizer. This template includes an Amazon Cognito user pool as the issuer for the JWT authorizer 
  and an Amazon Cognito app client as the audience for the authorizer. The outputs include a URL for an Amazon Cognito hosted UI where clients can 
  sign up and sign in to receive a JWT. After a client signs in, the client is redirected to your HTTP API with an access token 
  in the URL. To invoke the API with the access token, change the '#' in the URL to a '?' to use the token as a query string parameter.

Resources:
  MyAPI:
    Type: AWS::ApiGatewayV2::Api
    Properties: 
      Description: Example HTTP API
      Name: api-with-auth
      ProtocolType: HTTP
      Target: !GetAtt MyLambdaFunction.Arn
  DefaultRouteOverrides:
    Type: AWS::ApiGatewayV2::ApiGatewayManagedOverrides
    Properties: 
      ApiId: !Ref MyAPI
      Route: 
        AuthorizationType: JWT
        AuthorizerId: !Ref JWTAuthorizer
  JWTAuthorizer:
    Type: AWS::ApiGatewayV2::Authorizer
    Properties: 
      ApiId: !Ref MyAPI
      AuthorizerType: JWT
      IdentitySource: 
        - '$request.querystring.access_token'
      JwtConfiguration: 
        Audience: 
        - !Ref AppClient
        Issuer: !Sub https://cognito-idp.${AWS::Region}.amazonaws.com/${UserPool}
      Name: test-jwt-authorizer
  MyLambdaFunction:
    Type: AWS::Lambda::Function
    Properties:
      Runtime: nodejs18.x
      Role: !GetAtt FunctionExecutionRole.Arn
      Handler: index.handler
      Code:
        ZipFile: |
          exports.handler = async (event) => {
              const response = {
                  statusCode: 200,
                  body: JSON.stringify('Hello from the ' + event.routeKey + ' route!'),
              };
              return response;
          };
  APIInvokeLambdaPermission:
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !Ref MyLambdaFunction
      Action: lambda:InvokeFunction
      Principal: apigateway.amazonaws.com
      SourceArn: !Sub arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${MyAPI}/$default/$default
  FunctionExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17		 	 	 '
        Statement:
          - Effect: Allow
            Principal:
              Service:
              - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      ManagedPolicyArns: 
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
  UserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: http-api-user-pool
      AutoVerifiedAttributes:
        - email
      Schema:
        - Name: name
          AttributeDataType: String
          Mutable: true
          Required: true
        - Name: email
          AttributeDataType: String
          Mutable: false
          Required: true
  AppClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      AllowedOAuthFlows: 
        - implicit
      AllowedOAuthScopes: 
        - aws.cognito.signin.user.admin
        - email
        - openid
        - profile
      AllowedOAuthFlowsUserPoolClient: true
      ClientName: api-app-client
      CallbackURLs:
        - !Sub https://${MyAPI}.execute-api.${AWS::Region}.amazonaws.com
      ExplicitAuthFlows:
        - ALLOW_USER_PASSWORD_AUTH
        - ALLOW_REFRESH_TOKEN_AUTH
      UserPoolId: !Ref UserPool
      SupportedIdentityProviders:
        - COGNITO 
  HostedUI:
    Type: AWS::Cognito::UserPoolDomain
    Properties: 
      Domain: !Join
        - '-'
        - - !Ref MyAPI
          - !Ref AppClient
      UserPoolId: !Ref UserPool
Outputs:
  SignupURL:
    Value: !Sub https://${HostedUI}.auth.${AWS::Region}.amazoncognito.com/login?client_id=${AppClient}&response_type=token&scope=email+profile&redirect_uri=https://${MyAPI}.execute-api.${AWS::Region}.amazonaws.com
```

## 更新路由以使用 JWT 授權方
<a name="http-api-jwt-authorizer.create.route"></a>

您可以使用 主控台 AWS CLI、 或 AWS 開發套件來更新路由，以使用 JWT 授權方。

### 使用主控台更新路由以使用 JWT 授權方
<a name="http-api-jwt-authorizer.create.route"></a>

下列步驟顯示如何使用主控台更新路由，以使用 JWT 授權方。

**使用主控台建立 JWT 授權方**

1. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 選擇一個 HTTP API。

1. 在主要導覽窗格中，選擇**授權**。

1. 選擇一種方法，然後從下拉式選單中選取您的授權方，然後選擇**連接授權方**。

#### 使用 更新路由以使用 JWT 授權方 AWS CLI
<a name="http-api-jwt-authorizer.create.route"></a>

以下 [update-route](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-route.html) 命令會將路由更新為使用 JWT 授權方：

```
aws apigatewayv2 update-route \
   --api-id api-id  \
   --route-id route-id  \
   --authorization-type JWT \
   --authorizer-id authorizer-id \
   --authorization-scopes user.email
```

# 使用 API Gateway 中的 IAM 授權控制對 HTTP API 的存取
<a name="http-api-access-control-iam"></a>

您可以為 HTTP API 路由啟用 IAM 授權。啟用 IAM 授權時，用戶端必須使用 [Signature 第 4 版 (SigV4)](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html) 以 AWS 登入資料簽署其請求。只有在用戶端具有路由的 `execute-api` 許可時，API Gateway 才會叫用您的 API 路由。

HTTP API 的 IAM 授權與 [REST API](api-gateway-control-access-using-iam-policies-to-invoke-api.md) 的 IAM 授權類似。

**注意**  
HTTP API 目前不支援資源原則。

如需授予用戶端叫用 API 許可的 IAM 政策範例，請參閱[控制對 API 的呼叫存取權](api-gateway-control-access-using-iam-policies-to-invoke-api.md)。

## 啟用路由的 IAM 授權
<a name="http-api-access-control-iam-example"></a>

以下 [update-route](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-route.html) 命令會為 HTTP API 路由啟用 IAM 授權：

```
aws apigatewayv2 update-route \
    --api-id abc123 \
    --route-id abcdef \
    --authorization-type AWS_IAM
```

# 在 API Gateway 中建立 HTTP API 的整合
<a name="http-api-develop-integrations"></a>

「整合」**會將路由連接到後端資源。HTTP API 支援 Lambda 代理、AWS 服務和 HTTP 代理整合。例如，您可以設定 API `/signup` 路由的 `POST` 請求，以便與可處理客戶註冊的 Lambda 函數整合。

**Topics**
+ [在 APIs AWS Lambda 代理整合](http-api-develop-integrations-lambda.md)
+ [為 HTTP API 建立 HTTP 代理整合](http-api-develop-integrations-http.md)
+ [在 APIs Gateway 中建立 HTTP API AWS 的服務整合](http-api-develop-integrations-aws-services.md)
+ [在 API Gateway 中建立 HTTP API 的私有整合](http-api-develop-integrations-private.md)

# 在 APIs AWS Lambda 代理整合
<a name="http-api-develop-integrations-lambda"></a>

Lambda 代理整合可讓您將 API 路由與 Lambda 函數整合。當用戶端呼叫您的 API 時，API Gateway 會將請求傳送到該 Lambda 函數並傳回該函數的回應給用戶端。如需建立 HTTP API 的範例，請參閱[建立 HTTP API](http-api-develop.md#http-api-examples)。

## 裝載格式版本
<a name="http-api-develop-integrations-lambda.proxy-format"></a>

承載格式版本會指定 API Gateway 傳送到 Lambda 整合的事件格式，以及 API Gateway 如何解釋 Lambda 的回應。如果您未指定承載格式版本， 預設 AWS 管理主控台 會使用最新版本。如果您使用 AWS CLI CloudFormation或 SDK 建立 Lambda 整合，則必須指定 `payloadFormatVersion`。支援的值為 `1.0` 和 `2.0`。

如需有關如何設定 `payloadFormatVersion` 的詳細資訊，請參閱 [create-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration.html)。如需有關如何判斷現有整合之 `payloadFormatVersion` 的詳細資訊，請參閱 [get-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/get-integration.html)

### 承載格式差異
<a name="http-api-develop-integrations-lambda.proxy-format-differences"></a>

下列清單顯示 `1.0` 和 `2.0` 承載格式版本之間的差異：
+ 格式 `2.0` 沒有 `multiValueHeaders` 或 `multiValueQueryStringParameters` 欄位。重複的標題與逗號相結合，並包含在 `headers` 欄位中。重複的查詢字串與逗號相結合，並包含在 `queryStringParameters` 欄位中。
+ 格式 `2.0` 具有 `rawPath`。如果您使用 API 映射將您的階段連接到自訂網域名稱，`rawPath` 不會提供 API 映射值。使用格式 `1.0` 和 `path` 存取自訂網域名稱的 API 映射。
+ 格式 `2.0` 包括新的 `cookies` 欄位。請求中的所有 Cookie 標頭都與逗號相結合並新增到該 `cookies` 欄位中。在對用戶端地回應中，每個 Cookie 都會變成 `set-cookie` 標題。

### 承載格式結構
<a name="http-api-develop-integrations-lambda.proxy-format-structure"></a>

下列範例顯示每個裝載格式版本的結構。所有標頭名稱均為小寫。

------
#### [ 2.0 ]

```
{
  "version": "2.0",
  "routeKey": "$default",
  "rawPath": "/my/path",
  "rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
  "cookies": [
    "cookie1",
    "cookie2"
  ],
  "headers": {
    "header1": "value1",
    "header2": "value1,value2"
  },
  "queryStringParameters": {
    "parameter1": "value1,value2",
    "parameter2": "value"
  },
  "requestContext": {
    "accountId": "123456789012",
    "apiId": "api-id",
    "authentication": {
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "authorizer": {
      "jwt": {
        "claims": {
          "claim1": "value1",
          "claim2": "value2"
        },
        "scopes": [
          "scope1",
          "scope2"
        ]
      }
    },
    "domainName": "id.execute-api.us-east-1.amazonaws.com",
    "domainPrefix": "id",
    "http": {
      "method": "POST",
      "path": "/my/path",
      "protocol": "HTTP/1.1",
      "sourceIp": "192.0.2.1",
      "userAgent": "agent"
    },
    "requestId": "id",
    "routeKey": "$default",
    "stage": "$default",
    "time": "12/Mar/2020:19:03:58 +0000",
    "timeEpoch": 1583348638390
  },
  "body": "Hello from Lambda",
  "pathParameters": {
    "parameter1": "value1"
  },
  "isBase64Encoded": false,
  "stageVariables": {
    "stageVariable1": "value1",
    "stageVariable2": "value2"
  }
}
```

------
#### [ 1.0 ]

```
{
  "version": "1.0",
  "resource": "/my/path",
  "path": "/my/path",
  "httpMethod": "GET",
  "headers": {
    "header1": "value1",
    "header2": "value2"
  },
  "multiValueHeaders": {
    "header1": [
      "value1"
    ],
    "header2": [
      "value1",
      "value2"
    ]
  },
  "queryStringParameters": {
    "parameter1": "value1",
    "parameter2": "value"
  },
  "multiValueQueryStringParameters": {
    "parameter1": [
      "value1",
      "value2"
    ],
    "parameter2": [
      "value"
    ]
  },
  "requestContext": {
    "accountId": "123456789012",
    "apiId": "id",
    "authorizer": {
      "claims": null,
      "scopes": null
    },
    "domainName": "id.execute-api.us-east-1.amazonaws.com",
    "domainPrefix": "id",
    "extendedRequestId": "request-id",
    "httpMethod": "GET",
    "identity": {
      "accessKey": null,
      "accountId": null,
      "caller": null,
      "cognitoAuthenticationProvider": null,
      "cognitoAuthenticationType": null,
      "cognitoIdentityId": null,
      "cognitoIdentityPoolId": null,
      "principalOrgId": null,
      "sourceIp": "192.0.2.1",
      "user": null,
      "userAgent": "user-agent",
      "userArn": null,
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "path": "/my/path",
    "protocol": "HTTP/1.1",
    "requestId": "id=",
    "requestTime": "04/Mar/2020:19:15:17 +0000",
    "requestTimeEpoch": 1583349317135,
    "resourceId": null,
    "resourcePath": "/my/path",
    "stage": "$default"
  },
  "pathParameters": null,
  "stageVariables": null,
  "body": "Hello from Lambda!",
  "isBase64Encoded": false
}
```

------

## Lambda 函數回應格式
<a name="http-api-develop-integrations-lambda.response"></a>

承載格式版本會決定 Lambda 函數必須傳回的回應結構。

### 格式 1.0 的 Lambda 函數回應
<a name="http-api-develop-integrations-lambda.v1"></a>

有了 `1.0` 格式版本，Lambda 整合就必須以下列 JSON 格式傳回回應：

**Example**  

```
{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headername": "headervalue", ... },
    "multiValueHeaders": { "headername": ["headervalue", "headervalue2", ...], ... },
    "body": "..."
}
```

### 格式 2.0 的 Lambda 函數回應
<a name="http-api-develop-integrations-lambda.v2"></a>

有了 `2.0` 格式版本，API Gateway 可以為您推斷回應格式。如果您的 Lambda 函數傳回有效的 JSON 但未傳回 `statusCode`，則 API Gateway 會進行下列假設：
+ `isBase64Encoded` 是 `false`。
+ `statusCode` 是 `200`。
+ `content-type` 是 `application/json`。
+ `body` 是函數的回應。

下列範例顯示 Lambda 函數和 API Gateway 解譯的輸出。


| Lambda 函數輸出 | API Gateway 解譯 | 
| --- | --- | 
|  <pre>"Hello from Lambda!"</pre>  |  <pre>{<br />  "isBase64Encoded": false,<br />  "statusCode": 200,<br />  "body": "Hello from Lambda!",<br />  "headers": {<br />    "content-type": "application/json"<br />  }<br />}</pre>  | 
|  <pre>{ "message": "Hello from Lambda!" }</pre>  |  <pre>{<br />  "isBase64Encoded": false,<br />  "statusCode": 200,<br />  "body": "{ \"message\": \"Hello from Lambda!\" }",<br />  "headers": {<br />    "content-type": "application/json"<br />  }<br />}</pre>  | 

若要自定義回應，您的 Lambda 函數應該會傳回下列格式的回應。

```
{
    "cookies" : ["cookie1", "cookie2"],
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headername": "headervalue", ... },
    "body": "Hello from Lambda!"
}
```

# 為 HTTP API 建立 HTTP 代理整合
<a name="http-api-develop-integrations-http"></a>

HTTP 代理整合可讓您將 API 路由連線至公開可路由的 HTTP 端點。有了這種整合類型，API Gateway 會在前端和後端之間傳遞整個請求和回應。

若要建立 HTTP 代理整合，請提供公開可路由 HTTP 端點的 URL。

## HTTP 代理與路徑變數整合
<a name="http-api-develop-integrations-http-proxy"></a>

您可以在 HTTP API 路由中使用路徑變數。

例如，路由 `/pets/{petID}` 捕獲請求 `/pets/6`。您可以參考整合 URI 中的路徑變數，將變數的內容傳送至整合。例如，`/pets/extendedpath/{petID}`。

您可以使用 Greedy 路徑變量來捕獲路由的所有子資源。若要建立 Greedy 路徑變數，請將 `+` 新增至變數名稱，例如 `{proxy+}`。

若要設定包含 HTTP 代理整合以捕獲所有請求的路由，請使用 Greedy 路徑變數 (例如，`/parent/{proxy+}`) 建立 API 路由。將路由與 `ANY` 方法上的 HTTP 端點 (例如，`https://petstore-demo-endpoint.execute-api.com/petstore/{proxy}`) 整合。Greedy 路徑變數必須位於資源路徑結尾。

# 在 APIs Gateway 中建立 HTTP API AWS 的服務整合
<a name="http-api-develop-integrations-aws-services"></a>

您可以使用一級整合，將 HTTP API 與 AWS 服務整合。 **一級整合會將 HTTP API 路由連接到 AWS 服務 API。當用戶端叫用由一級整合支援的路由時，API Gateway 會為您叫用 AWS 服務 API。例如，您可以使用一級整合將訊息傳送至 Amazon Simple Queue Service 佇列，或啟動 AWS Step Functions 狀態機器。如需支援的服務動作，請參閱[整合子類型參照](http-api-develop-integrations-aws-services-reference.md)。

## 映射請求參數
<a name="http-api-develop-integrations-aws-services-parameter-mapping"></a>

一級整合具有必要和選用的參數。您必須設定所有必要的參數，才能建立整合。您可以使用在執行階段動態評估的靜態值或映射參數。如需支援整合與參數的完整清單，請參閱[整合子類型參照](http-api-develop-integrations-aws-services-reference.md)。

下表說明受支援的映射請求參數。


| Type | 範例 | 備註 | 
| --- | --- | --- | 
| 標頭值 | \$1request.header.name | 網域名稱需區分大小寫。API Gateway 會將多個標頭值與逗號結合起來，例如 "header1": "value1,value2"。 | 
| 查詢字串值 | \$1request.querystring.name | 查詢字串名稱區分大小寫。API Gateway 會將多個值與逗號結合起來，例如 "querystring1": "Value1,Value2"。 | 
| 路徑參數 | \$1request.path.name | 請求中的路徑參數值。例如，如果路由是 /pets/\$1petId\$1，您可以透過 \$1request.path.petId 從請求映射 petId 參數。 | 
| 請求內文傳遞 | \$1request.body | API Gateway 會傳遞整個請求內文。 | 
| 請求內文 | \$1request.body.name | [JSON 路徑表達式](https://goessner.net/articles/JsonPath/index.html#e2)。不支援遞迴下降 (\$1request.body..name) 和篩選表達式 (?(expression))。 當您指定 JSON 路徑時，API Gateway 會在 100 KB 時截斷請求主體，然後套用選擇表達式。若要傳送大於 100 KB 的承載，請指定 `$request.body`。  | 
| 環境變數 | \$1context.variableName | 支援的[內容變數](http-api-logging-variables.md)值。 | 
| 階段變數 | \$1stageVariables.variableName | [階段變數](http-api-stages.stage-variables.md)的值。 | 
| 靜態值 | string | 常數值。 | 

## 建立一級整合
<a name="http-api-develop-integrations-aws-services-example"></a>

建立一級整合之前，您必須建立授予 API Gateway 許可的 IAM 角色，以叫用您要整合 AWS 的服務動作。如需進一步了解，請參閱[為 AWS 服務建立角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html)。

若要建立一級整合，請選擇支援的 AWS 服務動作，例如 `SQS-SendMessage`、設定請求參數，並提供授予 API Gateway 呼叫整合 AWS 服務 API 許可的角色。根據整合子類型，需要不同的請求參數。如需進一步了解，請參閱[整合子類型參照](http-api-develop-integrations-aws-services-reference.md)。

以下 [create-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration.html) 命令會建立可傳送 Amazon SQS 訊息的整合：

```
aws apigatewayv2 create-integration \
    --api-id abcdef123 \
    --integration-subtype SQS-SendMessage \
    --integration-type AWS_PROXY \
    --payload-format-version 1.0 \
    --credentials-arn arn:aws:iam::123456789012:role/apigateway-sqs \
    --request-parameters '{"QueueUrl": "$request.header.queueUrl", "MessageBody": "$request.body.message"}'
```

## 使用 建立一級整合 CloudFormation
<a name="http-api-develop-integrations-aws-services-example-cfn"></a>

下列範例顯示 程式碼片段，該程式碼片段會建立與 CloudFormation Amazon EventBridge 進行一級整合的`/{source}/{detailType}`路由。

`Source` 參數會對應至 `{source}` 路徑參數、`DetailType` 對應至 `{DetailType}` 路徑參數，且 `Detail` 參數會對應至要求主體。

程式碼片段不會顯示授與 API Gateway 許可來調用 `PutEvents` 動作的事件匯流排或 IAM 角色。

```
Route:
    Type: AWS::ApiGatewayV2::Route
    Properties:
      ApiId: !Ref HttpApi
      AuthorizationType: None
      RouteKey: 'POST /{source}/{detailType}'
      Target: !Join 
        - /
        - - integrations
          - !Ref Integration
  Integration:
    Type: AWS::ApiGatewayV2::Integration
    Properties:
      ApiId: !Ref HttpApi
      IntegrationType: AWS_PROXY
      IntegrationSubtype: EventBridge-PutEvents
      CredentialsArn: !GetAtt EventBridgeRole.Arn
      RequestParameters:
        Source: $request.path.source
        DetailType: $request.path.detailType
        Detail: $request.body
        EventBusName: !GetAtt EventBus.Arn
      PayloadFormatVersion: "1.0"
```

# 整合子類型參照
<a name="http-api-develop-integrations-aws-services-reference"></a>

HTTP API 支援下列[整合子類型](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid.html#apis-apiid-integrations-integrationid-prop-integration-integrationsubtype)。

**Topics**
+ [EventBridge-PutEvents 1.0](#EventBridge-PutEvents)
+ [SQS-SendMessage 1.0](#SQS-SendMessage)
+ [SQS-ReceiveMessage 1.0](#SQS-ReceiveMessage)
+ [SQS-DeleteMessage 1.0](#SQS-DeleteMessage)
+ [SQS-PurgeQueue 1.0](#SQS-PurgeQueue)
+ [AppConfig-GetConfiguration 1.0](#AppConfig-GetConfiguration)
+ [Kinesis-PutRecord 1.0](#Kinesis-PutRecord)
+ [StepFunctions-StartExecution 1.0](#StepFunctions-StartExecution)
+ [StepFunctions-StartSyncExecution 1.0](#StepFunctions-StartSyncExecution)
+ [StepFunctions-StopExecution 1.0](#StepFunctions-StopExecution)

## EventBridge-PutEvents 1.0
<a name="EventBridge-PutEvents"></a>

將自訂事件傳送到 Amazon EventBridge 以將這些事件與規則比對。


| 參數 | 必要 | 
| --- | --- | 
| Detail | True | 
| DetailType | True | 
| Source | True | 
| Time | False | 
| EventBusName | False | 
| Resources | False | 
| Region | False | 
| TraceHeader | False | 

若要進一步了解，請參閱《Amazon EventBridge API 參考》**中的 [PutEvents](https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutEvents.html)。

## SQS-SendMessage 1.0
<a name="SQS-SendMessage"></a>

將訊息傳遞到指定的佇列。


| 參數 | 必要 | 
| --- | --- | 
| QueueUrl | True | 
| MessageBody | True | 
| DelaySeconds | False | 
| MessageAttributes | False | 
| MessageDeduplicationId | False | 
| MessageGroupId | False | 
| MessageSystemAttributes | False | 
| Region | False | 

若要進一步了解，請參閱《Amazon Simple Queue Service API 參考》**中的 [SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)。

## SQS-ReceiveMessage 1.0
<a name="SQS-ReceiveMessage"></a>

您從指定的佇列擷取一個或多個訊息 (最多可達 10 個)。


| 參數 | 必要 | 
| --- | --- | 
| QueueUrl | True | 
| AttributeNames | False | 
| MaxNumberOfMessages | False | 
| MessageAttributeNames | False | 
| ReceiveRequestAttemptId | False | 
| VisibilityTimeout | False | 
| WaitTimeSeconds | False | 
| Region | False | 

若要進一步了解，請參閱《Amazon Simple Queue Service API 參考》**中的 [ReceiveMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html)。

## SQS-DeleteMessage 1.0
<a name="SQS-DeleteMessage"></a>

從指定的佇列刪除指定的訊息。


| 參數 | 必要 | 
| --- | --- | 
| ReceiptHandle | True | 
| QueueUrl | True | 
| Region | False | 

若要進一步了解，請參閱《Amazon Simple Queue Service API 參考》**中的 [DeleteMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_DeleteMessage.html)。

## SQS-PurgeQueue 1.0
<a name="SQS-PurgeQueue"></a>

刪除指定佇列中的所有訊息。


| 參數 | 必要 | 
| --- | --- | 
| QueueUrl | True | 
| Region | False | 

若要進一步了解，請參閱《Amazon Simple Queue Service API 參考》**中的 [PurgeQueue](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_PurgeQueue.html)。

## AppConfig-GetConfiguration 1.0
<a name="AppConfig-GetConfiguration"></a>

接收組態的相關資訊。


| 參數 | 必要 | 
| --- | --- | 
| Application | True | 
| Environment | True | 
| Configuration | True | 
| ClientId | True | 
| ClientConfigurationVersion | False | 
| Region | False | 

如需進一步了解，請參閱《AWS AppConfig API 參考》**中的 [GetConfiguration](https://docs.aws.amazon.com/appconfig/2019-10-09/APIReference/API_GetConfiguration.html)。

## Kinesis-PutRecord 1.0
<a name="Kinesis-PutRecord"></a>

將單一資料記錄寫入 Amazon Kinesis 資料串流。


| 參數 | 必要 | 
| --- | --- | 
| StreamName | True | 
| Data | True | 
| PartitionKey | True | 
| SequenceNumberForOrdering | False | 
| ExplicitHashKey | False | 
| Region | False | 

若要進一步了解，請參閱《Amazon Kinesis Data Streams API 參考》**中的 [PutRecord](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecord.html)。

## StepFunctions-StartExecution 1.0
<a name="StepFunctions-StartExecution"></a>

啟動狀態機器的執行。


| 參數 | 必要 | 
| --- | --- | 
| StateMachineArn | True | 
| Name | False | 
| Input | False | 
| Region | False | 

如需進一步了解，請參閱《AWS Step Functions API 參考》**中的 [StartExecution](https://docs.aws.amazon.com/step-functions/latest/apireference/API_StartExecution.html)。

## StepFunctions-StartSyncExecution 1.0
<a name="StepFunctions-StartSyncExecution"></a>

啟動同步狀態機器執行。


| 參數 | 必要 | 
| --- | --- | 
| StateMachineArn | True | 
| Name | False | 
| Input | False | 
| Region | False | 
| TraceHeader | False | 

如需進一步了解，請參閱《AWS Step Functions API 參考》**中的 [StartSyncExecution](https://docs.aws.amazon.com/step-functions/latest/apireference/API_StartSyncExecution.html)。

## StepFunctions-StopExecution 1.0
<a name="StepFunctions-StopExecution"></a>

停止執行。


| 參數 | 必要 | 
| --- | --- | 
| ExecutionArn | True | 
| Cause | False | 
| Error | False | 
| Region | False | 

如需進一步了解，請參閱《AWS Step Functions API 參考》**中的 [StopExecution](https://docs.aws.amazon.com/step-functions/latest/apireference/API_StopExecution.html)。

# 在 API Gateway 中建立 HTTP API 的私有整合
<a name="http-api-develop-integrations-private"></a>

私有整合可讓您在 VPC 中建立具有私有資源的 API 整合，例如 Application Load Balancer 或 Amazon ECS 容器型應用程式。

您可以使用私有整合來公開 VPC 中的資源，供 VPC 以外的用戶端存取。您可以使用 API Gateway 支援的任何[授權方法](http-api-access-control.md)來控制對您的 API 的存取。

**注意**  
若要建立私有整合，您必須先建立 VPC 連結。HTTP 和 REST APIs 現在都支援 VPC 連結 V2。若要進一步了解 VPC 連結 V2，請參閱 [在 API Gateway 中設定 VPC 連結 V2](apigateway-vpc-links-v2.md)。

建立 VPC 連結 V2 之後，您可以設定連線至 Application Load Balancer、Network Load Balancer 或向 AWS Cloud Map 服務註冊的資源的私有整合。

## 考量事項
<a name="http-api-develop-integrations-private-considerations"></a>

下列考量事項可能會影響您使用私有整合：
+ 所有資源都必須由相同的 擁有 AWS 帳戶。這包括負載平衡器 AWS Cloud Map 或服務、VPC 連結和 HTTP API。
+ 依預設，私有整合流量會使用 HTTP 通訊協定。若要使用 HTTPS，請指定 [https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid.html](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-integrations-integrationid.html)。若要使用 執行此操作 AWS 管理主控台，當您建立私有整合時，請選擇**進階設定**，然後輸入安全伺服器名稱。
+ 對於私有整合，API Gateway 會在對後端資源的請求中包含 API 端點的[階段](http-api-stages.md)部分。例如，對 API `test` 階段的請求會包含 `test/route-path` 在私人整合的請求中。若要移除從請求至後端資源的階段名稱，請使用[參數映射](http-api-parameter-mapping.md)將請求路徑覆寫為 `$request.path`。

## 使用 Application Load Balancer 或 Network Load Balancer 建立私有整合
<a name="http-api-develop-integrations-private-ELB"></a>

建立私有整合之前，您必須建立 VPC 連結 V2。若要進一步了解 VPC 連結 V2，請參閱 [在 API Gateway 中設定 VPC 連結 V2](apigateway-vpc-links-v2.md)。

若要使用 Application Load Balancer 或 Network Load Balancer 建立私有整合，請建立 HTTP 代理整合、指定要使用的 VPC 連結，以及提供負載平衡器的接聽程式 ARN。

以下 [create-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration.html) 命令會建立私有整合，以使用 VPC 連結連線至負載平衡器：

```
aws apigatewayv2 create-integration --api-id api-id --integration-type HTTP_PROXY \
    --integration-method GET --connection-type VPC_LINK \
    --connection-id VPC-link-ID \
    --integration-uri arn:aws:elasticloadbalancing:us-east-2:123456789012:listener/app/my-load-balancer/50dc6c495c0c9188/0467ef3c8400ae65
    --payload-format-version 1.0
```

## 使用 AWS Cloud Map 服務探索建立私有整合
<a name="http-api-develop-integrations-private-Cloud-Map"></a>

建立私有整合之前，您必須建立 VPC 連結 V2。若要深入了解 VPC 連結，請參閱[在 API Gateway 中設定 VPC 連結 V2](apigateway-vpc-links-v2.md)。

對於與 的整合 AWS Cloud Map，API Gateway 會使用 `DiscoverInstances` 來識別資源。您可以使用查詢參數來鎖定特定資源。已註冊資源的屬性必須包含 IP 位址和連接埠。API Gateway 會將請求分散於 `DiscoverInstances` 傳回的狀態良好資源。若要進一步了解，請參閱 AWS Cloud Map API 參考中的 [DiscoverInstances](https://docs.aws.amazon.com/cloud-map/latest/api/API_DiscoverInstances.html)。

**注意**  
如果您使用 Amazon ECS 在 中填入項目 AWS Cloud Map，則必須將 Amazon ECS 任務設定為搭配 Amazon ECS Service Discovery 使用 SRV 記錄，或開啟 Amazon ECS Service Connect。如需詳細資訊，請參閱《Amazon Elastic Container Service 開發人員指南》中的[服務探索](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/interconnecting-services.html)。

若要與 建立私有整合 AWS Cloud Map，請建立 HTTP 代理整合、指定要使用的 VPC 連結，並提供 AWS Cloud Map 服務的 ARN。

下列 [create-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration.html) 命令會建立使用 AWS Cloud Map 服務探索來識別資源的私有整合：

```
aws apigatewayv2 create-integration --api-id api-id --integration-type HTTP_PROXY  \
    --integration-method GET --connection-type VPC_LINK \
    --connection-id VPC-link-ID \
    --integration-uri arn:aws:servicediscovery:us-east-2:123456789012:service/srv-id?stage=prod&deployment=green_deployment
    --payload-format-version 1.0
```

# 在 API Gateway 中設定 HTTP API 的 CORS
<a name="http-api-cors"></a>

[跨來源資源共享 (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) 是一種瀏覽器安全功能，限制從瀏覽器中執行之指令碼啟動的跨來源 HTTP 請求。如果您無法存取 API 並收到包含 `Cross-Origin Request Blocked` 的錯誤訊息，您可能需要啟用 CORS。如需詳細資訊，請參閱[什麼是 CORS？](https://aws.amazon.com/what-is/cross-origin-resource-sharing/)。

建立 Web 應用程式來存取託管在不同網域或來源上的 API，通常需要 CORS。您可以啟用 CORS 以允許來自不同網域上託管的 Web 應用程式對 API 的請求。例如，如果您的 API 託管在 `https://{api_id}.execute-api.{region}.amazonaws.com/` 上，並且您想要從 `example.com` 上託管的 Web 應用程式呼叫 API，則您的 API 必須支援 CORS。

如果您為 API 設定 CORS，即使沒有為您的 API 設定 OPTIONS 路由，API Gateway 也會自動傳送回應給預檢 OPTIONS 請求。對於 CORS 請求，API Gateway 會將設定的 CORS 標頭加入至整合的回應。

**注意**  
如果您為 API 設定 CORS，則 API Gateway 會忽略從後端整合傳回的 CORS 標頭。

您可以在 CORS 組態中指定下列參數。若要使用 API Gateway HTTP API 主控台新增這些參數，請在輸入值之後選擇**新增**。


| CORS 標頭 | CORS 組態屬性 | 範例值 | 
| --- | --- | --- | 
|  Access-Control-Allow-Origin  |  allowOrigins  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/http-api-cors.html)  | 
|  Access-Control-Allow-Credentials  |  allowCredentials  |  true  | 
|  Access-Control-Expose-Headers  |  exposeHeaders  |  date、x-api-id、\$1  | 
|  Access-Control-Max-Age  |  maxAge  |  300  | 
|  Access-Control-Allow-Methods  |  allowMethods  |  GET、POST、DELETE、\$1  | 
|  Access-Control-Allow-Headers  |  allowHeaders  |  authorization、\$1  | 

若要傳回 CORS 標頭，您的請求必須包含 `origin` 標頭。對於 `OPTIONS` 方法，您的請求必須包含 `origin` 標頭和 `Access-Control-Request-Method` 標頭。

您的 CORS 組態可能看起來如下：

![\[設定 HTTP API 的 CORS 組態\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/http-cors-console.png)


## 為具有 `$default` 路由和授權方的 HTTP API 設定 CORS
<a name="http-api-cors-default-route"></a>

您可以啟用 CORS 並設定任何 HTTP API 的任何路由授權。當您為 [`$default` 路由](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-routes.html#http-api-develop-routes.default) 啟用 CORS 和授權時，有些特殊事項需要考量。`$default` 路由會擷取您未明確定義之所有方法和路由的請求，包括 `OPTIONS` 請求。為了支援未授權的 `OPTIONS` 請求，請將 `OPTIONS /{proxy+}` 路由新增到您不需要授權的 API，並將整合連接到路由。該 `OPTIONS /{proxy+}` 路由具有比 `$default` 路由更高的優先順序。因此，它會允許用戶端在未經授權的情況下向您的 API 提交 `OPTIONS` 請求。如需有關路由傳送優先順序的詳細資訊，請參閱[路由傳送 API 請求](http-api-develop-routes.md#http-api-develop-routes.evaluation)。

## 使用 CLI 設定 HTTP API AWS 的 CORS
<a name="http-api-cors.example"></a>

以下 [update-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-api.html) 命令會啟用來自 `https://www.example.com` 的 CORS 請求：

**Example**  

```
aws apigatewayv2 update-api --api-id api-id --cors-configuration AllowOrigins="https://www.example.com"
```

如需詳細資訊，請參閱《Amazon API Gateway 第 2 版 API 參考》中的 [CORS](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid.html#apis-apiid-model-cors)。

# 在 API Gateway 中轉換 HTTP API 的 API 請求和回應
<a name="http-api-parameter-mapping"></a>

您可以在用戶端到達後端整合之前修改 API 請求。您也可以在 API Gateway 將回應傳回給用戶端之前，變更來自整合變的回應。您可以使用*參數映射*，來修改 HTTP API 的 API 請求和回應。若要使用參數映射，請指定要修改的 API 請求或回應參數，並指定如何修改這些參數。



## 轉換 API 請求
<a name="http-api-mapping-request-parameters"></a>

您可以使用請求參數，在請求到達後端整合之前變更請求。您可以修改標頭、查詢字串或請求路徑。

請求參數為金鑰-值映射。金鑰可確定要變更的請求參數的位置，以及變更方式。該值指定參數的新資料。

下表顯示支援的金鑰。


| Type | 語法 | 
| --- | --- | 
| 標頭 | append\$1overwrite\$1remove:header.headername | 
| 查詢字串 | append\$1overwrite\$1remove:querystring.querystring-name | 
| 路徑 | overwrite:path | 

下表顯示可映射至參數的支援值。


| Type | 語法 | 備註 | 
| --- | --- | --- | 
| 標頭值 | \$1request.header.name 或 \$1\$1request.header.name\$1 | 網域名稱需區分大小寫。API Gateway 會將多個標頭值與逗號結合起來，例如 "header1": "value1,value2"。有些標頭為預留。如需進一步了解，請參閱 [預留的標頭](#http-api-mapping-reserved-headers)。 | 
| 查詢字串值 | \$1request.querystring.name 或 \$1\$1request.querystring.name\$1 | 查詢字串名稱區分大小寫。API Gateway 會將多個值與逗號結合起來，例如 "querystring1" "Value1,Value2"。 | 
| 請求內文 | \$1request.body.name 或 \$1\$1request.body.name\$1 | JSON 路徑表達式。不支援遞迴下降 (\$1request.body..name)) 和篩選表達式 (?(expression))。 當您指定 JSON 路徑時，API Gateway 會在 100 KB 時截斷請求主體，然後套用選擇表達式。若要傳送大於 100 KB 的承載，請指定 `$request.body`。  | 
| 請求路徑。 | \$1request.path 或 \$1\$1request.path\$1 | 請求路徑，不含階段名稱。 | 
| 路徑參數 | \$1request.path.name 或 \$1\$1request.path.name\$1 | 請求中的路徑參數值。例如，如果路由是 /pets/\$1petId\$1，您可以透過 \$1request.path.petId 從請求映射 petId 參數。 | 
| 環境變數 | \$1context.variableName 或 \$1\$1context.variableName\$1 | [內容變數](http-api-logging-variables.md)的值。僅支援特殊字元 `.` 和 `_`。 | 
| 階段變數 | \$1stageVariables.variableName 或 \$1\$1stageVariables.variableName\$1 | [階段變數](http-api-stages.stage-variables.md)的值。 | 
| 靜態值 | string | 常數值。 | 

**注意**  
要在選擇表達式中使用多個變數，請將變數括在括號內。例如 `${request.path.name} ${request.path.id}`。

## 轉換 API 回應
<a name="http-api-mapping-response-parameters"></a>

您可以使用回應參數，在將回應傳回給用戶端之前，從後端整合轉換 HTTP 回應。您可以在 API Gateway 將回應傳回給用戶端之前，修改標題或回應的狀態碼。

您可以為整合傳回的每個狀態碼設定回應參數。回應參數為金鑰-值映射。金鑰可確定要變更的請求參數的位置，以及變更方式。該值指定參數的新資料。

下表顯示支援的金鑰。


| Type | 語法 | 
| --- | --- | 
| 標頭 | append\$1overwrite\$1remove:header.headername | 
| 狀態碼 | overwrite:statuscode | 

下表顯示可映射至參數的支援值。


| Type | 語法 | 備註 | 
| --- | --- | --- | 
| 標頭值 | \$1response.header.name 或 \$1\$1response.header.name\$1 | 網域名稱需區分大小寫。API Gateway 會將多個標頭值與逗號結合起來，例如 "header1": "value1,value2"。有些標頭為預留。如需進一步了解，請參閱 [預留的標頭](#http-api-mapping-reserved-headers)。 | 
| 回應內文 | \$1response.body.name 或 \$1\$1response.body.name\$1 | JSON 路徑表達式。不支援遞迴下降 (\$1response.body..name) 和篩選表達式 (?(expression))。 當您指定 JSON 路徑時，API Gateway 會在 100 KB 時截斷回應主體，然後套用選擇表達式。若要傳送大於 100 KB 的承載，請指定 `$response.body`。  | 
| 環境變數 | \$1context.variableName 或 \$1\$1context.variableName\$1 | 支援的[內容變數](http-api-logging-variables.md)值。 | 
| 階段變數 | \$1stageVariables.variableName 或 \$1\$1stageVariables.variableName\$1 | [階段變數](http-api-stages.stage-variables.md)的值。 | 
| 靜態值 | string | 常數值。 | 

**注意**  
要在選擇表達式中使用多個變數，請將變數括在括號內。例如 `${request.path.name} ${request.path.id}`。

## 預留的標頭
<a name="http-api-mapping-reserved-headers"></a>

以下標題為預留。您無法設定這些標頭的請求或回應映射。
+ access-control-\$1
+ apigw-\$1
+ Authorization
+ Connection
+ Content-Encoding
+ Content-Length
+ Content-Location
+ Forwarded
+ Keep-Alive
+ Origin
+ Proxy-Authenticate
+ Proxy-Authorization
+ TE
+ Trailers 
+ Transfer-Encoding
+ Upgrade
+ x-amz-\$1
+ x-amzn-\$1
+ X-Forwarded-For
+ X-Forwarded-Host
+ X-Forwarded-Proto
+ Via

## 範例
<a name="http-api-parameter-mapping-examples"></a>

下列 AWS CLI 範例會設定參數映射。如需 CloudFormation 範本範例，請參閱 [GitHub](https://github.com/awsdocs/amazon-api-gateway-developer-guide/tree/main/cloudformation-templates)。

### 將標頭新增至 API 請求
<a name="http-api-parameter-mapping-examples-request-header"></a>

以下 [create-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration.html) 命令會在 API 請求到達您的後端整合之前，為其建立名為 `header1` 的標頭。API Gateway 會填充請求 ID 的標頭。

```
aws apigatewayv2 create-integration \
    --api-id abcdef123 \
    --integration-type HTTP_PROXY \
    --payload-format-version 1.0 \
    --integration-uri 'https://api.example.com' \
    --integration-method ANY \
    --request-parameters '{ "append:header.header1": "$context.requestId" }'
```

### 重新命名請求標頭
<a name="http-api-parameter-mapping-examples-response"></a>

以下 [create-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration.html) 命令會將請求標頭從 `header1` 重新命名 `header2`：

```
aws apigatewayv2 create-integration \
    --api-id abcdef123 \
    --integration-type HTTP_PROXY \
    --payload-format-version 1.0 \
    --integration-uri 'https://api.example.com' \
    --integration-method ANY \
    --request-parameters '{ "append:header.header2": "$request.header.header1",  "remove:header.header1": "''"}'
```

### 變更整合的回應
<a name="http-api-parameter-mapping-examples-response"></a>

以下 [create-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration.html) 命令會設定整合的回應參數。若整合傳回 500 狀態碼，API Gateway 會將狀態碼變更為 403，並在回應中新增 `header1`1。若整合傳回 404 狀態碼時，API Gateway 會將 `error` 標頭新增至回應。

```
aws apigatewayv2 create-integration \
    --api-id abcdef123 \
    --integration-type HTTP_PROXY \
    --payload-format-version 1.0 \
    --integration-uri 'https://api.example.com' \
    --integration-method ANY \
    --response-parameters '{"500" : {"append:header.header1": "$context.requestId", "overwrite:statuscode" : "403"}, "404" : {"append:header.error" : "$stageVariables.environmentId"}  }'
```

### 移除已設定的參數映射
<a name="http-api-parameter-mapping-examples-remove"></a>

以下 [update-integration](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-integration.html) 命令會移除先前為 `append:header.header1` 設定的請求參數。還會移除 200 狀態碼之前設定的回應參數。

```
aws apigatewayv2 update-integration \
    --api-id abcdef123 \
    --integration-id hijk456 \
    --request-parameters '{"append:header.header1" : ""}' \
    --response-parameters '{"200" : {}}'
```

# 在 API Gateway 中使用 HTTP API 的 OpenAPI 定義
<a name="http-api-open-api"></a>

您可以使用 OpenAPI 3.0 定義檔來定義 HTTP API。之後，您就能將定義匯入 API Gateway，以建立 API。若要進一步了解 OpenAPI 的 API Gateway 延伸，請參閱[API Gateway 的 OpenAPI 擴充功能](api-gateway-swagger-extensions.md)。

## 匯入 HTTP API
<a name="http-api-import"></a>

您可以透過匯入 OpenAPI 3.0 定義檔案來建立 HTTP API。

若要從 REST API 遷移至 HTTP API，您可以將 REST API 匯出為 OpenAPI 3.0 定義檔案。然後將 API 定義匯入為 HTTP API。若要進一步了解如何匯出 REST API，請參閱[從 API Gateway 匯出 REST API](api-gateway-export-api.md)。

**注意**  
HTTP APIs支援與 REST APIs相同的 AWS 變數。如需進一步了解，請參閱[AWS OpenAPI 匯入的 變數](import-api-aws-variables.md)。

### 匯入驗證資訊
<a name="http-api-import.validation"></a>

匯入 API 時，API Gateway 會提供三種類別的驗證資訊。

**Info**  
根據 OpenAPI 規格，屬性有效，但該屬性不支援 HTTP API。  
例如，下列 OpenAPI 3.0 程式碼片段會產生匯入資訊，因為 HTTP API 不支援請求驗證。API Gateway 會忽略 `requestBody` 和 `schema` 欄位。  

```
"paths": {
  "/": {
    "get": {
      "x-amazon-apigateway-integration": {
        "type": "AWS_PROXY",
        "httpMethod": "POST",
        "uri": "arn:aws:lambda:us-east-2:123456789012:function:HelloWorld",
        "payloadFormatVersion": "1.0"
      },
      "requestBody": {
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Body"
            }
          }
        }
      }
    }
  }
  ...
},
"components": {
  "schemas": {
    "Body": {
      "type": "object",
      "properties": {
        "key": {
          "type": "string"
        }
      }
    }
    ...
  }
  ...
}
```

**警告**  
根據 OpenAPI 規範，屬性或結構無效，但它不會封鎖 API 建立。您可以指定 API Gateway 是否應忽略這些警告並繼續建立 API，或在警告時停止建立 API。  
下列 OpenAPI 3.0 文件會在匯入時產生警告，因為 HTTP API 僅支援 Lambda 代理和 HTTP 代理整合。  

```
"x-amazon-apigateway-integration": {
  "type": "AWS",
  "httpMethod": "POST",
  "uri": "arn:aws:lambda:us-east-2:123456789012:function:HelloWorld",
  "payloadFormatVersion": "1.0"
}
```

**錯誤**  
OpenAPI 規格無效或格式錯誤。API Gateway 無法從格式錯誤的文件建立任何資源。您必須修正錯誤，然後再試一次。  
下列 API 會定義在匯入時產生錯誤，因為 HTTP API 僅支援 OpenAPI 3.0 規格。  

```
{
  "swagger": "2.0.0",
  "info": {
    "title": "My API",
    "description": "An Example OpenAPI definition for Errors/Warnings/ImportInfo",
    "version": "1.0"
  }
  ...
}
```
作為另一個範例，雖然 OpenAPI 允許使用者定義可將多個安全性需求附加至特定操作的 API，但 API Gateway 不支援該操作。每項作業只能有一個 IAM 授權、Lambda 授權方或 JWT 授權方。嘗試建立多個安全性需求的模型會導致錯誤。

### 使用 匯入 API AWS CLI
<a name="http-api-import.example"></a>

以下 [import-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/import-api.html) 命令會將 OpenAPI 3.0 定義檔 `api-definition.json` 匯入為 HTTP API：

**Example**  

```
aws apigatewayv2 import-api --body file://api-definition.json
```

**Example**  
您可以匯入下列範例 OpenAPI 3.0 定義來建立 HTTP API。  

```
{
  "openapi": "3.0.1",
  "info": {
    "title": "Example Pet Store",
    "description": "A Pet Store API.",
    "version": "1.0"
  },
  "paths": {
    "/pets": {
      "get": {
        "operationId": "GET HTTP",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Pets"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "HTTP_PROXY",
          "httpMethod": "GET",
          "uri": "http://petstore.execute-api.us-west-1.amazonaws.com/petstore/pets",
          "payloadFormatVersion": 1.0
        }
      },
      "post": {
        "operationId": "Create Pet",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NewPet"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "200 response",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NewPetResponse"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "type": "HTTP_PROXY",
          "httpMethod": "POST",
          "uri": "http://petstore.execute-api.us-west-1.amazonaws.com/petstore/pets",
          "payloadFormatVersion": 1.0
        }
      }
    },
    "/pets/{petId}": {
      "get": {
        "operationId": "Get Pet",
        "parameters": [
          {
            "name": "petId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Pet"
                }
              }
            }
          }
        },        
        "x-amazon-apigateway-integration": {
          "type": "HTTP_PROXY",
          "httpMethod": "GET",
          "uri": "http://petstore.execute-api.us-west-1.amazonaws.com/petstore/pets/{petId}",
          "payloadFormatVersion": 1.0
        }
      }
    }
  },
  "x-amazon-apigateway-cors": {
    "allowOrigins": [
      "*"
    ],
    "allowMethods": [
      "GET",
      "OPTIONS",
      "POST"
    ],
    "allowHeaders": [
      "x-amzm-header",
      "x-apigateway-header",
      "x-api-key",
      "authorization",
      "x-amz-date",
      "content-type"
    ]
  },
  "components": {
    "schemas": {
      "Pets": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/Pet"
        }
      },
      "Empty": {
        "type": "object"
      },
      "NewPetResponse": {
        "type": "object",
        "properties": {
          "pet": {
            "$ref": "#/components/schemas/Pet"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "Pet": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "price": {
            "type": "number"
          }
        }
      },
      "NewPet": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/PetType"
          },
          "price": {
            "type": "number"
          }
        }
      },
      "PetType": {
        "type": "string",
        "enum": [
          "dog",
          "cat",
          "fish",
          "bird",
          "gecko"
        ]
      }
    }
  }
}
```

# 從 APIs Gateway 匯出 HTTP API
<a name="http-api-export"></a>

建立 HTTP API 之後，您可以從 API Gateway 匯出您的 API 的 OpenAPI 3.0 定義。您可以選擇要匯出的階段，也可以匯出 API 的最新組態。您也可以將匯出的 API 定義匯入到 API Gateway，以建立另一個相同的 API。若要進一步了解如何匯入 API 定義，請參閱[匯入 HTTP API](http-api-open-api.md#http-api-import)。

## 使用 CLI 匯出階段的 OpenAPI 3.0 AWS 定義
<a name="http-api-export.stage.example"></a>

以下 [export-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/export-api.html) 命令會將名為 `prod` 的 API 階段的 OpenAPI 定義，匯出至名為 `stage-definition.yaml` 的 YAML 檔案。匯出的定義檔案預設會包含 [API Gateway 延伸](api-gateway-swagger-extensions.md)。

```
aws apigatewayv2 export-api \
    --api-id api-id  \
    --output-type YAML  \
    --specification OAS30 \
    --stage-name prod \
    stage-definition.yaml
```

## 使用 CLI 匯出 API 最新變更的 OpenAPI 3.0 AWS 定義
<a name="http-api-export.latest.example"></a>

以下 [export-api](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/export-api.html) 命令會將 HTTP API 的 OpenAPI 定義匯出至名為 `latest-api-definition.json` 的 JSON 檔案。由於命令未指定階段，因此無論 API 是否已部署至階段，API Gateway 都會匯出 API 的最新組態。匯出的定義檔案不會包含 [API Gateway 延伸](api-gateway-swagger-extensions.md)。

```
aws apigatewayv2 export-api \
    --api-id api-id  \
    --output-type JSON  \
    --specification OAS30 \
    --no-include-extensions \
    latest-api-definition.json
```

如需詳細資訊，請參閱《Amazon API Gateway 第 2 版 API 參考》**中的 [ExportAPI](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-exports-specification.html#apis-apiid-exports-specification-http-methods)。

## 使用 API Gateway 主控台匯出 OpenAPI 3.0 定義
<a name="http-api-export.console"></a>

下列程序說明如何匯出 HTTP API 的 OpenAPI 定義。

**若要使用 API Gateway 主控台匯出 OpenAPI 3.0 定義**

1. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 選擇一個 HTTP API。

1. 在主導覽窗格的**開發**底下，選擇**匯出**。

1. 從下方選取匯出 API 的選項：  
![\[適用於 HTTP API 的匯出選項。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/export-http-api.png)

   1. 針對**來源**，選取 OpenAPI 3.0 定義的來源。您可以選擇要匯出的階段，也可以匯出 API 的最新組態。

   1. 開啟**包含 API Gateway 延伸模組**以包含 [API Gateway 延伸模組](api-gateway-swagger-extensions.md)。

   1. 針對**輸出格式**，選取輸出格式。

1. 選擇 **Download** (下載)。

# 發布 HTTP API 以供客戶調用
<a name="http-api-publish"></a>

您可以使用階段和自訂網域名稱來發布 API，以供用戶端呼叫。

API 階段是 API 生命週期狀態的邏輯參考 (例如，`dev`、`prod`、`beta` 或 `v2`)。每個階段都是 API 部署的具名參考，且可供用戶端應用程式呼叫。您可以為 API 的每個階段設定不同的整合和設定。

您可以使用自訂網域名稱來提供更簡單、更直覺的 URL，讓用戶端呼叫您的 API，而非預設的 URL `https://api-id.execute-api.region.amazonaws.com/stage`。

**注意**  
為了增強 API Gateway API 的安全性，`execute-api.{region}.amazonaws.com` 網域會在[公用尾碼清單 (PSL](https://publicsuffix.org/)) 中註冊。為了加強安全性，如果您需要在 API Gateway API 的預設網域名稱中設定敏感性 Cookie，我們建議您使用具 `__Host-` 前置詞的 Cookie。此做法將有助於保護您的網域免受跨站請求偽造 (CSRF) 攻擊。如需更多資訊，請參閱 Mozilla 開發人員網路中的[設定 Cookie](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#cookie_prefixes) 頁面。

**Topics**
+ [API Gateway 中 HTTP API 的階段](http-api-stages.md)
+ [API Gateway 中 HTTP API 的安全政策](http-api-ciphers.md)
+ [API Gateway 中 HTTP API 的自訂網域名稱](http-api-custom-domain-names.md)

# API Gateway 中 HTTP API 的階段
<a name="http-api-stages"></a>

API 階段是 API 生命週期狀態的邏輯參考 (例如，`dev`、`prod`、`beta` 或 `v2`)。API 階段是由其 API ID 及階段名稱來識別，而且它們會包含在您用來呼叫 API 的 URL 中。每個階段都是 API 部署的具名參考，且可供用戶端應用程式呼叫。

您可以建立從 API URL 基礎提供的 `$default` 階段，例如 `https://{api_id}.execute-api.{region}.amazonaws.com/`。您可以使用此 URL 來呼叫 API 階段。

部署是 API 組態的快照。將 API 部署到階段之後，用戶端就可以叫用它。您必須部署 API 才能讓變更生效。如果您啟用自動部署，則會自動為您發行 API 的變更。

# 在 API Gateway 中使用 HTTP API 的階段變數
<a name="http-api-stages.stage-variables"></a>

階段變數是您可為 HTTP API 定義階段的索引鍵/值對。它們的作用如同環境變數，而且可用於 API 設定。

階段變數並非用於敏感資料，例如登入資料。若要將敏感資料傳遞至整合，請使用 AWS Lambda 授權方。您可以將敏感資料傳遞至 Lambda 授權方輸出中的整合。如需進一步了解，請參閱[Lambda 授權方回應格式](http-api-lambda-authorizer.md#http-api-lambda-authorizer.payload-format-response)。

## 範例 – 使用階段變數自訂 HTTP 整合端點
<a name="http-api-stages.stage-variables-examples"></a>

例如，您可以定義階段變數，然後將其值設定為 HTTP Proxy 整合的 HTTP 端點。稍後，您可以使用相關聯的階段變數名稱來參照端點。如此，您可以在每個階段使用不同的端點來使用相同的 API 設定。同樣地，您可以使用階段變數，為 API 的每個階段指定不同的 AWS Lambda 函數整合。

若要使用階段變數來自訂 HTTP 整合端點，您必須先將階段變數 (例如，`url`) 的名稱和值設定為 `example.com`。之後，設定 HTTP 代理整合。您可以告訴 API Gateway 使用階段變數值 **http://\$1\$1stageVariables.url\$1**，而不需要輸入端點的 URL。此值會指示 API Gateway 在執行時間替換您的階段變數 `${}`，視您 API 的階段而定。

您可以使用類似的方式來參考階段變數，以指定 Lambda 函數名稱或 AWS 角色 ARN。

將 Lambda 函數名稱指定為階段變數值時，您必須在 Lambda 函數中手動設定許可。以下 [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) 命令會設定 Lambda 函式的許可：

```
aws lambda add-permission --function-name arn:aws:lambda:XXXXXX:your-lambda-function-name --source-arn arn:aws:execute-api:us-east-1:YOUR_ACCOUNT_ID:api_id/*/HTTP_METHOD/resource --principal apigateway.amazonaws.com --statement-id apigateway-access --action lambda:InvokeFunction
```

# API Gateway 中適用於 HTTP API 的 API Gateway 階段變數參考
<a name="http-api-stages.stage-variables-reference"></a>

在下列情況下，您可以針對 HTTP API 使用 API Gateway 階段變數。

## HTTP 整合 URI
<a name="http-api-stages.stage-variables-in-integration-HTTP-uris"></a>

您可以使用階段變數作為 HTTP 整合 URI 的一部分，如下例範例所示。
+ 不含通訊協定的完整 URI – `http://${stageVariables.<variable_name>}`
+ 完整的網域 – `http://${stageVariables.<variable_name>}/resource/operation`
+ 子網域 – `http://${stageVariables.<variable_name>}.example.com/resource/operation`
+ 路徑 – `http://example.com/${stageVariables.<variable_name>}/bar`
+ 查詢字串 – `http://example.com/foo?q=${stageVariables.<variable_name>}` 

## Lambda 函式
<a name="http-api-stages.stage-variables-in-integration-lambda-functions"></a>

 您可以使用階段變數取代 Lambda 函數整合名稱或別名，如下列範例所示。
+ `arn:aws:apigateway:<region>:lambda:path/2015-03-31/functions/arn:aws:lambda:<region>:<account_id>:function:${stageVariables.<function_variable_name>}/invocations`
+ `arn:aws:apigateway:<region>:lambda:path/2015-03-31/functions/arn:aws:lambda:<region>:<account_id>:function:<function_name>:${stageVariables.<version_variable_name>}/invocations`

**注意**  
若要使用 Lambda 函數的階段變數，函數必須與 API 位於相同的帳戶中。階段變數不支援跨帳戶 Lambda 函數。

## AWS 整合憑證
<a name="http-api-stages.stage-variables-in-integration-aws-credentials"></a>

 您可以使用階段變數做為 AWS 使用者或角色登入資料 ARN 的一部分，如下列範例所示。
+  `arn:aws:iam::<account_id>:${stageVariables.<variable_name>}` 

# API Gateway 中 HTTP API 的安全政策
<a name="http-api-ciphers"></a>

API Gateway 會針對所有 HTTP API 端點強制執行 `TLS_1_2` 的安全政策。

*安全政策*是由 Amazon API Gateway 提供的最低 TLS 版本與密碼套件的預先定義組合。TLS 通訊協定可解決用戶端和伺服器間的竄改與竊聽等網路安全問題。當用戶端透過自訂網域建立 API 的 TLS 信號交換時，安全政策會強制執行用戶端可選擇使用的 TLS 版本和密碼套件。此安全政策接受 TLS 1.2 和 TLS 1.3 流量，並拒絕 TLS 1.0 流量。

## HTTP API 支援的 TLS 通訊協定和密碼
<a name="http-api-ciphers-list"></a>

下表說明 HTTP API 支援的 TLS 通訊協定。


| **TLS 通訊協定** | **TLS\$11\$12 安全政策** | 
| --- | --- | 
| TLSv1.3 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| TLSv1.2 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 

下表說明適用於 HTTP API 的 TLS 1\$12 安全政策的 TLS 加密。


| **TLS 加密** | **TLS\$11\$12 安全政策** | 
| --- | --- | 
| TLS-AES-128-GCM-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| TLS-AES-256-GCM-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| TLS-CHACHA20-POLY1305-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| ECDHE-ECDSA-AES128-GCM-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| ECDHE-RSA-AES128-GCM-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| ECDHE-ECDSA-AES128-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| ECDHE-RSA-AES128-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| ECDHE-ECDSA-AES256-GCM-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| ECDHE-RSA-AES256-GCM-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| ECDHE-ECDSA-AES256-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| ECDHE-RSA-AES256-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| AES128-GCM-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| AES128-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| AES256-GCM-SHA384 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 
| AES256-SHA256 | ![\[alt text not found\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/success_icon.svg) 是 | 

## OpenSSL 和 RFC 密碼名稱
<a name="apigateway-secure-connections-openssl-rfc-cipher-names-http"></a>

OpenSSL 和 IETF RFC 5246 使用相同密碼的不同名稱。如需密碼名稱的清單，請參閱 [OpenSSL 和 RFC 密碼名稱](apigateway-security-policies-list.md#apigateway-secure-connections-openssl-rfc-cipher-names)。

## REST API 和 WebSocket API 的相關資訊
<a name="apigateway-http-additional-apis"></a>

如需 REST API 和 WebSocket API 的詳細資訊，請參閱 [在 API Gateway 中為您的自訂網域選擇安全政策](apigateway-custom-domain-tls-version.md) 和 [API Gateway 中適用於 WebSocket API 的安全政策](websocket-api-ciphers.md)。

# API Gateway 中 HTTP API 的自訂網域名稱
<a name="http-api-custom-domain-names"></a>

*自訂網域名稱*是更簡單且更直觀的 URL，可提供給 API 使用者。

部署 API 之後，您 (和您的客戶) 可以使用下列格式的預設基本 URL 來呼叫 API：

```
https://api-id.execute-api.region.amazonaws.com/stage
```

其中 *api-id* 是 API Gateway 所產生，*region* 即為 (AWS 區域)，而 *stage* 是您在部署 API 時所指定。

URL 的主機名稱部分 (即 `api-id.execute-api.region.amazonaws.com`) 指的是 API 端點。預設 API 端點是隨機產生的，不容易取回，而且不方便使用。

使用自訂網域名稱，您就能設定 API 的主機名稱，並選擇基本路徑 (例如，`myservice`) 將替代 URL 映射至您的 API。例如，更方便使用者使用的 API 基本 URL 可以成為：

```
https://api.example.com/myservice
```

## 考量事項
<a name="http-api-custom-domain-name-considerations"></a>

下列考量事項可能會影響您使用自訂網域名稱。
+ 區域性自訂網域名稱可與 REST API 和 HTTP API 相關聯。您可以使用 API Gateway 第 2 版 API 來建立及管理 REST API 的區域性自訂網域名稱。
+ 對於最低 TLS 版本，僅 TLS 1.2 受支援。
+ 您必須建立或更新 DNS 提供者的資源記錄，以映射至您的 API 端點。如果沒有這種映射，送往自訂網域名稱的 API 請求無法到達 API Gateway。
+ 您可以使用萬用字元憑證來支援幾乎不限數量的網域名稱，而不會超過預設配額。如需更多詳細資訊，請參閱 [萬用字元自訂網域名稱](#http-wildcard-custom-domain-names)。

## 先決條件
<a name="http-api-custom-domain-names-prerequisites"></a>

以下是建立自訂網域名稱的先決條件。

### 註冊網域名稱
<a name="http-api-custom-domain-names-register"></a>

您必須具有已註冊的網際網路網域名稱，才能為您的 API 設定自訂網域名稱。您可以使用 [Amazon Route 53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/) 或使用您選擇的第三方網域註冊機構來註冊網際網路網域。您的自訂網域名稱可以是已註冊網際網路網域的子網域或根網域 (也稱為 "zone apex") 的名稱。

您的網域名稱必須遵循 [RFC 1035](https://tools.ietf.org/html/rfc1035#section-2.3.4) 規格，每個標籤最多可有 63 個八位元組，總共有 255 個八位元組。

### 自訂網域名稱的憑證
<a name="http-api-custom-domain-names-certificates"></a>

必須為 API 設定自訂網域名稱前，您必須先在 ACM 中備妥 SSL/TLS 憑證。如果您建立自訂網域名稱的 AWS 區域中無法使用 ACM，則必須將憑證匯入該區域中的 API Gateway。

若要匯入 SSL/TLS 憑證，您必須提供 PEM 格式化 SSL/TLS 憑證內文、私有金鑰，以及自訂網域名稱的憑證鏈。

ACM 中所存放的每個憑證都是透過其 ARN 進行識別。使用 ACM 所發出的憑證，就不需要擔心公開任何敏感的憑證詳細資訊，例如私有金鑰。若要使用網域名稱的 AWS 受管憑證，您只需要參考其 ARN。

如果您的應用程式是使用憑證關聯 (有時稱為 SSL 關聯) 來關聯 ACM 憑證，則 AWS 續約憑證後，應用程式可能會無法連線到您的網域。如需詳細資訊，請參閱 *AWS Certificate Manager 使用者指南*中的[憑證關聯問題](https://docs.aws.amazon.com/acm/latest/userguide/troubleshooting-pinning.html)。

## 萬用字元自訂網域名稱
<a name="http-wildcard-custom-domain-names"></a>

使用萬用字元自訂網域名稱，您可以支援幾乎無限數目的網域名稱，而不會超過[預設配額](limits.md)。例如，您可以為每個客戶提供其自己的網域名稱，`customername.api.example.com`。

若要建立萬用字元自訂網域名稱，可以指定萬用字元 (`*`) 作為自訂網域的第一個子網域，藉以表示根網域所有可能的子網域。

例如，萬用字元自訂網域名稱 `*.example.com` 會產生如 `a.example.com`、`b.example.com` 和 `c.example.com` 等子網域，而這些子網域全都路由至相同的網域。

萬用字元自訂網域名稱支援來自 API Gateway 標準自訂網域名稱的相異組態。例如，您可以在單一 AWS 帳戶中，設定 `*.example.com` 和 `a.example.com` 採取不同的行為。

若要建立萬用字元自訂網域名稱，您必須提供由 ACM 發行並已經使用 DNS 或電子郵件驗證方法驗證的憑證。

**注意**  
如果不同的 AWS 帳戶已建立與萬用字元自訂網域名稱衝突的自訂網域名稱，則您無法建立萬用字元自訂網域名稱。例如，如果帳戶 A 已建立 `a.example.com`，則帳戶 B 無法建立萬用字元自訂網域名稱 `*.example.com`。  
如果帳戶 A 和帳戶 B 共用擁有者，您可以聯絡 [AWS 支援中心](https://console.aws.amazon.com/support/home#/)，以請求例外狀況。

## 自訂網域名稱的後續步驟
<a name="http-api-custom-domain-names-next-steps"></a>

若要設定 HTTP API 的自訂網域名稱，請參閱《API Gateway 開發人員指南》中的 REST API 相關章節文件。

首先，指定自訂網域名稱所用的憑證。如需更多詳細資訊，請參閱 [在 中備妥憑證 AWS Certificate Manager](how-to-specify-certificate-for-custom-domain-name.md)。接著，建立區域性自訂網域名稱。如需更多詳細資訊，請參閱 [在 API Gateway 中設定區域性自訂網域名稱](apigateway-regional-api-custom-domain-create.md)。

# 將 API 階段映射至 HTTP API 的自訂網域名稱
<a name="http-api-mappings"></a>

您可以使用 API 映射將 API 階段連線至自訂網域名稱。建立網域名稱並設定 DNS 記錄之後，您可以使用 API 映射，透過自訂網域名稱將流量傳送至您的 API。

API 映射指定一個 API，一個階段，以及選擇性用於映射的路徑。例如，您可以將 API 的 `production` 階段映射至 `https://api.example.com/orders`。

您可以將 HTTP 和 REST API 階段映射至相同的自訂網域名稱。

建立 API 映射之前，您必須先擁有 API、階段和自訂網域名稱。如需進一步了解如何建立自訂網域名稱，請參閱[在 API Gateway 中設定區域性自訂網域名稱](apigateway-regional-api-custom-domain-create.md)。

## 路由傳送 API 請求
<a name="http-api-mappings-evalutation"></a>

您可以設定具有多個層級的 API 映射，例如 `orders/v1/items` 和 `orders/v2/items`。

針對有多個層級的 API 映射，API Gateway 會將請求路由傳送至具有最長相符路徑的 API 映射。API Gateway 只會考慮為 API 映射而非 API 路由設定的路徑，以選取要調用的 API。如果沒有路徑與請求相符，則 API Gateway 會將請求傳送到您映射到空白路徑 `(none)` 的 API。

針對使用有多個層級的 API 映射的自訂網域名稱，API Gateway 會將請求路由傳送至具有最長相符字首的 API 映射。

例如，假設具有下列 API 映射的自訂網域名稱 `https://api.example.com`：

1. `(none)` 已映射到 API 1。

1. `orders` 已映射到 API 2。

1. `orders/v1/items` 已映射到 API 3。

1. `orders/v2/items` 已映射到 API 4。

1. `orders/v2/items/categories` 已映射到 API 5。


| 要求 | 選取的 API | 說明 | 
| --- | --- | --- | 
|  `https://api.example.com/orders`  |  `API 2`  |  請求完全符合此 API 映射。  | 
|  `https://api.example.com/orders/v1/items`  |  `API 3`  |  請求完全符合此 API 映射。  | 
|  `https://api.example.com/orders/v2/items`  |  `API 4`  |  請求完全符合此 API 映射。  | 
|  `https://api.example.com/orders/v1/items/123`  |  `API 3`  |  API Gateway 會選擇具有最長相符路徑的映射。請求結束時的 `123` 不會影響選擇。  | 
|  `https://api.example.com/orders/v2/items/categories/5`  |  `API 5`  |  API Gateway 會選擇具有最長相符路徑的映射。  | 
|  `https://api.example.com/customers`  |  `API 1`  |  API Gateway 使用空白映射作為全部擷取。  | 
|  `https://api.example.com/ordersandmore`  |  `API 2`  |  API Gateway 會選擇具有最長相符字首的映射。 針對設定使用單一層級映射的自訂網域名稱，例如只有 `https://api.example.com/orders` 和 `https://api.example.com/`，API Gateway 會選擇 `API 1`，因為沒有與 `ordersandmore` 相符的路徑。  | 

## 限制
<a name="http-api-mappings-restrictions"></a>
+ 在 API 映射中，自訂網域名稱和映射的 API 必須位於同一個 AWS 帳戶中。
+ API 映射只能包含字母、數字和下列字元：`$-_.+!*'()/`。
+ API 映射中路徑的最大長度為 300 個字元。
+ 您可以為每個域名設定具有 200 個具多個層級的 API 映射。此限制不包括具有單一層級的 API 映射，例如 `/prod`。
+ 您只能將 HTTP API 映射至具有 TLS 1.2 安全政策的區域自訂網域名稱。
+ 您無法將 WebSocket API 映射至與 HTTP API 或 REST API 相同的自訂網域名稱。
+ 如果您建立具有多層的 API 映射，API Gateway 會將所有標頭名稱轉換為小寫。

## 建立 API 映射
<a name="http-api-mappings-examples"></a>

若要建立 API 映射，您必須先建立自訂網域名稱、API 和階段。如需建立自訂網域名稱的資訊，請參閱[在 API Gateway 中設定區域性自訂網域名稱](apigateway-regional-api-custom-domain-create.md)。

有關建立所有資源的 AWS Serverless Application Model 範本範例，請參閱 GitHub 上的[使用 SAM 的工作階段](https://github.com/aws-samples/sessions-with-aws-sam/tree/master/custom-domains)。

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

**建立 API 映射**

1. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 選擇 **Custom domain names** (自訂網域名稱)。

1. 選取您已建立的自訂網域名稱。

1. 選擇 **API mappings** (API 映射)。

1. 選擇 **Configure API mappings (設定 API 映射)**。

1. 選擇 **Add new mapping (新增映射)**。

1. 輸入 **API**、**Stage** (階段)，以及選擇性地輸入 **Path** (路徑)。

1. 選擇**儲存**。

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

以下 [create-api-mapping](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-api.html) 命令會建立 API 映射。在此範例中，API Gateway 會將請求傳送至 `api.example.com/v1/orders`，到指定的 API 和階段。

```
aws apigatewayv2 create-api-mapping \
    --domain-name api.example.com \
    --api-mapping-key v1/orders \
    --api-id a1b2c3d4 \
    --stage test
```

------
#### [ CloudFormation ]

以下 CloudFormation 範例會建立 API 映射。

```
MyApiMapping:
  Type: 'AWS::ApiGatewayV2::ApiMapping'
  Properties:
    DomainName: api.example.com
    ApiMappingKey: 'orders/v2/items'
    ApiId: !Ref MyApi
    Stage: !Ref MyStage
```

------

# 停用 HTTP API 的預設端點
<a name="http-api-disable-default-endpoint"></a>

預設情況下，用戶端可以使用 API Gateway 為 API 產生的 `execute-api` 端點來調用 API。若要確保用戶端只能使用自訂網域名稱來存取您的 API，請停用預設 `execute-api` 端點。當您停用預設端點時，它會影響 API 的所有階段。

下列程序顯示如何停用 HTTP API 的預設端點。

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

1. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 選擇一個 HTTP API。

1. 選擇 API 的 ID 以開啟 **API 詳細資訊**頁面。

1. 在 **API 詳細資訊**上，選擇**編輯**。

1. 對於**預設端點**，選取**停用**。

1. 選擇**儲存**。

   如果您為階段開啟自動部署，則不需要為了讓變更生效而重新部署 API。否則，您必須重新部署 API。

1. (選用) 選擇**部署**，然後重新部署您的 API 或建立新的階段，以使變更生效。

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

以下 [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-domain-name.html) 命令會停用 HTTP API 的預設端點：

```
aws apigatewayv2 update-api \
    --api-id abcdef123 \
    --disable-execute-api-endpoint
```

停用預設端點後，您必須部署 API 才能讓變更生效，除非已啟用自動部署。

下列 [create-deployment](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-deployment.html) 命令會建立部署：

```
aws apigatewayv2 create-deployment \
    --api-id abcdef123 \
    --stage-name dev
```

------

# HTTP API 自訂網域名稱的 IP 位址類型
<a name="http-api-custom-domain-names-ip-address-type"></a>

建立 API 時，您可以指定可調用網域的 IP 位址類型。您可以選擇 IPv4 來解析 IPv4 位址以調用網域，也可以選擇雙堆疊，以同時允許 IPv4 和 IPv6 位址調用您的網域。我們建議您將 IP 位址類型設定為雙堆疊，以緩解 IP 空間耗盡或用於安全狀態。如需雙堆疊 IP 位址類型優點的詳細資訊，請參閱 [AWS 上的 IPv6](https://docs.aws.amazon.com/whitepapers/latest/ipv6-on-aws/internet-protocol-version-6.html)。

## IP 位址類型的考量事項
<a name="http-ip-address-type-considerations"></a>

下列考量事項可能會影響您使用 IP 位址類型。
+ API Gateway 自訂網域名稱的預設 IP 位址類型為 IPv4。
+ 您的自訂網域名稱不需要針對所有與其對應的 API 使用相同 IP 位址類型。如果您停用預設 API 端點，則可能會影響呼叫方調用 API 的方式。

## 變更自訂網域名稱的 IP 位址類型
<a name="http-api-custom-domain-names-ip-address-type-change"></a>

您可以藉由更新網域的端點組態來變更 IP 位址類型。您可以使用 AWS 管理主控台、AWS CLI、CloudFormation 或 AWS SDK 來更新網域的端點組態。

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

**若要變更自訂網域名稱的 IP 位址類型**

1. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 選擇公有自訂網域名稱。

1. 選擇**端點組態**。

1. 針對 IP 位址類型，選取 **IPv4** 或**雙堆疊**。

1. 選擇**儲存**。

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

以下 [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-domain-name.html) 命令會將 API 更新為雙堆疊 IP 位址類型：

```
aws apigatewayv2 update-domain-name \
   --domain-name dualstack.example.com \
   --domain-name-configurations CertificateArn=arn:aws:acm:us-east-1:111122223333:certificate/abcd1234-5678-abc,IpAddressType=dualstack
```

輸出將如下所示：

```
{
    "ApiMappingSelectionExpression": "$request.basepath",
    "DomainName": "dualstack.example.com",
    "DomainNameConfigurations": [
        {
            "ApiGatewayDomainName": "d-abcd1234.execute-api.us-east-1.amazonaws.com",
            "CertificateArn": "arn:aws:acm:us-east-1:111122223333:certificate/abcd1234-5678-abc",
            "DomainNameStatus": "AVAILABLE",
            "EndpointType": "REGIONAL",
            "HostedZoneId": "Z3LQWSYCGH4ADY",
            "SecurityPolicy": "TLS_1_2",
            "IpAddressType": "dualstack"
        }
    ],
    "Tags": {}
}
```

------

# 在 API Gateway 中保護您的 HTTP API
<a name="http-api-protect"></a>

API Gateway 提供多種方法來保護 API 免於遭受特定威脅，例如惡意使用者或流量高峰。您可以使用設定調節目標和啟用交互 TLS 等策略來保護您的 API。您可以在本節中了解如何使用 API Gateway 啟用這些功能。

**Topics**
+ [調節對 HTTP API 的請求，以提高 API Gateway 中的輸送量](http-api-throttling.md)
+ [如何在 API Gateway 中為 HTTP API 開啟交互 TLS 驗證](http-api-mutual-tls.md)

# 調節對 HTTP API 的請求，以提高 API Gateway 中的輸送量
<a name="http-api-throttling"></a>

您可以為您的 API 設定調節，以防止 API 接收過多請求。調節會依最佳作法來套用，它們都應該視為目標，而非確定的請求上限。

API Gateway 會使用字符儲存貯體演算法將字符計算為請求，進而調節傳送給 API 的請求量。具體而言，API Gateway 會按區域檢查帳戶中所有 API 的速率和爆量請求次數。在字符儲存貯體演算法中，爆量可以實現預先定義的超限，但在某些情況下，其他因素也可能導致超限。

提交的請求量超出穩定狀態請求率和爆量限制時，API Gateway 會開始調節請求量。此時用戶端可能會收到 `429 Too Many Requests` 的錯誤回應。發現這類例外狀況時，用戶端可以採用限制速率的方式來重新提交失敗的請求。

身為 API 開發人員，您可以設定個別 API 階段或路由的目標限制，來改善您帳戶中所有 API 的整體效能。

## 每個區域的帳戶層級調節
<a name="http-api-protect-throttling-account"></a>

預設情況下，API Gateway 會按區域限制 AWS 帳戶內所有 API 的每秒穩定狀態請求量 (RPS)。它還會按區域限制 AWS 帳戶內所有 API 的爆量 (即儲存貯體大小上限)。在 API Gateway 中，爆量限制代表 API Gateway 傳回 `429 Too Many Requests` 錯誤回應前可實現的並行請求提交數上限。如需有關調節配額的詳細資訊，請參閱 [Amazon API Gateway 配額](limits.md)。

帳戶型限制會套用至指定區域內某帳戶的所有 API。帳戶層級速率限制可按請求提高。使用較短逾時值和較小酬載的 API 可擁有更高的上限。如需請求提高區域內帳戶層級的調節限制，請與 [AWS 支援中心](https://console.aws.amazon.com/support/home#/)聯絡。如需詳細資訊，請參閱[Amazon API Gateway 配額](limits.md)。請注意，這些限制不能高於限 AWS 流限制。

## 路由層級調節
<a name="http-api-protect-throttling-route"></a>

您可以設定路由層級調節，來覆寫特定階段或 API 中個別路由的帳戶層級請求調節限制。預設路由調節限制不能超出帳戶層級速率限制。

您可以使用 AWS CLI設定路由層級的節流設定。以下 [update-stage](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-stage.html) 命令會針對指定的 API 階段和路由設定自訂限流：

```
aws apigatewayv2 update-stage \
    --api-id a1b2c3d4 \
    --stage-name dev \
    --route-settings '{"GET /pets":{"ThrottlingBurstLimit":100,"ThrottlingRateLimit":2000}}'
```

# 如何在 API Gateway 中為 HTTP API 開啟交互 TLS 驗證
<a name="http-api-mutual-tls"></a>

交互 TLS 驗證需要用戶端與伺服器之間的雙向驗證。使用交互 TLS 時，用戶端必須出示 X.509 憑證，以驗證其身分才能存取您的 API。交互 TLS 是物聯網 (IoT) 和企業對企業應用程式的常見需求。

交互 TLS 可與 API Gateway 支援的其他[授權和身分驗證作業](apigateway-control-access-to-api.md)一起使用。API Gateway 會將用戶端提供的憑證轉送給 Lambda 授權方和後端整合系統。

**重要**  
預設情況下，用戶端可以使用 API Gateway 為 API 產生的 `execute-api` 端點來叫用 API。若要確保用戶端只能透過使用具有交互 TLS 的自訂網域名稱來存取您的 API，請停用預設 `execute-api` 端點。如需進一步了解，請參閱[停用 HTTP API 的預設端點](http-api-disable-default-endpoint.md)。

## 交互 TLS 的先決條件
<a name="http-api-mutual-tls-prerequisites"></a>

若要設定交互 TLS，您需要：
+ 自訂網域名稱
+ 在 中 AWS Certificate Manager 為您的自訂網域名稱設定至少一個憑證
+ 已設定並上傳至 Amazon S3 的信任庫

### 自訂網域名稱
<a name="http-api-mutual-tls-custom-domain-name"></a>

 若要啟用 HTTP API 的交互 TLS，必須設定 API 的自訂網域名稱。您可以為自訂網域名稱啟用交互 TLS，然後將自訂網域名稱提供給用戶端。若要使用已啟用交互 TLS 的自訂網域名稱來存取 API，用戶端必須提供您在 API 要求中信任的憑證。您可以在 [API Gateway 中 HTTP API 的自訂網域名稱](http-api-custom-domain-names.md) 中尋找詳細資訊。

### 使用 AWS Certificate Manager 發行的憑證
<a name="http-api-mutual-tls-using-acm-issued-certs"></a>

您可以直接從 ACM 請求公開信任的憑證，或匯入公開或自行簽署的憑證。若要在 ACM 中設定憑證，請前往 [ACM](https://console.aws.amazon.com/acm/)。如果想要匯入憑證，請繼續閱讀下一節。

### 使用匯入的 或 AWS 私有憑證授權單位 憑證
<a name="http-api-mutual-tls-non-acm-certs"></a>

若要使用匯入 ACM 的憑證或從 的憑證 AWS 私有憑證授權單位 搭配交互 TLS，API Gateway 需要 ACM `ownershipVerificationCertificate`發行的 。此擁有權憑證僅用於確認您具有使用網域名稱的許可，不會用於 TLS 信號交換。如果您尚未擁有 `ownershipVerificationCertificate`，請前往 [https://console.aws.amazon.com/acm/](https://console.aws.amazon.com/acm/) 以設定一個。

您需要讓此憑證在網域名稱的有效生命週期內保持有效狀態。如果憑證過期且自動續約失敗，則網域名稱的所有更新都會遭到鎖定。您需要使用有效的 `ownershipVerificationCertificate` 更新 `ownershipVerificationCertificateArn`，才能進行任何其他變更。所以，`ownershipVerificationCertificate` 不可作為 API Gateway 中另一個交互 TLS 網域的伺服器憑證。如果直接將憑證重新匯入至 ACM，發行者必須保持不變。

### 設定您的信任庫
<a name="http-api-mutual-tls-create-trust-store"></a>

信任庫是副檔名為 `.pem` 的文字檔案。它們是來自憑證授權機構的受信任憑證清單。若要使用交互 TLS，請建立信任的 X.509 憑證信任存放區，以存取您的 API。

您必須在信任庫中包含從發行的憑證授權機構憑證到根憑證授權機構憑證完整的信任鏈。API Gateway 接受信任鏈中存在的任何憑證授權機構所發行的用戶端憑證。憑證可以來自公開或私有憑證授權單位。憑證的鏈接長度上限為四。您也可以提供自我簽署憑證。信任庫支援下列雜湊演算法：
+ SHA-256 或更強的憑證
+ RSA-2048 或更強的憑證
+ ECDSA-256 或更強的憑證

API Gateway 會驗證許多憑證屬性。當用戶端叫用 API 時，您可以透過 Lambda 授權方執行其他檢查，包括檢查憑證是否已遭撤銷。如此一來，API Gateway 就會驗證下列屬性：


| 驗證 | 描述 | 
| --- | --- | 
|  X.509 語法  |  憑證必須符合 X.509 語法需求。  | 
|  完整性  |  憑證的內容不得從信任庫的憑證授權單位所簽署的內容進行變更。  | 
|  Validity  |  憑證的有效期必須是最新的。  | 
|  名稱鏈接/金鑰鏈接  |  憑證的名稱和主體必須形成一個完整的鏈接。憑證的鏈接長度上限為四。  | 

### 請將信任庫以單一檔案的形式上傳到 Amazon S3 儲存貯體中
<a name="w2aac19c17b9b9c13"></a>

**Example certificates.pem**  

```
-----BEGIN CERTIFICATE-----
<Certificate contents>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<Certificate contents>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<Certificate contents>
-----END CERTIFICATE-----
...
```

下列 [cp](https://docs.aws.amazon.com/cli/latest/reference/s3/cp.html) AWS CLI 命令`certificates.pem`會上傳至您的 Amazon S3 儲存貯體：

```
aws s3 cp certificates.pem s3://bucket-name
```

## 設定自訂網域名稱的交互 TLS
<a name="http-api-mutual-tls-configure"></a>

若要設定 HTTP API 的交互 TLS，您必須使用 API 的區域性自訂網域名稱，且要求的最低 TLS 版本為 1.2。如需深入瞭解如何建立和設定自訂網域名稱，請參閱[在 API Gateway 中設定區域性自訂網域名稱](apigateway-regional-api-custom-domain-create.md)。

**注意**  
私有 API 不支援交互 TLS。

將信任庫上傳到 Amazon S3 後，您可以將自訂網域名稱設定為使用交互 TLS。以下 [create-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-domain-name.html) 命令會建立具有交互 TLS 的自訂網域名稱：

```
aws apigatewayv2 create-domain-name \
    --domain-name api.example.com \
    --domain-name-configurations CertificateArn=arn:aws:acm:us-west-2:123456789012:certificate/123456789012-1234-1234-1234-12345678 \
    --mutual-tls-authentication TruststoreUri=s3://bucket-name/key-name
```

建立網域名稱之後，您必須設定 API 作業的 DNS 記錄和基本路徑對應。如需進一步了解，請參閱[在 API Gateway 中設定區域性自訂網域名稱](apigateway-regional-api-custom-domain-create.md)。

## 使用需要交互 TLS 的自訂網域名稱叫用 API
<a name="http-api-mutual-tls-invoke"></a>

若要調用啟用交互 TLS 的 API，用戶端必須在 API 要求中提供受信任的憑證。當用戶端嘗試叫用您的 API 時，API Gateway 會在您的信任庫中尋找用戶端憑證的發行者。若要讓 API Gateway 繼續執行要求，憑證發行者和完整信任鏈 (一路深入到根憑證授權機構憑證) 必須位於您的信任庫中。

下列範例 `curl` 命令會將要求傳送至 `api.example.com,` 要求 `my-cert.pem` 中包含的要求。`my-key.key` 是憑證的私密金鑰。

```
curl -v --key ./my-key.key --cert ./my-cert.pem api.example.com
```

只有在您的信任庫信任憑證時，才會調用您的 API。下列情況會導致 API Gateway 的 TLS 信號交換失敗，並拒絕狀態碼為 `403` 的請求。如果您的憑證：
+ 不受信任
+ 已過期
+ 未使用支援的演算法

**注意**  
API Gateway 並不會驗證憑證是否已遭撤銷。

## 更新您的信任庫
<a name="http-api-mutual-tls-update-truststore"></a>

若要更新信任庫中的憑證，請將新的憑證套件上傳至 Amazon S3。之後，您可以更新自訂網域名稱，以使用更新的憑證。

您可以使用 [Amazon S3 版本控制](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html)來維護多個信任庫版本。在更新自訂網域名稱以使用新的信任庫版本時，如果憑證無效，則 API Gateway 會傳回警告。

API Gateway 只會在您更新網域名稱時產生憑證警告。如果先前上傳的憑證過期，API Gateway 並不會通知您。

以下 [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-domain-name.html) 命令會更新自訂網域名稱，以使用新的信任庫版本：

```
aws apigatewayv2 update-domain-name \
    --domain-name api.example.com \
    --domain-name-configurations CertificateArn=arn:aws:acm:us-west-2:123456789012:certificate/123456789012-1234-1234-1234-12345678 \
    --mutual-tls-authentication TruststoreVersion='abcdef123'
```

## 停用交互 TLS
<a name="http-api-mutual-tls-disable"></a>

若要停用自訂網域名稱的交互 TLS，請從自訂網域名稱移除信任庫，如下列命令所示。

以下 [update-domain-name](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-domain-name.html) 命令會更新自訂網域名稱，以從您的自訂網域名稱中移除信任庫：

```
aws apigatewayv2 update-domain-name \
    --domain-name api.example.com \
    --domain-name-configurations CertificateArn=arn:aws:acm:us-west-2:123456789012:certificate/123456789012-1234-1234-1234-12345678 \
    --mutual-tls-authentication TruststoreUri=''
```

## 針對 HTTP API 的交互 TLS 進行疑難排解
<a name="http-api-mutual-tls-troubleshooting"></a>

以下針對當您開啟交互 TLS 時可能遇到錯誤和問題，所提供的疑難排解建言。

### 故障診斷憑證警告
<a name="http-api-mutual-tls-troubleshooting-certificate"></a>

 建立帶有交互 TLS 的自訂網域名稱時，如果信任庫中的憑證無效，則 API Gateway 會傳回警告。在更新自訂網域名稱以使用新的信任庫時，也會發生這種情況。警告指出憑證和產生警告之憑證主體的問題。您的 API 仍然啟用交互 TLS，但有些用戶端可能無法存取您的 API。

若要識別產生警告的憑證，請解碼信任庫中的憑證。您可以使用諸如 `openssl` 解碼憑證及識別其主體之類的工具。

下列命令會顯示憑證的內容，包括其主體：

```
openssl x509 -in certificate.crt -text -noout
```

請更新或移除產生警告的憑證，然後將新的信任庫上傳至 Amazon S3。上傳新的信任庫之後，請更新您的自訂網域名稱以使用新的信任庫。

### 疑難排解網域名稱衝突
<a name="w2aac19c17b9c19b7"></a>

錯誤 `"The certificate subject <certSubject> conflicts with an existing certificate from a different issuer."` 表示多個憑證授權單位已發行此網域的憑證。對於憑證中的每個主體，交互 TLS 網域的 API Gateway 中只能有一個發行者。您需要透過單一發行者取得該主體的所有憑證。如果問題是您無法控制的憑證，但您可以證明您擁有網域名稱，請[聯絡 支援](https://console.aws.amazon.com/support/cases#/create) 以開啟票證。

### 疑難排解網域名稱狀態訊息
<a name="w2aac19c17b9c19b9"></a>

`PENDING_CERTIFICATE_REIMPORT`：這表示您已將憑證重新匯入至 ACM，而且由於新憑證具有 SAN (主體別名)，而且這個 SAN 不屬於 `ownershipVerificationCertificate` 範圍或憑證中的主體或 SAN 不包含網域名稱，導致憑證驗證失敗。某些項目可能設定不正確或匯入了無效的憑證。您需要將有效憑證重新匯入 ACM。如需有關驗證的詳細資訊，請參閱[驗證網域擁有權](https://docs.aws.amazon.com/acm/latest/userguide/domain-ownership-validation.html)。

`PENDING_OWNERSHIP_VERIFICATION`：這表示您先前驗證的憑證已過期，ACM 無法對其進行自動續約。您將需要為憑證續約或申請新憑證。關於憑證續約的詳細資訊，請參閱 [ACM 的疑難排解受管憑證續約](https://docs.aws.amazon.com/acm/latest/userguide/troubleshooting-renewal.html)指南。

# 在 API Gateway 中監控 HTTP API
<a name="http-api-monitor"></a>

您可以使用 CloudWatch 指標和 CloudWatch Logs 來監控 HTTP API。藉由結合日誌和指標，您可以記錄錯誤並監控 API 的效能。

**注意**  
在下列情況下，API Gateway 可能無法產生日誌和指標：  
413 請求實體過大錯誤
過多的 429 請求過多錯誤
400 系列錯誤，來自傳送至沒有 API 映射自訂網域的要求
由於內部失敗造成的 500 系列錯誤

**Topics**
+ [在 API Gateway 中監控 HTTP API 的 CloudWatch 指標](http-api-metrics.md)
+ [在 API Gateway 中設定 HTTP API 的日誌](http-api-logging.md)

# 在 API Gateway 中監控 HTTP API 的 CloudWatch 指標
<a name="http-api-metrics"></a>

您可以使用 CloudWatch 來監控 API 執行，該服務會收集並處理來自 API Gateway 的原始資料，進而將這些資料轉換為便於讀取且幾近即時的指標。這些統計資料會記錄 15 個月的時間，以便您存取歷史資訊，並更清楚 Web 應用程式或服務的執行效能。根據預設，API Gateway 指標資料會自動在一分鐘內傳送給 CloudWatch。若要監控您的指標，請為您的 API 建立 CloudWatch 儀表板。如需如何建立 CloudWatch 儀表板的詳細資訊，請參閱《Amazon CloudWatch 使用者指南》**中的[建立 CloudWatch 儀表板](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/create_dashboard.html)。如需更多詳細資訊，請參閱《Amazon CloudWatch 使用者指南》**中的[什麼是 Amazon CloudWatch？](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html)。

HTTP API 支援下列指標。您也可以啟用詳細指標，將路由層級的指標寫入 Amazon CloudWatch。


| 指標 | 描述 | 
| --- | --- | 
| 4xx | 在指定期間內擷取的用戶端錯誤數目。 | 
| 5xx | 在指定期間內擷取的伺服器端錯誤數目。 | 
| Count | 指定期間內的 API 要求總數。 | 
| IntegrationLatency | API Gateway 將請求轉送給後端時與收到來自後端的回應時之間的時間。 | 
| Latency | API Gateway 收到來自用戶端的請求時與它將回應傳回給用戶端時之間的時間。延遲包含整合延遲與其他 API Gateway 額外負荷。 | 
| DataProcessed | 處理的資料量 (以位元組為單位)。 | 

您可以使用下表中的維度來篩選 API Gateway 指標。


| 維度 | 描述 | 
| --- | --- | 
| ApiId | 篩選具指定 API ID 之 API 的 API Gateway 指標。 | 
| ApiId、階段 | 篩選具指定 API ID 與階段 ID 之 API 階段的 API Gateway 指標。 | 
| ApiId、方法、資源、階段 |  篩選具指定 API ID、階段 ID、資源路徑和路由 ID 之 API 方法的 API Gateway 指標。 除非您已明確啟用詳細的 CloudWatch 指標，否則 API Gateway 不會傳送這類指標。您可以透過呼叫 API Gateway V2 REST API 的 [UpdateStage](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-stages-stagename.html) 動作，將 `detailedMetricsEnabled` 屬性更新為 `true`。或者，您可以呼叫[更新階段](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-stage.html) AWS CLI 命令，將 `DetailedMetricsEnabled` 屬性更新為 `true`。啟用這類指標會產生您帳戶的額外費用。如需定價資訊，請參閱 [Amazon CloudWatch 定價](https://aws.amazon.com/cloudwatch/pricing/)。  | 

# 在 API Gateway 中設定 HTTP API 的日誌
<a name="http-api-logging"></a>

您可以開啟記錄功能，將日誌寫入 CloudWatch Logs。您可以使用[記錄變數](http-api-logging-variables.md)來自訂日誌的內容。

為了改善您的安全狀態，建議您將 HTTP API 所有階段的日誌寫入 CloudWatch Logs。您可能需要這樣做，才能符合各種合規架構。如需詳細資訊，請參閱《AWS Security Hub 使用者指南》**中的 [Amazon API Gateway 控制項](https://docs.aws.amazon.com/securityhub/latest/userguide/apigateway-controls.html)。

若要開啟 HTTP API 的記錄功能，您必須執行下列動作。

1. 確定您的使用者具有啟用記錄所需的許可。

1. 建立 CloudWatch Logs 日誌群組。

1. 為 API 的某個階段提供 CloudWatch Logs 日誌群組的 ARN。

## 用以啟用記錄的許可。
<a name="http-api-logging.permissions"></a>

若要開啟 API 的記錄功能，您的使用者必須具有下列許可。

**Example**    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:DescribeLogGroups",
                "logs:DescribeLogStreams",
                "logs:GetLogEvents",
                "logs:FilterLogEvents"
            ],
            "Resource": "arn:aws:logs:us-east-2:123456789012:log-group:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogDelivery",
                "logs:PutResourcePolicy",
                "logs:UpdateLogDelivery",
                "logs:DeleteLogDelivery",
                "logs:CreateLogGroup",
                "logs:DescribeResourcePolicies",
                "logs:GetLogDelivery",
                "logs:ListLogDeliveries"
            ],
            "Resource": "*"
        }
    ]
}
```

## 建立日誌群組並啟動 HTTP API 的記錄
<a name="http-api-enable-logging"></a>

您可以使用 AWS 管理主控台 或 建立日誌群組並啟用存取記錄 AWS CLI。

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

1.  建立 日誌群組 

   如要了解如何使用主控台建立日誌群組，請參閱《Amazon CloudWatch Logs 使用者指南》中的[建立日誌群組](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html)

1. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 選擇一個 HTTP API。

1. 在主導覽面板中的 **Monitor** (監視器) 標籤下，選擇 **Logging** (記錄)。

1. 選取要啟動記錄的階段，然後選擇 **Select** (選取)。

1. 選擇 **Edit** (編輯) 以啟動存取記錄。

1. 開啟 **Access logging** (存取記錄功能)，輸入 CloudWatch Logs，然後選取日誌格式。

1. 選擇**儲存**。

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

以下 [create-log-group](https://docs.aws.amazon.com/cli/latest/reference/logs/create-log-group.html) 命令會建立日誌群組：

```
aws logs create-log-group --log-group-name my-log-group
```

您需要日誌群組的 Amazon Resource Name (ARN) 才能啟用記錄。ARN 格式為 arn:aws:logs:*region*:*account-id*:log-group:*log-group-name*。

下列 [update-stage](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-stage.html) 命令會啟動 HTTP API 的 `$default` 階段的記錄功能：

```
aws apigatewayv2 update-stage --api-id abcdef \
    --stage-name '$default' \
    --access-log-settings '{"DestinationArn": "arn:aws:logs:region:account-id:log-group:log-group-name", "Format": "$context.identity.sourceIp - - [$context.requestTime] \"$context.httpMethod $context.routeKey $context.protocol\" $context.status $context.responseLength $context.requestId"}'
```

------

## 日誌格式範例
<a name="http-api-enable-logging.examples"></a>

一些常用存取日誌格式範例會顯示在 API Gateway 主控台中，並列出如下。
+ `CLF` ([通用日誌格式](https://httpd.apache.org/docs/current/logs.html#common))：

  ```
  $context.identity.sourceIp - - [$context.requestTime] "$context.httpMethod $context.routeKey $context.protocol" $context.status $context.responseLength $context.requestId $context.extendedRequestId
  ```
+  `JSON`: 

  ```
  { "requestId":"$context.requestId", "ip": "$context.identity.sourceIp", "requestTime":"$context.requestTime", "httpMethod":"$context.httpMethod","routeKey":"$context.routeKey", "status":"$context.status","protocol":"$context.protocol", "responseLength":"$context.responseLength", "extendedRequestId": "$context.extendedRequestId" }
  ```
+ `XML`: 

  ```
  <request id="$context.requestId"> <ip>$context.identity.sourceIp</ip> <requestTime>$context.requestTime</requestTime> <httpMethod>$context.httpMethod</httpMethod> <routeKey>$context.routeKey</routeKey> <status>$context.status</status> <protocol>$context.protocol</protocol> <responseLength>$context.responseLength</responseLength> <extendedRequestId>$context.extendedRequestId</extendedRequestId> </request>
  ```
+ `CSV` (逗號分隔值)：

  ```
  $context.identity.sourceIp,$context.requestTime,$context.httpMethod,$context.routeKey,$context.protocol,$context.status,$context.responseLength,$context.requestId,$context.extendedRequestId
  ```

# 自訂 HTTP API 存取日誌
<a name="http-api-logging-variables"></a>

您可以使用下列變數來自訂 HTTP API 存取日誌。要進一步了解 HTTP API 的存取日誌，請參閱[在 API Gateway 中設定 HTTP API 的日誌](http-api-logging.md)。


| 參數 | Description | 
| --- | --- | 
| \$1context.accountId |  API 擁有者 AWS 的帳戶 ID。  | 
| \$1context.apiId |  API Gateway 指派給您 API 的識別碼。  | 
| \$1context.authorizer.claims.property |  成功驗證方法發起人 (例如 `$context.authorizer.claims.username`) 之後，從 JSON Web Token (JWT) 傳回之宣告的屬性。如需詳細資訊，請參閱[使用 API Gateway 中的 JWT 授權方來控制對 HTTP API 的存取](http-api-jwt-authorizer.md)。  呼叫 `$context.authorizer.claims` 會傳回 null。   | 
| \$1context.authorizer.error | 從授權方傳回的錯誤訊息。 | 
| \$1context.authorizer.property |  API Gateway Lambda 授權方函數所傳回 `context` 對應之指定索引鍵/值對的值。例如，如果授權方傳回下列 `context` 映射： <pre>"context" : {<br />  "key": "value",<br />  "numKey": 1,<br />  "boolKey": true<br />}</pre> 呼叫 `$context.authorizer.key` 會傳回 `"value"` 字串，呼叫 `$context.authorizer.numKey` 會傳回 `1`，而呼叫 `$context.authorizer.boolKey` 會傳回 `true`。  | 
| \$1context.awsEndpointRequestId |  來自 `x-amz-request-id`或 `x-amzn-requestId`標頭的 AWS 端點請求 ID。  | 
| \$1context.awsEndpointRequestId2 |  來自 `x-amz-id-2`標頭的 AWS 端點請求 ID。  | 
| \$1context.customDomain.basePathMatched |  傳入請求相符的 API 映射路徑。適用於用戶端使用自訂網域名稱來存取 API 時。例如，如果用戶端向 `https://api.example.com/v1/orders/1234` 傳送請求，並且請求讓 API 映射與路徑 `v1/orders` 相符，則該值為 `v1/orders`。如需進一步了解，請參閱[將 API 階段映射至 HTTP API 的自訂網域名稱](http-api-mappings.md)。  | 
| \$1context.dataProcessed | 處理的資料量 (以位元組為單位)。 | 
| \$1context.domainName |  用來叫用 API 的完整網域名稱。這應該與傳入的 `Host` 標頭相同。  | 
| \$1context.domainPrefix |  `$context.domainName` 的第一個標籤。  | 
| \$1context.error.message |  包含 API Gateway 錯誤訊息的字串。  | 
| \$1context.error.messageString | \$1context.error.message 的引用值，即 "\$1context.error.message"。 | 
| \$1context.error.responseType |  `GatewayResponse` 的類型。如需詳細資訊，請參閱 [使用 CloudWatch 指標監控 WebSocket API 執行](apigateway-websocket-api-logging.md) 和 [設定閘道回應以自訂錯誤回應](api-gateway-gatewayResponse-definition.md#customize-gateway-responses)。  | 
| \$1context.extendedRequestId | 等同於 \$1context.requestId。 | 
| \$1context.httpMethod |  使用的 HTTP 方法。有效值包含：`DELETE`、`GET`、`HEAD`、`OPTIONS`、`PATCH`、`POST` 和 `PUT`。  | 
| \$1context.identity.accountId |  與請求相關聯的 AWS 帳戶 ID。支援使用 IAM 授權的路由。  | 
| \$1context.identity.caller |  已簽署請求之發起人的主體識別符。支援使用 IAM 授權的路由。  | 
| \$1context.identity.cognitoAuthenticationProvider |  提出請求的發起人所使用的所有 Amazon Cognito 驗證提供者清單 (以逗號分隔)。僅在使用 Amazon Cognito 登入資料簽署請求時才可使用。 例如，適用於 Amazon Cognito 使用者集區的身分，`cognito-idp. region.amazonaws.com/user_pool_id,cognito-idp.region.amazonaws.com/user_pool_id:CognitoSignIn:token subject claim` 如需有關 Amazon Cognito 驗證提供者的詳細資訊，請參閱《[Amazon Cognito 開發人員指南](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html)》中的*使用聯合身分*。 | 
| \$1context.identity.cognitoAuthenticationType |  提出請求的發起人的 Amazon Cognito 驗證類型。僅在使用 Amazon Cognito 登入資料簽署請求時才可使用。可能的值包括用於已驗證身分的 `authenticated` 和未經驗證身分的 `unauthenticated`。 | 
| \$1context.identity.cognitoIdentityId |  提出請求的發起人的 Amazon Cognito 身分 ID。僅在使用 Amazon Cognito 登入資料簽署請求時才可使用。  | 
| \$1context.identity.cognitoIdentityPoolId |  提出請求的發起人的 Amazon Cognito 身分集區 ID。僅在使用 Amazon Cognito 登入資料簽署請求時才可使用。  | 
| \$1context.identity.principalOrgId |  [AWS 組織 ID](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_org_details.html)。支援使用 IAM 授權的路由。  | 
| \$1context.identity.clientCert.clientCertPem |  用戶端在交互 TLS 驗證期間所呈現的 PEM 編碼用戶端憑證。當用戶端使用已啟用交互 TLS 的自訂網域名稱存取 API 時會顯示。  | 
| \$1context.identity.clientCert.subjectDN |  用戶端提供之憑證主體的辨別名稱。當用戶端使用已啟用交互 TLS 的自訂網域名稱存取 API 時會顯示。  | 
| \$1context.identity.clientCert.issuerDN |  用戶端提供之憑證發行者的辨別名稱。當用戶端使用已啟用交互 TLS 的自訂網域名稱存取 API 時會顯示。  | 
| \$1context.identity.clientCert.serialNumber |  憑證的序號。當用戶端使用已啟用交互 TLS 的自訂網域名稱存取 API 時會顯示。  | 
| \$1context.identity.clientCert.validity.notBefore |  憑證無效之前的日期。當用戶端使用已啟用交互 TLS 的自訂網域名稱存取 API 時會顯示。  | 
| \$1context.identity.clientCert.validity.notAfter |  憑證無效之後的日期。當用戶端使用已啟用交互 TLS 的自訂網域名稱存取 API 時會顯示。  | 
| \$1context.identity.sourceIp |  對 API Gateway 提出請求之即時 TCP 連線的來源 IP 地址。  | 
| \$1context.identity.user |  將針對資源存取授權之使用者的主體識別符。支援使用 IAM 授權的路由。  | 
| \$1context.identity.userAgent |  API 發起人的 [https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) 標頭。  | 
| \$1context.identity.userArn |  身分驗證之後識別之有效使用者的 Amazon Resource Name (ARN)。支援使用 IAM 授權的路由。如需更多詳細資訊，請參閱 [https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html)。  | 
| \$1context.integration.error | 從整合傳回的錯誤訊息。等同於 \$1context.integrationErrorMessage。 | 
| \$1context.integration.integrationStatus | 對於 Lambda 代理整合，從 傳回的狀態碼 AWS Lambda，而不是從後端 Lambda 函數程式碼傳回的狀態碼。 | 
| \$1context.integration.latency | 整合延遲 (以毫秒為單位)。等同於 \$1context.integrationLatency。 | 
| \$1context.integration.requestId |  AWS 端點的請求 ID。等同於 \$1context.awsEndpointRequestId。 | 
| \$1context.integration.status | 從整合傳回的狀態碼。對於 Lambda 代理整合而言，這是您的 Lambda 函數程式碼傳回的狀態碼。 | 
| \$1context.integrationErrorMessage |  包含整合錯誤訊息的字串。  | 
| \$1context.integrationLatency | 整合延遲 (以毫秒為單位)。 | 
| \$1context.integrationStatus | 對於 Lambda 代理整合，此參數代表從 傳回的狀態碼 AWS Lambda，而不是從後端 Lambda 函數傳回的狀態碼。 | 
| \$1context.path | 請求路徑。例如，/\$1stage\$1/root/child。 | 
| \$1context.protocol | 請求通訊協定，例如 HTTP/1.1。 API Gateway API 可以接受 HTTP/2 請求，但 API Gateway 會使用 HTTP/1.1 將請求傳送至後端整合。因此，即使用戶端傳送使用 HTTP/2 的請求，請求通訊協定也會記錄為 HTTP/1.1。   | 
| \$1context.requestId |  API Gateway 指派給 API 請求的 ID。  | 
| \$1context.requestTime | [CLF](https://httpd.apache.org/docs/current/logs.html#common) 格式化請求時間 (dd/MMM/yyyy:HH:mm:ss \$1-hhmm)。 | 
| \$1context.requestTimeEpoch | [Epoch](https://en.wikipedia.org/wiki/Unix_time) 格式化請求時間。 | 
| \$1context.responseLatency | 回應延遲 (以毫秒為單位)。 | 
| \$1context.responseLength | 回應承載長度 (以位元組為單位)。 | 
| \$1context.routeKey |  API 請求的路由金鑰，例如 `/pets`。  | 
| \$1context.stage |  API 請求的部署階段 (例如，`beta` 或 `prod`)。  | 
| \$1context.status | 方法回應狀態。 | 

# 疑難排解 API Gateway 中的 HTTP API 問題
<a name="http-api-troubleshooting"></a>

下列主題說明當您在使用 HTTP API 時，可如何疑難排解可能遭遇到的錯誤和問題的建議。

**Topics**
+ [對 HTTP API Lambda 整合的問題進行疑難排解](http-api-troubleshooting-lambda.md)
+ [對 HTTP API JWT 授權方的問題進行疑難排解](http-api-troubleshooting-jwt.md)

# 對 HTTP API Lambda 整合的問題進行疑難排解
<a name="http-api-troubleshooting-lambda"></a>

以下建議說明在您將 [AWS Lambda 整合](http-api-develop-integrations-lambda.md) 與 HTTP API 搭配使用時，如何疑難排解可能會遇到的錯誤和問題。

## 問題：具有 Lambda 整合的 API 會傳回 `{"message":"Internal Server Error"}`
<a name="http-api-troubleshooting-lambda-internal-server-error"></a>

若要對內部伺服器錯誤進行疑難排解，請將 `$context.integrationErrorMessage` [記錄變數](http-api-logging-variables.md)新增至您的日誌格式，然後檢視您 HTTP API 的日誌。若要完成此動作，請執行下列操作：

**使用 建立日誌群組 AWS 管理主控台**

1. 在 [https://console.aws.amazon.com/cloudwatch/](https://console.aws.amazon.com/cloudwatch/) 開啟 CloudWatch 主控台。

1. 選擇 **Log groups** (日誌群組)。

1. 選擇 **Create log group** (建立日誌群組)。

1. 輸入日誌群組名稱，然後選擇 **Create** (建立)。

1. 記下日誌群組的 Amazon Resource Name (ARN)。ARN 格式為 arn:aws:logs:*region*: *account-id*:log-group:*log-group-name*。您需要日誌群組 ARN 才能存取 HTTP API 的記錄功能。

**新增 `$context.integrationErrorMessage` 記錄變數**

1. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 選擇 HTTP API。

1. 在 **Monitor** (監控) 下，選擇 **Logging** (記錄)。

1. 選取 API 的階段。

1. 選擇 **Edit** (編輯)，然後存取記錄。

1. 針對 **Log destination** (日誌目的地)，輸入您在上一個步驟中建立之日誌群組的 ARN。

1. 在 **Log format** (日誌格式) 中，選擇 **CLF**。API Gateway 會建立範例日誌格式。

1. 將 `$context.integrationErrorMessage` 新增至日誌格式的結尾。

1. 選擇 **Save** (儲存)。

**檢視 API 的日誌**

1. 產生日誌。使用瀏覽器或 `curl` 來叫用您的 API。

   ```
   $curl https://api-id.execute-api.us-west-2.amazonaws.com/route
   ```

1. 在以下網址登入 API Gateway 主控台：[https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway)。

1. 選擇 HTTP API。

1. 在 **Monitor** (監控) 下，選擇 **Logging** (記錄)。

1. 選取您啟用記錄功能的 API 階段。

1. 選擇 **View logs in CloudWatch** (檢視 CloudWatch 中的日誌)。

1. 選擇最新的日誌串流來檢視 HTTP API 的日誌。

1. 您的日誌項目看起來應與下列類似：  
![\[CloudWatch Logs 日誌項目，顯示來自 Lambda 的整合錯誤訊息。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/troubleshoot-http-api-logs.png)

因為我們已將 `$context.integrationErrorMessage` 新增至日誌格式，所以我們會在摘要問題的日誌中看到錯誤訊息。

您的日誌可能包含不同的錯誤訊息，其中會指出您的 Lambda 函數程式碼發生問題。在這種情況下，請檢查您的 Lambda 函數程式碼，並確認您的 Lambda 函數以[所需的格式](http-api-develop-integrations-lambda.md#http-api-develop-integrations-lambda.response)傳回回應。如果您的日誌未包含錯誤訊息，請將 `$context.error.message` 和 `$context.error.responseType` 新增至您的日誌格式，以取得更多有助於疑難排解的資訊。

在這種情況下，日誌會顯示 API Gateway 沒有叫用 Lambda 函式所需的許可。

當您在 API Gateway 主控台中建立 Lambda 整合時，API Gateway 會自動設定叫用 Lambda 函數的許可。當您使用 AWS CLI CloudFormation或 SDK 建立 Lambda 整合時，您必須授予 API Gateway 調用函數的許可。以下 [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) 命令會對不同的 HTTP API 路由授予許可，以調用 Lambda 函式。

**Example 範例 – 適用於 HTTP API 的 `$default` 階段和 `$default` 路由**  

```
aws lambda add-permission \
    --function-name my-function \
    --statement-id apigateway-invoke-permissions \
    --action lambda:InvokeFunction \
    --principal apigateway.amazonaws.com \
    --source-arn "arn:aws:execute-api:us-west-2:123456789012:api-id/\$default/\$default"
```

**Example 範例 – 適用於 HTTP API 的 `prod` 階段和 `test` 路由**  

```
aws lambda add-permission \
    --function-name my-function \
    --statement-id apigateway-invoke-permissions \
    --action lambda:InvokeFunction \
    --principal apigateway.amazonaws.com \
    --source-arn "arn:aws:execute-api:us-west-2:123456789012:api-id/prod/*/test"
```

在 Lambda 主控台的 **Permissions** (許可) 索引標籤中，[確認函數政策](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html)。

嘗試再次叫用您的 API。您應會看見 Lambda 函數的回應。

# 對 HTTP API JWT 授權方的問題進行疑難排解
<a name="http-api-troubleshooting-jwt"></a>

以下建議說明當您在搭配 HTTP API 使用 JSON Web Token (JWT) 授權方時，如何對可能遇到的錯誤和問題進行疑難排解。

## 問題：我的 API 傳回 `401 {"message":"Unauthorized"}`
<a name="http-api-troubleshooting-jwt.unauthorized"></a>

檢查 API 回應中的 `www-authenticate` 標頭。

下列命令會用 `curl` 來將請求傳送至 API，並使用 JWT 授權方 `$request.header.Authorization` 做為其身分識別來源。

```
$curl -v -H "Authorization: token" https://api-id.execute-api.us-west-2.amazonaws.com/route
```

來自 API 的回應包括一個 `www-authenticate` 標頭。

```
...
< HTTP/1.1 401 Unauthorized
< Date: Wed, 13 May 2020 04:07:30 GMT
< Content-Length: 26
< Connection: keep-alive
< www-authenticate: Bearer scope="" error="invalid_token" error_description="the token does not have a valid audience"
< apigw-requestid: Mc7UVioPPHcEKPA=
<
* Connection #0 to host api-id.execute-api.us-west-2.amazonaws.com left intact
{"message":"Unauthorized"}}
```

在這種情況下，`www-authenticate` 標頭會顯示字符並未發給有效的對象。若 API Gateway 要授權請求，JWT 的 `aud` or `client_id` 要求必須符合為授權方設定的其中一個對象項目。API Gateway 僅於 `aud` 不存在時驗證 `client_id`。當 `aud` 和 `client_id` 同時存在時，API Gateway 會評估 `aud`。

您也可以解碼 JWT，並確認它符合您的 API 所需的發行者、對象和範圍。該網站 [jwt.io](https://jwt.io/) 可以在瀏覽器中對 JWT 偵錯。OpenID Foundation 會[提供可搭配 JWT 使用的程式庫清單](https://openid.net/developers/jwt-jws-jwe-jwk-and-jwa-implementations/)。

若要進一步了解 JWT 授權方，請參閱[使用 API Gateway 中的 JWT 授權方來控制對 HTTP API 的存取](http-api-jwt-authorizer.md)。