

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

# 在 APIs Gateway 中開發 REST API
<a name="rest-api-develop"></a>

 在 Amazon API Gateway 中，您可以將 REST API 建置為可程式化實體的集合，稱為 API Gateway [資源](https://docs.aws.amazon.com/apigateway/latest/api/API_Resource.html)。例如，您可以使用 [RestApi](https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html) 資源來代表可包含 [Resource](https://docs.aws.amazon.com/apigateway/latest/api/API_Resource.html) 實體集合的 API。

每個 `Resource` 實體可以擁有一或多個 [Method](https://docs.aws.amazon.com/apigateway/latest/api/API_Method.html) 資源。`Method` 是用戶端提交的傳入請求，可包含下列請求參數：路徑參數、標頭或查詢字串參數。此外，根據 HTTP 方法而定，請求可以包含內文。您的方法會定義用戶端存取公開 `Resource` 的方式。若要將 `Method` 與後端端點整合，也稱為整合端點，您可以建立[整合](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html)資源。這會將傳入請求轉送到指定的整合端點 URI。如有必要，您可以轉換請求參數或請求內文以符合後端需求，也可以建立代理整合，其中 API Gateway 會以標準化格式將整個請求傳送至整合端點 URI，然後直接將回應傳送至用戶端。

針對回應，您可以建立 [MethodResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html) 資源來代表用戶端接收的回應，並建立 [IntegrationResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html) 資源來代表後端傳回的回應。請先使用整合回應來轉換後端回應資料，再將資料傳回至用戶端，或將後端回應依現狀傳遞到用戶端。

## REST API 的範例資源
<a name="rest-api-develop-example"></a>

下圖顯示 API Gateway 如何針對 `GET /pets` 資源的 HTTP 代理和 HTTP 非代理整合，實作此請求/回應模型。用戶端會將 `x-version:beta` 標頭傳送至 API Gateway，而 API Gateway 會將 `204` 狀態碼傳送至用戶端。

在非代理整合中，API Gateway 會修改整合請求和整合回應來執行資料轉換，以滿足後端需求。在非代理整合中，您可以在方法請求中存取內文，但會在整合請求中進行轉換。當整合端點傳回具有內文的回應時，您可以在整合回應中存取和轉換內文。您無法在方法回應中修改內文。

在代理整合中，整合端點會修改請求和回應。API Gateway 不會修改整合請求或整合回應，且會將傳入的請求依原樣傳送至後端。

無論整合類型為何，用戶端都會將請求傳送至 API Gateway，而 API Gateway 會同步回應。

------
#### [ Non-proxy integration ]

![\[API Gateway 非代理整合圖\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/develop-non-proxy.png)


------
#### [ Proxy integration ]

![\[API Gateway 代理整合圖\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/develop-proxy.png)


------

下列範例執行日誌顯示 API Gateway 在上一個範例中記錄的內容。部分值和初始日誌已移除，以便清楚呈現內容：

------
#### [ Non-proxy integration ]

```
Wed Feb 12 23:56:44 UTC 2025 : Starting execution for request: abcd-1234-5678
Wed Feb 12 23:56:44 UTC 2025 : HTTP Method: GET, Resource Path: /pets
Wed Feb 12 23:56:44 UTC 2025 : Method request path: {}
Wed Feb 12 23:56:44 UTC 2025 : Method request query string: {}
Wed Feb 12 23:56:44 UTC 2025 : Method request headers: {x-version=beta}
Wed Feb 12 23:56:44 UTC 2025 : Method request body before transformations: 
Wed Feb 12 23:56:44 UTC 2025 : Endpoint request URI: http://petstore-demo-endpoint.execute-api.com/petstore/pets
Wed Feb 12 23:56:44 UTC 2025 : Endpoint request headers: {app-version=beta}
Wed Feb 12 23:56:44 UTC 2025 : Endpoint request body after transformations: 
Wed Feb 12 23:56:44 UTC 2025 : Sending request to http://petstore-demo-endpoint.execute-api.com/petstore/pets
Wed Feb 12 23:56:45 UTC 2025 : Received response. Status: 200, Integration latency: 123 ms
Wed Feb 12 23:56:45 UTC 2025 : Endpoint response headers: {Date=Wed, 12 Feb 2025 23:56:45 GMT}
Wed Feb 12 23:56:45 UTC 2025 : Endpoint response body before transformations:
Wed Feb 12 23:56:45 UTC 2025 : Method response body after transformations: (null)
Wed Feb 12 23:56:45 UTC 2025 : Method response headers: {X-Amzn-Trace-Id=Root=1-abcd-12345}
Wed Feb 12 23:56:45 UTC 2025 : Successfully completed execution
Wed Feb 12 23:56:45 UTC 2025 : Method completed with status: 204
```

------
#### [ Proxy integration ]

```
Wed Feb 12 23:59:42 UTC 2025 : Starting execution for request: abcd-1234-5678
Wed Feb 12 23:59:42 UTC 2025 : HTTP Method: GET, Resource Path: /pets
Wed Feb 12 23:59:42 UTC 2025 : Method request path: {}
Wed Feb 12 23:59:42 UTC 2025 : Method request query string: {}
Wed Feb 12 23:59:42 UTC 2025 : Method request headers: {x-version=beta}
Wed Feb 12 23:59:42 UTC 2025 : Method request body before transformations: 
Wed Feb 12 23:59:42 UTC 2025 : Endpoint request URI: http://petstore-demo-endpoint.execute-api.com/petstore/pets
Wed Feb 12 23:59:42 UTC 2025 : Endpoint request headers: { x-version=beta}
Wed Feb 12 23:59:42 UTC 2025 : Endpoint request body after transformations: 
Wed Feb 12 23:59:42 UTC 2025 : Sending request to http://petstore-demo-endpoint.execute-api.com/petstore/pets
Wed Feb 12 23:59:43 UTC 2025 : Received response. Status: 204, Integration latency: 123 ms
Wed Feb 12 23:59:43 UTC 2025 : Endpoint response headers: {Date=Wed, 12 Feb 2025 23:59:43 GMT}
Wed Feb 12 23:59:43 UTC 2025 : Endpoint response body before transformations: 
Wed Feb 12 23:59:43 UTC 2025 : Method response body after transformations:
Wed Feb 12 23:59:43 UTC 2025 : Method response headers: {Date=Wed, 12 Feb 2025 23:59:43 GMT}
Wed Feb 12 23:59:43 UTC 2025 : Successfully completed execution
Wed Feb 12 23:59:43 UTC 2025 : Method completed with status: 204
```

------

若要匯入類似的 API 並在 中測試它 AWS 管理主控台，請參閱[範例 API](api-gateway-create-api-from-example.md)。

## 用於開發的其他 REST API 功能
<a name="rest-api-develop-details"></a>

API Gateway 支援其他用於開發 REST API 的功能。例如，為了協助客戶了解您的 API，您可以提供 API 的文件。若要啟用此功能，請新增受支援 API 實體的 [DocumentationPart](https://docs.aws.amazon.com/apigateway/latest/api/API_DocumentationPart.html) 資源。

若要控制用戶端呼叫 API 的方式，請使用 [IAM 許可](permissions.md)、[Lambda 授權方](apigateway-use-lambda-authorizer.md)或 [Amazon Cognito 使用者集區](apigateway-integrate-with-cognito.md)。若要測量 API 的用量，請設定 [ usage plans (用量方案)](api-gateway-api-usage-plans.md) 來調節 API 請求。您可以在建立或更新 API 時啟用這些功能。

下圖顯示可用於 REST API 開發的功能，以及請求/回應模型中可設定這些功能的位置。

![\[API Gateway 功能圖\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/develop-features.png)


如需有關如何建立 API 的簡介，請參閱 [教學：建立具 Lambda 代理整合的 REST API](api-gateway-create-api-as-simple-proxy-for-lambda.md)。若要進一步了解開發 REST API 時可能會使用的 API Gateway 功能，請參閱下列主題。這些主題包含您可以使用 API Gateway 主控台、API Gateway REST API AWS CLI、 或其中一個 AWS SDKs 執行的概念資訊和程序。

**Topics**
+ [REST API 的範例資源](#rest-api-develop-example)
+ [用於開發的其他 REST API 功能](#rest-api-develop-details)
+ [API Gateway 中 REST API 的 API 端點類型](api-gateway-api-endpoint-types.md)
+ [APIs中 REST API 的安全政策](apigateway-security-policies.md)
+ [API Gateway 中 REST API 的 IP 位址類型](api-gateway-ip-address-type.md)
+ [API Gateway 中 REST API 的方法](how-to-method-settings.md)
+ [在 API Gateway 中控制和管理對 REST API 的存取](apigateway-control-access-to-api.md)
+ [API Gateway 中 REST API 的整合](how-to-integration-settings.md)
+ [API Gateway 中的 REST API 的請求驗證](api-gateway-method-request-validation.md)
+ [API Gateway 中用於 REST API 的資料轉換](rest-api-data-transformations.md)
+ [API Gateway 中 REST API 的閘道回應](api-gateway-gatewayResponse-definition.md)
+ [API Gateway 中 REST API 的 CORS](how-to-cors.md)
+ [API Gateway 中 REST API 的二進位媒體類型](api-gateway-payload-encodings.md)
+ [在 API Gateway 中調用 REST API](how-to-call-api.md)
+ [在 API Gateway 中使用 OpenAPI 開發 REST API](api-gateway-import-api.md)

# API Gateway 中 REST API 的 API 端點類型
<a name="api-gateway-api-endpoint-types"></a>

*[API 端點](api-gateway-basic-concept.md#apigateway-definition-api-endpoints)* 類型是指 API 的主機名稱。根據您大部分 API 流量的來源而定，API 端點類型可以是*邊緣最佳化*、*區域*或*私有*。

## 邊緣最佳化的 API 端點
<a name="api-gateway-api-endpoint-types-edge-optimized"></a>

*[邊緣最佳化 API 端點](api-gateway-basic-concept.md#apigateway-definition-edge-optimized-api-endpoint)*通常會將請求路由至最靠近的 CloudFront 連接點 (POP)，該連接點可在您的用戶端分散各地的情況下提供協助。這是 API Gateway REST API 的預設端點類型。

邊緣最佳化 API 會提供 [HTTP 標頭](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers)的名稱 (例如，`Cookie`)。

CloudFront 依據 Cookie 名稱以自然順序排序 HTTP Cookie，然後將請求轉送到原始伺服器。如需 CloudFront 處理 Cookie 方式的詳細資訊，請參閱[根據 Cookie 快取內容](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Cookies.html)。

針對邊緣最佳化 API，您使用的任何自訂網域名稱適用於所有區域。

## 區域 API 端點
<a name="api-gateway-api-endpoint-types-regional"></a>

*[區域 API 端點](api-gateway-basic-concept.md#apigateway-definition-regional-api-endpoint)*適用於相同區域中的用戶端。當 EC2 執行個體上執行的用戶端呼叫相同區域中的 API 時，或當 API 是為了提供服務給具有高需求的少量用戶端時，區域 API 可降低連線成本。

針對區域 API，您使用的任何自訂網域名稱都是專屬於 API 部署所在的區域。如果您在多個區域中部署區域 API，其可在所有區域中擁有相同的自訂網域名稱。您可以使用自訂網域搭配 Amazon Route 53 來執行任務，例如[以延遲為基礎的路由](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy.html#routing-policy-latency)。如需詳細資訊，請參閱[在 API Gateway 中設定區域性自訂網域名稱](apigateway-regional-api-custom-domain-create.md)及[設定 API Gateway 中的邊緣最佳化的自訂網域名稱](how-to-edge-optimized-custom-domain-name.md)。

所有區域和 API 端點會依原狀傳遞所有標頭名稱。

**注意**  
如果地理上 API 用戶端分散各處，則使用區域 API 端點與自己的 Amazon CloudFront 分佈搭配，以確保 API Gateway 不會將 API 與服務控制的 CloudFront 分佈建立關聯，這樣做可能仍有意義。如需此使用案例的詳細資訊，請參閱[如何設定 API Gateway 與自己的 CloudFront 分佈搭配？](https://repost.aws/knowledge-center/api-gateway-cloudfront-distribution)。

## 私有 API 端點
<a name="api-gateway-api-endpoint-types-private"></a>

*[私有 API 端點](api-gateway-basic-concept.md#apigateway-definition-private-api-endpoint)*是僅能從 Amazon Virtual Private Cloud (VPC) 透過界面 VPC 端點存取的 API 端點；此端點是您在 VPC 中建立的端點網路界面 (ENI)。如需更多詳細資訊，請參閱 [API Gateway 中的私有 REST API](apigateway-private-apis.md)。

所有私有 API 端點會依原狀傳遞所有標頭名稱。

# 在 API Gateway 中變更公有或私有 API 端點類型
<a name="apigateway-api-migration"></a>

變更 API 端點類型需要您更新 API 的組態。您可以使用 API Gateway 主控台、 AWS CLI或適用於 API Gateway 的 AWS SDK 變更現有的 API 類型。無法再次變更其端點類型，直到目前變更完成為止。

支援下列端點類型的變更：
+ 從邊緣最佳化變更為區域性或私有
+ 從區域性變更為邊緣最佳化或私有
+ 從私有改為區域性

您不能將私有 API 改為邊緣最佳化 API。

請注意，如果您要將公有 API 從邊緣最佳化變更為區域性 (反之亦然)，邊緣最佳化的 API 的行為可能與區域 API 的行為不同。例如，邊緣最佳化 API 會移除 `Content-MD5` 標頭。任何傳送到後端的 MD5 雜湊值都可以請求字串參數或內文屬性表示。不過，區域 API 仍會傳送此標頭，雖然此標頭名稱可能會重新映射到其他一些名稱。了解其中差異有助於決定如何將邊緣最佳化的 API 更新為區域 API，或將區域 API 更新為邊緣最佳化的 API。

**Topics**
+ [使用 API Gateway 主控台變更 API 端點類型](#migrate-api-using-console)
+ [使用 AWS CLI 變更 API 端點類型](#migrate-api-using-aws-cli)

## 使用 API Gateway 主控台變更 API 端點類型
<a name="migrate-api-using-console"></a>

若要為您的 API 變更 API 端點類型，請執行下列任一組步驟：

**將端點從區域或邊緣最佳化轉換為公有 (以及反向轉換)**

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

1. 選擇 REST API。

1. 選擇 **API 設定**。

1. 在 **API 詳細資訊**區段中，選擇**編輯**。

1. 對於 **API 端點類型**，選取**邊緣最佳化**或**區域**。

1. 選擇**儲存變更**。

1. 重新部署您的 API，變更才會生效。

**將私有端點轉換為區域端點**

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

1. 選擇 REST API。

1. 編輯您的 API 資源政策，以移除任何提及的 VPC 或 VPC 端點；如此一來，從您的 VPC 內、外部進行的 API 呼叫將可成功。

1. 選擇 **API 設定**。

1. 在 **API 詳細資訊**區段中，選擇**編輯**。

1. 對於 **API 端點類型**，選取**區域**。

1. 選擇**儲存變更**。

1. 從您的 API 移除資源政策。

1. 重新部署您的 API，變更才會生效。

   由於您要將端點類型從私有移轉至區域，因此 API Gateway 會將 IP 位址類型變更為 IPv4。如需詳細資訊，請參閱[API Gateway 中 REST API 的 IP 位址類型](api-gateway-ip-address-type.md)。

**將區域端點轉換為私有端點**

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

1. 選擇 REST API。

1. 建立授予 VPC 或 VPC 端點存取權的資源政策。如需詳細資訊，請參閱[步驟 3：為私有 API 設定資源政策](apigateway-private-api-create.md#apigateway-private-api-set-up-resource-policy)。

1. 選擇 **API 設定**。

1. 在 **API 詳細資訊**區段中，選擇**編輯**。

1. 針對 **API 端點類型**，選取**私有**。

1. (選用) 針對 **VPC 端點 ID**，選取您要與私有 API 建立關聯的 VPC 端點 ID。

1. 選擇**儲存變更**。

1. 重新部署您的 API，變更才會生效。

   由於您要將端點類型從區域移轉至私有，因此 API Gateway 會將 IP 位址類型變更為雙堆疊。如需詳細資訊，請參閱[API Gateway 中 REST API 的 IP 位址類型](api-gateway-ip-address-type.md)。

## 使用 AWS CLI 變更 API 端點類型
<a name="migrate-api-using-aws-cli"></a>

以下 [update-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-rest-api.html) 命令會將邊緣最佳化 API 更新為區域 API：

```
aws apigateway update-rest-api \
    --rest-api-id a1b2c3 \
    --patch-operations op=replace,path=/endpointConfiguration/types/EDGE,value=REGIONAL
```

成功回應會有 `200 OK` 狀態碼與類似下列的承載：

```
{
    "createdDate": "2017-10-16T04:09:31Z",
    "description": "Your first API with Amazon API Gateway. This is a sample API that integrates via HTTP with our demo Pet Store endpoints",
    "endpointConfiguration": {
        "types": "REGIONAL"
    },
    "id": "a1b2c3",
    "name": "PetStore imported as edge-optimized"
}
```

以下 [update-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-rest-api.html) 命令會將區域 API 更新為邊緣最佳化 API：

```
aws apigateway update-rest-api \
    --rest-api-id a1b2c3 \
    --patch-operations op=replace,path=/endpointConfiguration/types/REGIONAL,value=EDGE
```

由於 [put-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-rest-api.html) 適用於更新 API 定義，因此不適用於更新 API 端點類型。

# APIs中 REST API 的安全政策
<a name="apigateway-security-policies"></a>

*安全政策*是 API Gateway 所提供的最低 TLS 版本與密碼套件的預先定義組合。當用戶端建立 API 的 TLS 交握或自訂網域名稱時，安全政策會強制執行 API Gateway 接受的 TLS 版本和密碼套件。安全政策可保護您的 API 和自訂網域名稱，使其免於發生網路安全問題，例如在用戶端和伺服器之間竄改和竊聽。

API Gateway 支援舊版安全政策和增強型安全政策。 `TLS_1_0`和 `TLS_1_2` 是舊版安全政策。使用這些安全政策來實現回溯相容性。任何以 開頭的政策`SecurityPolicy_`都是增強型安全政策。將這些政策用於受規範的工作負載、進階治理，或使用後量子密碼學。使用增強型安全政策時，您也必須設定端點存取模式，以進行額外的治理。如需詳細資訊，請參閱[端點存取模式](#apigateway-security-policies-endpoint-access-mode)。

## API Gateway 如何套用安全政策
<a name="apigateway-security-policies-understanding"></a>

下列範例顯示 API Gateway 如何使用安全政策作為範例來套用`SecurityPolicy_TLS13_1_3_2025_09`安全政策。

`SecurityPolicy_TLS13_1_3_2025_09` 安全政策接受 TLS 1.3 流量，並拒絕 TLS 1.2 和 TLS 1.0 流量。對於 TLS 1.3 流量，安全政策接受下列密碼套件：
+ `TLS_AES_128_GCM_SHA256`
+ `TLS_AES_256_GCM_SHA384`
+ `TLS_CHACHA20_POLY1305_SHA256`

API Gateway 不接受任何其他密碼套件。例如，安全政策會拒絕任何使用加密套件的 `AES128-SHA` TLS 1.3 流量。如需支援的 TLS 版本和密碼的詳細資訊，請參閱 [支援的安全政策](apigateway-security-policies-list.md)。

若要監控用於存取 API Gateway 的 TLS 通訊協定和加密用戶端，您可以使用存取日誌中的 `$context.tlsVersion`和 `$context.cipherSuite`內容變數。如需詳細資訊，請參閱[在 API Gateway 中監控 REST API](rest-api-monitor.md)。

## 端點存取模式
<a name="apigateway-security-policies-endpoint-access-mode"></a>

端點存取模式是您必須為任何使用以 `SecurityPolicy_` 開頭的增強型安全政策的 REST API 或自訂網域名稱所指定的額外參數。您可以在建立資源時執行此操作，或將安全政策從舊版政策變更為增強型政策時執行此操作。

當端點存取模式設定為 時`STRICT`，對 REST API 或自訂網域名稱的任何請求都必須通過下列檢查：
+ 請求必須來自與資源相同的 API Gateway 端點類型。這可能來自區域、邊緣最佳化或私有端點。
+ 如果您使用區域或私有端點，API Gateway 會使用 SNI 主機比對。如果您使用邊緣最佳化端點，API Gateway 會符合 CloudFront 的網域前端保護。如需詳細資訊，請參閱[網域前端](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html#alternate-domain-names-restrictions)。

如果不符合上述任一條件，API Gateway 會拒絕請求。我們建議您盡可能使用`STRICT`端點存取模式。

若要遷移現有的 API 或網域名稱以使用嚴格的端點存取模式，請先將安全政策更新為增強型安全政策，並將端點存取模式設定為 `BASIC`。驗證流量和存取日誌之後，請將端點存取模式設定為 `STRICT`。當您將端點存取模式從 遷移`STRICT`至 時`BASIC`，隨著變更傳播，您的端點將無法使用約 15 分鐘。

您不應該`STRICT`針對特定應用程式架構將端點存取模式設定為 ，而是將端點存取模式設定為 `BASIC`。下表顯示一些應用程式架構和建議，讓您的 REST API 或自訂網域名稱可以使用`STRICT`端點存取模式。


| Architecture | 建議的遷移 | 
| --- | --- | 
| 使用 VPC 端點存取公有自訂網域名稱。 | 此架構使用跨端點類型流量。我們建議您遷移至 [API Gateway 中的 API 私有 API 的自訂網域名稱](apigateway-private-custom-domains.md)。 | 
|  使用任何方法叫用不使用自訂網域名稱或私有 DNS 名稱的私有 API。 | 此架構會在主機標頭與 TLS 交握中使用的 SNI 之間建立不相符，並且不會通過 CloudFront 的網域前端限制。我們建議您遷移 VPC 以使用私有 DNS。 | 
| 使用網域碎片將內容分散到多個網域或子網域。 | 此架構會在主機標頭與 TLS 交握中使用的 SNI 之間建立不相符，並且不會通過 CloudFront 的網域前端限制。我們建議您使用 `HTTP/2`並從此反模式遷移。 | 

以下是使用端點存取模式的考量：
+ 如果 API 或網域名稱的端點存取模式為 `STRICT`，則您無法變更端點類型。若要變更端點類型，請先將端點存取模式變更為 `BASIC`。
+ 將端點存取模式從 變更為 `BASIC` 後`STRICT`，API Gateway 會延遲 15 分鐘，以強制執行嚴格的端點存取模式。
+ 當您將安全政策從開頭為 的政策變更為`SecurityPolicy_`舊版政策時，您必須將端點存取模式取消設定為 `""`。

## 考量事項
<a name="apigateway-security-policies-considerations"></a>

以下是 API Gateway 中 REST APIs的安全政策考量：
+ 您可以在 OpenAPI 定義檔案中匯入安全政策。如需詳細資訊，請參閱[x-amazon-apigateway-endpoint-access-modex-amazon-apigateway-security-policy](openapi-extensions-security-policy.md)。
+ 您的 API 可以映射到與 API 具有不同安全政策的自訂網域名稱。當您叫用該自訂網域名稱時，API Gateway 會使用 API 的安全政策來交涉 TLS 交握。如果您停用預設 API 端點，則可能會影響發起人調用 API 的方式。
+ 如果您變更安全政策，更新大約需要 15 分鐘才能完成。您可以監控 API `apiStatus`的 。隨著 API 更新， `apiStatus` 是 `UPDATING` ，當它完成時，它將是 `AVAILABLE`。當您的 API 狀態為 時`UPDATING`，您仍然可以叫用它。
+ API Gateway 支援所有 APIs的安全政策。不過，您只能選擇 REST APIs的安全政策。API Gateway 僅支援 HTTP 或 WebSocket APIs`TLS_1_2`的安全政策。
+ 您無法將 API 的安全政策從 更新`TLS_1_0`為 `TLS_1_2`。
+ 有些安全政策同時支援 ECDSA 和 RSA 密碼套件。如果您將這種類型的政策與自訂網域名稱搭配使用，加密套件會符合客戶提供的憑證金鑰類型 RSA 或 ECDSA。如果您搭配 REST API 使用這種類型的政策，加密套件會符合與 RSA 憑證類型相容的加密套件。

# 支援的安全政策
<a name="apigateway-security-policies-list"></a>

下表說明可為每個 REST API 端點類型和自訂網域名稱類型指定的[安全政策](apigateway-security-policies.md)。這些政策可讓您控制傳入連線。API Gateway 僅支援輸出的 TLS 1.2。您可以隨時更新 API 或自訂網域名稱的安全政策。

標題`FIPS`中包含 的政策與聯邦資訊處理標準 (FIPS) 相容，這是美國和加拿大政府標準，可指定保護敏感資訊之密碼編譯模組的安全要求。若要進一步了解，請參閱*AWS 雲端安全合規*頁面上的[聯邦資訊處理標準 (FIPS) 140](https://aws.amazon.com/compliance/fips/)。

所有 FIPS 政策都會利用 AWS-LC FIPS 驗證的密碼編譯模組。若要進一步了解，請參閱 NIST [ 密碼編譯模組驗證計劃網站上的 AWS-LC](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4631) 密碼編譯模組頁面。 **

標題`PQ`中包含 的政策使用[後量子密碼編譯 (PQC)](https://aws.amazon.com/security/post-quantum-cryptography/) 實作 TLS 的混合金鑰交換演算法，以確保流量對未來量子運算威脅的機密性。

標題`PFS`中包含 的政策會使用 [Perfect Forward Secrecy (PFS)](https://en.wikipedia.org/wiki/Forward_secrecy)，以確保工作階段金鑰不會洩露。

在其標題`PQ`中同時包含 `FIPS`和 的政策支援這兩種功能。

## 預設安全政策
<a name="apigateway-security-policies-default"></a>

當您建立新的 REST API 或自訂網域時，資源會獲指派預設的安全政策。下表顯示這些資源的預設安全政策。


| **Resource** | **預設安全政策名稱** | 
| --- | --- | 
| 區域 API | TLS\$11\$10 | 
| 邊緣最佳化的 API | TLS\$11\$10 | 
| 私有 API | TLS\$11\$12 | 
| 區域網域 | TLS\$11\$12 | 
| Edge 最佳化網域 | TLS\$11\$12 | 
| 私有網域 | TLS\$11\$12 | 

## 區域和私有 APIs以及自訂網域名稱支援的安全政策
<a name="apigateway-security-policies-non-edge"></a>

下表說明可為區域和私有 APIs 以及自訂網域名稱指定的安全政策：


| **安全政策** | **支援的 TLS 版本** | **支援的加密** | 
| --- | --- | --- | 
| SecurityPolicy\$1TLS13\$11\$13\$12025\$109 | TLS1.3 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| SecurityPolicy\$1TLS13\$11\$13\$1FIPS\$12025\$109 | TLS1.3 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| SecurityPolicy\$1TLS13\$11\$12\$1FIPS\$1PFS\$1PQ\$12025\$109 | TLS1.3 TLS1.2 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| SecurityPolicy\$1TLS13\$11\$12\$1PFS\$1PQ\$12025\$109 | TLS1.3 TLS1.2 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| SecurityPolicy\$1TLS13\$11\$12\$1PQ\$12025\$109 | TLS1.3 TLS1.2 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| SecurityPolicy\$1TLS13\$11\$12\$12021\$106 | TLS1.3 TLS1.2 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| TLS\$11\$12 | TLS1.3 TLS1.2 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| TLS\$11\$10 |  TLS1.3 TLS1.2 TLS1.1 TLS1.0  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 

## 邊緣最佳化 APIs 和自訂網域名稱支援的安全政策
<a name="apigateway-security-policies-edge-optimized"></a>

下表說明可針對邊緣最佳化 APIs 和邊緣最佳化自訂網域名稱指定的安全政策：


| **安全政策名稱** | **支援的 TLS 版本** | **支援的密碼** | 
| --- | --- | --- | 
| SecurityPolicy\$1TLS13\$12025\$1EDGE | TLS1.3 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| SecurityPolicy\$1TLS12\$1PFS\$12025\$1EDGE |  TLS1.3 TLS1.2  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| SecurityPolicy\$1TLS12\$12018\$1EDGE |  TLS1.3 TLS1.2  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 
| TLS\$11\$10 |  TLS1.3 TLS1.2 TLS1.1 TLS1.0  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html) [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-security-policies-list.html)  | 

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

OpenSSL 和 IETF RFC 5246 使用相同密碼的不同名稱。下表將 OpenSSL 名稱對應到每個密碼的 RFC 名稱。如需詳細資訊，請參閱 OpenSSL 文件中的[加密](https://docs.openssl.org/1.1.1/man1/ciphers/)。


| **OpenSSL 和密碼名稱** | **RFC 密碼名稱** | 
| --- | --- | 
| TLS\$1AES\$1128\$1GCM\$1SHA256 | TLS\$1AES\$1128\$1GCM\$1SHA256 | 
| TLS\$1AES\$1256\$1GCM\$1SHA384 | TLS\$1AES\$1256\$1GCM\$1SHA384 | 
| TLS\$1CHACHA20\$1POLY1305\$1SHA256 | TLS\$1CHACHA20\$1POLY1305\$1SHA256 | 
| ECDHE-RSA-AES128-GCM-SHA256 | TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1GCM\$1SHA256 | 
| ECDHE-RSA-AES128-SHA256 | TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA256  | 
| ECDHE-RSA-AES128-SHA | TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA | 
| ECDHE-RSA-AES256-GCM-SHA384 | TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1GCM\$1SHA384  | 
| ECDHE-RSA-AES256-SHA384 | TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA384  | 
| ECDHE-RSA-AES256-SHA | TLS\$1ECDHE\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA | 
| AES128-GCM-SHA256 | TLS\$1RSA\$1WITH\$1AES\$1128\$1GCM\$1SHA256 | 
| AES256-GCM-SHA384 | TLS\$1RSA\$1WITH\$1AES\$1256\$1GCM\$1SHA384 | 
| AES128-SHA256 | TLS\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA256 | 
| AES256-SHA | TLS\$1RSA\$1WITH\$1AES\$1256\$1CBC\$1SHA | 
| AES128-SHA | TLS\$1RSA\$1WITH\$1AES\$1128\$1CBC\$1SHA | 
| DES-CBC3-SHA | TLS\$1RSA\$1WITH\$13DES\$1EDE\$1CBC\$1SHA | 

# 如何變更安全政策
<a name="apigateway-security-policies-update"></a>

您可以變更 API 的安全政策。如果您要透過自訂網域名稱將流量傳送至 APIs，則 API 和自訂網域名稱不需要具有相同的安全政策。當您叫用該自訂網域名稱時，API Gateway 會使用 API 的安全政策來交涉 TLS 交握。不過，為了保持一致性，我們建議您針對自訂網域名稱和 API 使用相同的安全政策。

如果您變更安全政策，更新大約需要 15 分鐘才能完成。您可以監控 API `apiStatus`的 。隨著 API 更新， `apiStatus` 是 `UPDATING` ，當它完成時，它將是 `AVAILABLE`。更新 API 時，您仍然可以叫用它。

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

**變更 API 的安全政策**

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

1. 選擇 REST API。

1. 選擇 **API 設定**，然後選擇**編輯**。

1. 針對**安全政策**，選取以 開頭的新政策`SecurityPolicy_`。

1. 針對**端點存取模式**，選擇**嚴格**。

1. 選擇**儲存變更**。

   重新部署 API 以使變更生效。由於您將端點存取模式變更為嚴格，變更完全傳播大約需要 15 分鐘。

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

下列 [update-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-rest-api.html) 命令會更新 API 以使用`SecurityPolicy_TLS13_1_3_2025_09`安全政策：

```
aws apigateway update-rest-api \
    --rest-api-id abcd1234 \
    --patch-operations '[
        {
            "op": "replace",
            "path": "/securityPolicy",
            "value": "SecurityPolicy_TLS13_1_3_2025_09"
        }, 
        {
            "op": "replace",
            "path": "/endpointAccessMode",
            "value": "STRICT"
        }
    ]'
```

輸出將如下所示：

```
{
    "id": "abcd1234",
    "name": "MyAPI",
    "description": "My API with a new security policy",
    "createdDate": "2025-02-04T11:47:06-08:00",
    "apiKeySource": "HEADER",
    "endpointConfiguration": {
        "types": [
            "REGIONAL"
        ],
        "ipAddressType": "dualstack"
    },
    "tags": {},
    "disableExecuteApiEndpoint": false,
    "securityPolicy": "SecurityPolicy_TLS13_1_3_2025_09",
    "endpointAccessMode": "STRICT"
    "rootResourceId": "efg456"
}
```

下列 [update-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-rest-api.html) 命令會更新使用增強型安全政策來使用`TLS_1_0`安全政策的 API。

```
aws apigateway update-rest-api \
    --rest-api-id abcd1234 \
    --patch-operations '[
        {
            "op": "replace",
            "path": "/securityPolicy",
            "value": "TLS_1_0"
        }, 
        {
            "op": "replace",
            "path": "/endpointAccessMode",
            "value": ""
        }
    ]'
```

輸出將如下所示：

```
{
    "id": "abcd1234",
    "name": "MyAPI",
    "description": "My API with a new security policy",
    "createdDate": "2025-02-04T11:47:06-08:00",
    "apiKeySource": "HEADER",
    "endpointConfiguration": {
        "types": [
            "REGIONAL"
        ],
        "ipAddressType": "dualstack"
    },
    "tags": {},
    "disableExecuteApiEndpoint": false,
    "securityPolicy": "TLS_1_0",
    "rootResourceId": "efg456"
}
```

------

# API Gateway 中 REST API 的 IP 位址類型
<a name="api-gateway-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)。

若要將您的 API 僅限用於 IPv6 流量，您可以建立資源政策，並將來源 IP 位址僅限於 IPv6 範圍。您可以藉由更新 API 的組態來變更 IP 位址類型。此變更會立即生效，而且您不需要重新部署 API。如需詳細資訊，請參閱[範例：拒絕根據來源 IP 地址或範圍的 API 流量](apigateway-resource-policies-examples.md#apigateway-resource-policies-source-ip-address-example)

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

下列考量事項可能會影響您使用 IP 位址類型：
+ 所有區域和邊緣最佳化 API 的預設 IP 位址類型都是 IPv4。
+ 私有 API 只能具有雙堆疊 IP 位址類型。
+ 如果您將現有 API 的 IP 位址類型從 IPv4 變更為雙堆疊，請確認控制存取 API 的任何政策都已更新，以便進行 IPv6 呼叫。當您變更 IP 位址類型時，變更會立即生效。
+ 如果您將 API 的端點類型從區域或邊緣最佳化移轉至私有，則 API Gateway 會將 IP 位址類型變更為雙堆疊。如需更多詳細資訊，請參閱 [在 API Gateway 中變更公有或私有 API 端點類型](apigateway-api-migration.md)。
+ 如果您將 API 的端點類型從私有移轉至區域，則您必須將 IP 位址類型設為雙堆疊。端點移轉完成後，您可以將 IP 位址類型變更為 IPv4。如需更多詳細資訊，請參閱 [在 API Gateway 中變更公有或私有 API 端點類型](apigateway-api-migration.md)。
+ 您的 API 可以對應至與您的 API 具有不同 IP 位址類型的自訂網域名稱。如果您停用預設 API 端點，則可能會影響呼叫方調用 API 的方式。
+ 您無法使用外部定義檔案來設定 API 的 IP 位址類型。

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

您可以藉由更新 API 的組態來變更 IP 位址類型。您可以使用 AWS 管理主控台、AWS CLI、CloudFormation 或 AWS SDK 來更新 API 的組態。如果您變更 API 的 IP 位址類型，您不需重新部署 API 讓變更生效。在您變更 IP 位址類型之前，請先確認控制存取 API 的任何政策都已更新，以便進行 IPv6 呼叫。

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

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

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

1. 選擇 REST API。

1. 選擇 **API 設定**，然後選擇**編輯**。

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

1. 選擇**儲存變更**。

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

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

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

```
aws apigateway update-rest-api \
    --rest-api-id abcd1234 \
    --patch-operations "op='replace',path='/endpointConfiguration/ipAddressType',value='dualstack'"
```

輸出將如下所示：

```
{
    "id": "abcd1234",
    "name": "MyAPI",
    "description": "My API with a dualstack IP address type",
    "createdDate": "2025-02-04T11:47:06-08:00",
    "apiKeySource": "HEADER",
    "endpointConfiguration": {
        "types": [
            "REGIONAL"
        ],
        "ipAddressType": "dualstack"
    },
    "tags": {},
    "disableExecuteApiEndpoint": false,
    "rootResourceId": "efg456"
}
```

------

# API Gateway 中 REST API 的方法
<a name="how-to-method-settings"></a>

 在 API Gateway 中，API 方法包含[方法請求](https://docs.aws.amazon.com/apigateway/latest/api/API_Method.html)與[方法回應](https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html)。您可以設定 API 方法，來定義用戶端應該或必須執行才能提交請求以存取後端服務的操作，以及定義用戶端接著會收到的回應。輸入時，您可以選擇方法請求參數或適用的承載，讓用戶端在執行階段提供必要或選用的資料。輸出時，您會決定方法回應狀態碼、標頭與適用的本文，以作為後端回應資料映射的目標，再將這些目標傳回用戶端。為了協助用戶端開發人員了解您的 API 行為以及輸入與輸出格式，您可以[記錄您的 API](api-gateway-documenting-api.md) 並提供有關[無效的請求](api-gateway-method-request-validation.md)[的適當錯誤訊息](api-gateway-gatewayResponse-definition.md#customize-gateway-responses)。

API 方法請求是 HTTP 請求。若要設定方法請求，請設定 HTTP 方法 (或動詞)、API [資源](https://docs.aws.amazon.com/apigateway/latest/api/API_Resource.html)的路徑、標頭、適用的查詢字串參數。當 HTTP 方法是 `POST`、`PUT` 或 `PATCH` 時，您也會設定承載。例如，若要使用 [PetStore 範例 API](api-gateway-create-api-from-example.md) 擷取寵物，請定義 `GET /pets/{petId}` 的 API 方法請求，其中 `{petId}` 是可在執行階段接受一個數值的路徑參數。

```
GET /pets/1
Host: apigateway.us-east-1.amazonaws.com
...
```

如果用戶端指定不正確的路徑，例如 `/pet/1` 或 `/pets/one` 而不是 `/pets/1`，則會擲回例外狀況。

API 方法回應是指定狀態碼的 HTTP 回應。對於非代理整合，您必須設定方法回應來指定映射的必要或選用目標。這會將整合回應標頭或本文轉換成相關聯的方法回應標頭或本文。映射可以像[身分轉換](https://en.wikipedia.org/wiki/Identity_transform)一樣簡單，該轉換會依原狀透過整合來傳遞標頭或內文。例如，下列 `200` 方法回應顯示依現狀傳遞成功整合回應的範例。

```
200 OK 
Content-Type: application/json
...

{
    "id": "1",
    "type": "dog",
    "price": "$249.99"
}
```

基本上，您可以定義對應到後端之特定回應的方法回應。一般而言，這涉及任何 2XX、4XX 與 5XX 回應。不過，這可能不可行，因為您通常不太可能會事先知道後端可能傳回的所有回應。實際操作時，您可以指定一個方法回應作為預設值，處理來自後端之不明或未映射的回應。您最好指定 500 回應做為預設值。在任何情況下，您都必須為非代理整合設定至少一個方法回應。否則，API Gateway 會將 500 錯誤回應傳回用戶端，即使請求在後端成功也一樣。

 若要讓您的 API 支援強型別開發套件 (例如 Java 開發套件)，您應該定義方法請求輸入的資料模型，並定義方法回應輸出的資料模型。

## 先決條件
<a name="method-setting-prerequisites"></a>

設定 API 方法之前，請驗證下列項目：
+ 您必須在 API Gateway 中有可用的方法。請遵循中的說明進行[教學：建立具有 HTTP 非代理整合的 REST API](api-gateway-create-api-step-by-step.md)
+ 如果您想要讓方法與 Lambda 函數通訊，您必須已在 IAM 中建立 Lambda 呼叫角色與 Lambda 執行角色。您也必須已建立 Lambda 函數與您要在 AWS Lambda中用來通訊的方法。若要建立角色與函數，請使用[選擇 AWS Lambda 整合教學課程](getting-started-with-lambda-integration.md) 之[為 Lambda 非代理整合建立 Lambda 函數](getting-started-lambda-non-proxy-integration.md#getting-started-new-lambda)中的說明。
+ 如果您想要讓方法與 HTTP 或 HTTP 代理整合通訊，您必須已建立方法將用來通訊的 HTTP 端點 URL 並具備其存取權。
+  確認 API Gateway 是否支援 HTTP 與 HTTP 代理端點的憑證。如需詳細資訊，請參閱 [在 API Gateway 中，API Gateway 支援的 HTTP 與 HTTP 代理整合憑證授權單位](api-gateway-supported-certificate-authorities-for-http-endpoints.md)。

**Topics**
+ [先決條件](#method-setting-prerequisites)
+ [在 API Gateway 中設定方法請求](api-gateway-method-settings-method-request.md)
+ [在 API Gateway 中設定方法回應](api-gateway-method-settings-method-response.md)
+ [使用 API Gateway 主控台設定方法](how-to-set-up-method-using-console.md)

# 在 API Gateway 中設定方法請求
<a name="api-gateway-method-settings-method-request"></a>

設定方法請求需要在建立 [RestApi](https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html) 資源之後執行下列任務：

1.  建立新的 API 或選擇現有的 API [資源](https://docs.aws.amazon.com/apigateway/latest/api/API_Resource.html)實體。

1.  在新的或選擇的 API `Resource` 上，建立 API [方法](https://docs.aws.amazon.com/apigateway/latest/api/API_Method.html)資源 (也就是特定 HTTP 動詞)。這項作業可進一步分為下列子任務：
   +  將 HTTP 方法新增至方法請求
   +  設定請求參數
   +  定義請求本文的模型
   +  制定授權配置
   +  啟用請求驗證 

您可以使用下列方法來執行這些任務：
+  [API Gateway 主控台](how-to-set-up-method-using-console.md#how-to-method-settings-callers-console)
+  AWS CLI 命令 ([create-resource](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-resource.html) 和 [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html))
+  AWS SDK 函數 （例如，在 Node.js 中，[createResource](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/APIGateway.html#createResource-property) 和 [putMethod](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/APIGateway.html#putMethod-property))
+  API Gateway REST API ([resource:create](https://docs.aws.amazon.com/apigateway/latest/api/API_CreateResource.html) 與 [method:put](https://docs.aws.amazon.com/apigateway/latest/api/API_PutMethod.html))。

**Topics**
+ [設定 API 資源](#setup-method-resources)
+ [設定 HTTP 方法](#setup-method-add-http-method)
+ [設定方法請求參數](#setup-method-request-parameters)
+ [設定方法請求模型](#setup-method-request-model)
+ [設定方法請求授權](#setup-method-request-authorization)
+ [設定方法請求驗證](#setup-method-request-validation)

## 設定 API 資源
<a name="setup-method-resources"></a>

在 API Gateway API 中，您可以將可定址的資源公開為 API [資源](https://docs.aws.amazon.com/apigateway/latest/api/API_GetResources.html)實體的樹狀目錄，其根資源 (`/`) 在階層的最上層。此根資源與 API 的基底 URL 相關，其中包含 API 端點與階段名稱。在 API Gateway 主控台中，此基底 URI 稱為 **Invoke URI (呼叫 URI)**，並會在部署 API 之後顯示在 API 的階段編輯器中。

API 端點可以是預設主機名稱或自訂網域名稱。預設主機名稱的格式如下：

```
{api-id}.execute-api.{region}.amazonaws.com
```

在此格式中，*\$1api-id\$1* 表示 API Gateway 所產生的 API 識別符。`{region}` 變數表示您在建立 API 時選擇的 AWS 區域 (例如 `us-east-1`)。自訂網域名稱是有效網際網路網域下的任何使用者易記名稱。例如，如果您已註冊網際網路網域 `example.com`，任何 `*.example.com` 都是有效的自訂網域名稱。如需詳細資訊，請參閱[建立自訂網域名稱](how-to-custom-domains.md)。

以 [PetStore 範例 API](api-gateway-create-api-from-example.md) 而言，根資源 (`/`) 會公開寵物店。`/pets` 資源表示寵物店中可用的寵物集合。`/pets/{petId}` 會公開指定識別符 (`petId`) 的個別寵物。`{petId}` 的路徑參數是請求參數的一部分。

若要設定 API 資源，您可以選擇現有資源作為其父系，然後在此父資源下建立子資源。您一開始會以根資源作為父系，然後將資源新增至此父系，再將另一項資源新增至此子資源作為新的父系，依此類推直到新增至其父識別符。然後，您可以將具名資源新增至父系。

以下 [get-resources](https://docs.aws.amazon.com/cli/latest/reference/apigateway/get-resources.html) 命令會擷取 API 的所有資源：

```
aws apigateway get-resources --rest-api-id apiId
```

在 PetStore 範例 API 中，輸出如下所示：

```
{
    "items": [
        {
            "path": "/pets", 
            "resourceMethods": {
                "GET": {}
            }, 
            "id": "6sxz2j", 
            "pathPart": "pets", 
            "parentId": "svzr2028x8"
        }, 
        {
            "path": "/pets/{petId}", 
            "resourceMethods": {
                "GET": {}
            }, 
            "id": "rjkmth", 
            "pathPart": "{petId}", 
            "parentId": "6sxz2j"
        }, 
        {
            "path": "/", 
            "id": "svzr2028x8"
        }
    ]
}
```

每個項目會列出資源的識別符 (`id`)、其直屬父系 (`parentId`) (根資源除外)，以及資源名稱 (`pathPart`)。根資源是特殊的，因為它沒有任何父系。選擇某個資源作為父資源之後，使用下列命令來新增子資源：

```
aws apigateway create-resource --rest-api-id apiId \
    --parent-id parentId \
    --path-part resourceName
```

例如，若要在 PetStore 網站上新增販售的寵物食品，請使用下列命令：

```
aws apigateway create-resource --rest-api-id a1b2c3 \
    --parent-id svzr2028x8 \
    --path-part food
```

輸出將如下所示：

```
{
    "path": "/food", 
    "pathPart": "food", 
    "id": "xdsvhp", 
    "parentId": "svzr2028x8"
}
```

### 使用代理資源來簡化 API 設定
<a name="api-gateway-proxy-resource"></a>

隨著業務成長，PetStore 擁有者可能會決定新增食品、玩具與其他寵物相關項目來進行促銷。為了支援此目的，您可以在根資源下新增 `/food`、`/toys` 與其他資源。在每個銷售類別下，您可能還想要新增更多資源，例如 `/food/{type}/{item}`、`/toys/{type}/{item}` 等。這可能會變得很冗長。如果您決定將中介層 `{subtype}` 新增至資源路徑，以將路徑階層變更為 `/food/{type}/{subtype}/{item}`、`/toys/{type}/{subtype}/{item}` 等，變更會中斷現有的 API 設定。為了避免這種情況，您可以使用 API Gateway [代理資源](api-gateway-set-up-simple-proxy.md)一次完全公開一組 API 資源。

API Gateway 會將代理資源定義為要在提交請求時指定之資源的預留位置。代理資源是由 `{proxy+}` 的特殊路徑參數來表示，通常稱為 Greedy 路徑參數。`+` 符號指出要附加的子資源。`/parent/{proxy+}` 預留位置代表符合 `/parent/*` 之路徑模式的任何資源。您可以使用任何字串作為 greedy 路徑參數名稱。

以下 [create-resource](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-resource.html) 命令會在根目錄 (`/{proxy+}`) 下建立代理資源：

```
aws apigateway create-resource --rest-api-id apiId \
    --parent-id rootResourceId \
    --path-part {proxy+}
```

輸出將如下所示：

```
{
    "path": "/{proxy+}", 
    "pathPart": "{proxy+}", 
    "id": "234jdr", 
    "parentId": "svzr2028x8"
}
```

在 `PetStore` API 範例中，您可以使用 `/{proxy+}` 來表示 `/pets` 與 `/pets/{petId}`。此代理資源也可以參考其他任何 (現有或是要新增的) 資源，例如 `/food/{type}/{item}`、`/toys/{type}/{item}` 等，或是 `/food/{type}/{subtype}/{item}`、`/toys/{type}/{subtype}/{item}` 等。後端開發人員會決定資源階層，而用戶端開發人員則負責了解此階層。API Gateway 只會將用戶端提交的任何項目傳遞到後端。

一個 API 可以有多個代理資源。例如，API 中允許下列代理資源，假設 `/parent/{proxy+}` 和 `/parent/{child}/{proxy+}` 不在相同父系層級。

```
/{proxy+}
/parent/{proxy+}
/parent/{child}/{proxy+}
```

當代理資源有非代理同層級資源時，則會從代理資源的顯示方式中排除這些同層級資源。在上述範例中，`/{proxy+}` 是指根資源下除了 `/parent[/*]` 資源以外的任何資源。換言之，對特定資源提出的方法請求，會優先於對資源階層中同層級之一般資源提出的方法請求。

下表顯示 API Gateway 如何將請求路由至 API `prod` 階段的下列資源。

```
ANY /{proxy+}
GET /pets/{proxy+}
GET /pets/dog
```


| 請求 | 選取的路由 | 說明 | 
| --- | --- | --- | 
|  `GET https://api-id.execute-api.region.amazonaws.com/prod/pets/dog`  |  `GET /pets/dog`  |  請求與此資源完全相符。  | 
|  `GET https://api-id.execute-api.region.amazonaws.com/prod/pets/cats`  |  `GET /pets/{proxy+}`  |  `/pets/{proxy+}` greedy 路徑變數會擷取此請求。  | 
|  `GET https://api-id.execute-api.region.amazonaws.com/prod/animals`  |  `GET /{proxy+}`  |  `/{proxy+}` greedy 路徑變數會擷取此請求。  | 

代理資源不能有任何子資源。`{proxy+}` 後面的任何 API 資源是多餘且模棱兩可的。API 中不允許下列代理資源。

```
/{proxy+}/child
/parent/{proxy+}/{child}
/parent/{child}/{proxy+}/{grandchild+}
```

## 設定 HTTP 方法
<a name="setup-method-add-http-method"></a>

API 方法請求是由 API Gateway [方法](https://docs.aws.amazon.com/apigateway/latest/api/API_Method.html)資源所封裝。若要設定方法請求，您必須先具現化 `Method` 資源、設定至少一個 HTTP 方法，並在該方法上設定至少一種授權類型。

與代理資源密切相關的是，API Gateway 支援 HTTP 方法 `ANY`。此 `ANY` 方法代表要在執行階段提供的任何 HTTP 方法。它可讓您針對 `DELETE`、`GET`、`HEAD`、`OPTIONS`、`PATCH`、`POST` 與 `PUT` 之所有支援的 HTTP 方法，使用單一 API 方法設定。

您也可以在非代理資源上設定 `ANY` 方法。透過將 `ANY` 方法與代理資源合併，您就可以對 API 的任何資源，取得所有支援之 HTTP 方法的單一 API 方法設定。此外，後端可繼續發展而不需要中斷現有的 API 設定。

 設定 API 方法之前，請考慮誰可以呼叫此方法。請根據您的方案設定授權類型。如需開放式存取，請將其設定為 `NONE`。若要使用 IAM 許可，請將授權類型設定為 `AWS_IAM`。若要使用 Lambda 授權方函數，請將此屬性設定為 `CUSTOM`。若要使用 Amazon Cognito 使用者集區，請將授權類型設定為 `COGNITO_USER_POOLS`。

以下 [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) 命令會使用 IAM 許可建立 `ANY` 動詞的方法請求，以控制其存取。

```
aws apigateway put-method --rest-api-id vaz7da96z6 \
    --resource-id 6sxz2j \
    --http-method ANY \
    --authorization-type AWS_IAM
```

若要使用不同的授權類型來建立 API 方法請求，請參閱「[設定方法請求授權](#setup-method-request-authorization)」。

## 設定方法請求參數
<a name="setup-method-request-parameters"></a>

方法請求參數可讓用戶端提供完成方法請求所需的輸入資料或執行內容。方法參數可以是路徑參數、標頭或查詢字串參數。設定方法請求時，您必須宣告必要的請求參數以提供給用戶端。對於非代理整合，您可以將這些請求參數轉換成與後端需求相容的格式。

例如，對於 `GET /pets/{petId}` 方法請求，`{petId}` 路徑變數是必要的請求參數。您可以在呼叫 AWS CLI的 `put-method` 命令時宣告此路徑參數，以下 [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) 命令會建立方法與必要的路徑參數：

```
aws apigateway put-method --rest-api-id vaz7da96z6 \
    --resource-id rjkmth \
    --http-method GET \
    --authorization-type "NONE" \
    --request-parameters method.request.path.petId=true
```

如果不需要參數，您可以在 `false` 中將它設定為 `request-parameters`。例如，如果 `GET /pets` 方法使用選用的查詢字串參數 `type` 與選用的標頭參數 `age`，則您可以使用以下 [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) 命令來宣告這些參數：

```
aws apigateway put-method --rest-api-id vaz7da96z6 \
    --resource-id 6sxz2j \
    --http-method GET \
    --authorization-type "NONE" \
    --request-parameters method.request.querystring.type=false,method.request.header.age=false
```

除了此縮寫格式之外，您還可以使用 JSON 字串來設定 `request-parameters` 值：

```
'{"method.request.querystring.type":false,"method.request.header.age":false}'
```

有了這項設定，用戶端就可依類型查詢寵物：

```
GET /pets?type=dog
```

 而且用戶端可以查詢哪些狗是幼犬，如下所示：

```
GET /pets?type=dog
age:puppy
```

如需如何將方法請求參數映射到整合請求參數的資訊，請參閱「[API Gateway 中 REST API 的整合](how-to-integration-settings.md)」。

## 設定方法請求模型
<a name="setup-method-request-model"></a>

若要讓 API 方法可接受承載中的輸入資料，您可以使用模型。模型是以 [JSON 結構描述草稿第 4 版](https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04)來表示，並描述請求本文的資料結構。透過模型，用戶端可以判斷如何建構方法請求承載作為輸入。更重要的是，API Gateway 可使用模型來[驗證請求](api-gateway-method-request-validation.md)、[產生軟體開發套件](how-to-generate-sdk.md)，並初始化映射範本以在 API Gateway 主控台中設定整合。如需如何建立[模型](https://docs.aws.amazon.com/apigateway/latest/api/API_Model.html)的相關資訊，請參閱[了解資料模型](models-mappings-models.md)。

視內容類型而定，一個方法承載可能會有不同的格式。模型會針對已套用承載的媒體類型來編製索引。API Gateway 使用 `Content-Type` 請求標頭來確定內容類型。若要設定方法請求模型，請在呼叫 AWS CLI `put-method` 命令時，將`"media-type":"model-name"`格式的鍵值對新增至`requestModels`映射。

若要使用相同的模型，而不論內容類型為何，請指定 `$default` 為索引鍵。

例如，若要在 PetStore 範例 API 之 `POST /pets` 方法請求的 JSON 承載上設定模型，您可以使用以下 [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) 命令：

```
aws apigateway put-method \
    --rest-api-id vaz7da96z6 \
    --resource-id 6sxz2j \
    --http-method POST \
    --authorization-type "NONE" \
    --request-models '{"application/json":"petModel"}'
```

在此範例中，`petModel` 是描述寵物之 [https://docs.aws.amazon.com/apigateway/latest/api/API_Model.html](https://docs.aws.amazon.com/apigateway/latest/api/API_Model.html) 資源的 `Model` 屬性值。實際結構描述定義會以 `schema` 資源之 [https://docs.aws.amazon.com/apigateway/latest/api/API_Model.html#schema](https://docs.aws.amazon.com/apigateway/latest/api/API_Model.html#schema) 屬性的 JSON 字串值表示。

 在 API 的 Java 開發套件或其他強型別開發套件中，輸入資料會轉換成衍生自結構描述定義的 `petModel` 類別。透過請求模型，所產生之開發套件中的輸入資料會轉換成衍生自預設 `Empty` 模型的 `Empty` 類別。在本例中，用戶端無法具現化正確的資料類別以提供必要的輸入。



## 設定方法請求授權
<a name="setup-method-request-authorization"></a>



 若要控制誰可以呼叫 API 方法，您可以在方法上設定[授權類型](https://docs.aws.amazon.com/apigateway/latest/api/API_Method.html#authorizationType)。您可以使用此類型制定其中一個支援的授權方，包括 IAM 角色與政策 (`AWS_IAM`)、Amazon Cognito 使用者集區 (`COGNITO_USER_POOLS`) 或 Lambda 授權方 (`CUSTOM`)。

若要使用 IAM 許可來授權存取 API 方法，請將 `authorization-type` 輸入屬性設定為 **AWS\$1IAM**。在您設定此選項時，API Gateway 會根據發起人的憑證驗證發起人對要求的簽章。如果經驗證的使用者擁有呼叫方法的許可，則會接受請求。否則，請求會遭到拒絕，且發起人會收到未經授權的錯誤回應。除非發起人擁有呼叫 API 方法的許可，否則對方法的呼叫不會成功。以下 IAM 政策會向發起人授予呼叫在同一 AWS 帳戶中建立之任何 API 方法的許可：

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "execute-api:Invoke"
            ],
            "Resource": "arn:aws:execute-api:*:*:*"
        }
    ]
}
```

------

如需詳細資訊，請參閱[使用 IAM 許可權控制 REST API 的存取](permissions.md)。

目前，您只能將此政策授予 API 擁有者的 AWS 帳戶中的使用者、群組和角色。來自不同 的使用者只有在允許在 API 擁有者的 中擔任角色，並 AWS 帳戶 具有呼叫`execute-api:Invoke`動作的必要許可時， AWS 帳戶 才能呼叫 API 方法。如需跨帳戶許可的資訊，請參閱[使用 IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html)。

您可以使用 AWS AWS CLI開發套件或 REST API 用戶端，例如 [Postman](https://www.postman.com/)，其會實作 [Signature 第 4 版 (SigV4) 簽署](https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html)。

若要使用 Lambda 授權方來授權對 API 方法的存取，請將 `authorization-type` 輸入屬性設定為 `CUSTOM`，並將 [https://docs.aws.amazon.com/apigateway/latest/api/API_Method.html#authorizerId](https://docs.aws.amazon.com/apigateway/latest/api/API_Method.html#authorizerId) 輸入屬性設定為已存在之 Lambda 授權方的 [https://docs.aws.amazon.com/apigateway/latest/api/API_Authorizer.html#id](https://docs.aws.amazon.com/apigateway/latest/api/API_Authorizer.html#id) 屬性值。參考的 Lambda 授權方可以是 `TOKEN` 或 `REQUEST` 類型。如需建立 Lambda 授權方的資訊，請參閱[使用 API Gateway Lambda 授權方](apigateway-use-lambda-authorizer.md)。

若要使用 Amazon Cognito 使用者集區來授權對 API 方法的存取，請將 `authorization-type` 輸入屬性設定為 `COGNITO_USER_POOLS`，並將 [https://docs.aws.amazon.com/apigateway/latest/api/API_Method.html#authorizerId](https://docs.aws.amazon.com/apigateway/latest/api/API_Method.html#authorizerId) 輸入屬性設定為已建立之 `COGNITO_USER_POOLS` 授權方的 [https://docs.aws.amazon.com/apigateway/latest/api/API_Authorizer.html#id](https://docs.aws.amazon.com/apigateway/latest/api/API_Authorizer.html#id) 屬性值。如需有關建立 Amazon Cognito 使用者集區授權方的資訊，請參閱[使用 Amazon Cognito 使用者集區做為授權方，藉以控制對 REST API 的存取](apigateway-integrate-with-cognito.md)。

## 設定方法請求驗證
<a name="setup-method-request-validation"></a>

您可以在設定 API 方法請求時啟用請求驗證。您必須先建立[請求驗證程式](https://docs.aws.amazon.com/apigateway/latest/api/API_RequestValidator.html)。以下 [create-request-validator](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-request-validator.html) 命令會建立僅限內文的請求驗證程式。

```
aws apigateway create-request-validator \
    --rest-api-id 7zw9uyk9kl \
    --name bodyOnlyValidator \
    --validate-request-body  \
    --no-validate-request-parameters
```

輸出將如下所示：

```
{
    "validateRequestParameters": false, 
    "validateRequestBody": true, 
    "id": "jgpyy6", 
    "name": "bodyOnlyValidator"
}
```

只要使用此請求驗證程式，您就可以在設定方法請求時使用請求驗證。以下 [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) 命令會建立方法請求，以要求傳入的請求內文符合 `PetModel`，並且具有兩個非必要的請求參數：

```
aws apigateway put-method \
    --rest-api-id 7zw9uyk9kl \
    --resource-id xdsvhp \
    --http-method PUT \
    --authorization-type "NONE" \
    --request-parameters '{"method.request.querystring.type": false, "method.request.querystring.page":false}' \ 
    --request-models '{"application/json":"petModel"}' \
    --request-validator-id jgpyy6
```

若要將請求參數納入請求驗證中，您必須將請求驗證程式的 `validateRequestParameters` 設定為 `true`，並將 `put-method` 命令中的特定請求參數設定為 `true`。

# 在 API Gateway 中設定方法回應
<a name="api-gateway-method-settings-method-response"></a>

API 方法回應可封裝用戶端將會接收的 API 方法請求輸出。該輸出資料包含 HTTP 狀態碼、一些標頭，並可能包含本文。

透過非代理整合，指定的回應參數與本文可從相關聯的整合回應資料映射，或根據映射指派特定靜態值。這些映射是在整合回應中指定。此映射可以是依現狀傳遞整合回應的相同轉換。

透過代理整合，API Gateway 會自動將後端回應傳遞至方法回應。您不需要設定 API 方法回應。不過，若使用 Lambda 代理整合，Lambda 函數必須傳回[此輸出格式](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-output-format)的結果，API Gateway 才能成功將整合回應映射至方法回應。

就程式設計而言，此方法回應設定相當於建立 API Gateway 的 [MethodResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html) 資源，然後設定 [statusCode](https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html#statusCode)、[responseParameters](https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html#responseParameters) 與 [responseModels](https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html#responseModels) 的屬性。

設定 API 方法的狀態碼時，您應該選擇一個預設值，來處理非預期狀態碼的任何整合回應。您可以設定 `500` 作為預設值，因為此值相當於將未映射的回應轉換為伺服器端錯誤。為了進行說明，API Gateway 主控台設定 `200` 回應作為預設值。但您可以將它重設為 `500` 回應。

若要設定方法回應，您必須已建立方法請求。

## 設定方法回應狀態碼
<a name="setup-method-response-status-code"></a>

方法回應狀態碼可定義回應類型。例如，回應 200、400 與 500 分別表示成功、用戶端錯誤與伺服器端錯誤回應。

若要設定方法回應狀態碼，請將 [https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html#statusCode](https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html#statusCode) 屬性設定為 HTTP 狀態碼。以下 [put-method-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method-response.html) 命令會建立 `200` 方法回應。

```
aws apigateway put-method-response \
    --rest-api-id vaz7da96z6 \ 
    --resource-id 6sxz2j \
    --http-method GET \
    --status-code 200
```

## 設定方法回應參數
<a name="setup-method-response-parameters"></a>

方法回應參數可定義用戶端所收到以回應相關聯方法請求的標頭。回應參數也可根據 API 方法的整合回應中所指定的映射，來指定 API Gateway 映射整合回應參數的目標。

若要設定方法回應參數，請新增至 `responseParameters` 格式之 `MethodResponse` 索引鍵/值組的 [https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html#responseParameters](https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html#responseParameters) 映射。以下 [put-method-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method-response.html) 命令會設定 `my-header` 標頭。

```
aws apigateway put-method-response \
        --rest-api-id vaz7da96z6 \
        --resource-id 6sxz2j \
        --http-method GET \
        --status-code 200  \
        --response-parameters method.response.header.my-header=false
```

## 設定方法回應模型
<a name="setup-method-response-models"></a>

 

 方法回應模型可定義方法回應本文的格式。當您為 API 產生強型別開發套件時，需要設定方法回應模型。它可確保輸出在 Java 或 Objective-C 中轉換成適當的類別。在其他情況下，設定模型為選擇性。

設定回應模型之前，您必須先在 API Gateway 中建立模型。若要這樣做，您可以呼叫 `[create-model](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-model.html)` 命令。以下 [create-model](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-model.html) 命令會建立 `PetStorePet` 模型，以描述 `GET /pets/{petId}` 方法請求的回應內文。

```
aws apigateway create-model \
    --rest-api-id vaz7da96z6 \
    --content-type application/json \
    --name PetStorePet \
    --schema '{ \
                  "$schema": "http://json-schema.org/draft-04/schema#", \
                  "title": "PetStorePet", \
                  "type": "object", \
                  "properties": { \
                    "id": { "type": "number" }, \
                    "type": { "type": "string" }, \
                    "price": { "type": "number" } \
                  } \
              }'
```

結果會建立為 API Gateway [https://docs.aws.amazon.com/apigateway/latest/api/API_Model.html](https://docs.aws.amazon.com/apigateway/latest/api/API_Model.html) 資源。

若要設定方法回應模型來定義酬載格式，請將 "application/json":"PetStorePet" 鍵/值對新增至 [https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html](https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html) 資源的 [https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html#responseModels](https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html#responseModels) 映射。以下 [put-method-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method-response.html) 命令會建立使用回應模型來定義承載格式的方法回應：

```
aws apigateway put-method-response \
    --rest-api-id vaz7da96z6 \
    --resource-id 6sxz2j \
    --http-method GET \
    --status-code 200  \
    --response-parameters method.response.header.my-header=false \
    --response-models '{"application/json":"PetStorePet"}'
```

# 使用 API Gateway 主控台設定方法
<a name="how-to-set-up-method-using-console"></a>

當您使用 REST API 主控台建立方法時，可以同時設定整合請求和方法請求。根據預設，API Gateway 會為您的方法建立 `200` 方法回應。

下列指示顯示如何編輯方法請求設定，以及如何為您的方法建立其他方法回應。

**Topics**
+ [在 API Gateway 主控台編輯 API Gateway 方法請求](#how-to-method-settings-callers-console)
+ [使用 API Gateway 主控台設定 API Gateway 方法回應](#how-to-method-response-settings-console)

## 在 API Gateway 主控台編輯 API Gateway 方法請求
<a name="how-to-method-settings-callers-console"></a>

 這些說明假設您已建立方法請求。如需有關如何建立方法的詳細資訊，請參閱 [使用 API Gateway 主控台設定 API 整合請求](how-to-method-settings-console.md)。

1. 在**資源**窗格中，選擇您的方法，然後選擇**方法請求**標籤。

1. 在**方法請求設定**區段中，選擇**編輯**。

1. 針對**授權**，選取可用的授權方。

   1. 若要對任何使用者開放方法的存取權，請選取**無**。如果尚未變更預設設定，則可以略過此步驟。

   1. 若要使用 IAM 許可來控制用戶端對方法的存取權，請選取 `AWS_IAM`。使用此選項，只有連接正確 IAM 政策之 IAM 角色的使用者可以呼叫此方法。

      若要建立 IAM 角色，請使用類似如下的格式來指定存取政策：

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

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "execute-api:Invoke"
            ],
            "Resource": [
              "arn:aws:execute-api:us-east-1:111111111111:aaabbb/*/GET/"
            ]
          }
        ]
      }
      ```

------

      在此存取政策中，`arn:aws:execute-api:us-east-1:111111111111:aaabbb/*/GET/` 是方法的 ARN。您可以在**資源**頁面上選取方法，以尋找方法的 ARN。如需設定 IAM 許可的詳細資訊，請參閱[使用 IAM 許可權控制 REST API 的存取](permissions.md)。

      若要建立 IAM 角色，您可以調整下列教學課程 [為 Lambda 非代理整合建立 Lambda 函數](getting-started-lambda-non-proxy-integration.md#getting-started-new-lambda) 中的說明。

   1.  若要使用 Lambda 授權方，請選取權杖或請求授權方。請先建立 Lambda 授權方，下拉式選單中才會顯示此選項。如需如何建立 Lambda 授權方的資訊，請參閱[使用 API Gateway Lambda 授權方](apigateway-use-lambda-authorizer.md)。

   1.  若要使用 Amazon Cognito 使用者集區，請在 **Cognito user pool authorizers (Cognito 使用者集區授權方)** 下，選擇可用的使用者集區。在 Amazon Cognito 中建立使用者集區，並在 API Gateway 中建立 Amazon Cognito 使用者集區授權方，下拉式選單中才會顯示此選項。如需有關如何建立 Amazon Cognito 使用者集區授權方的資訊，請參閱[使用 Amazon Cognito 使用者集區做為授權方，藉以控制對 REST API 的存取](apigateway-integrate-with-cognito.md)。

1.  若要指定請求驗證，請從**請求驗證程式**下拉式選單中選取值。若要關閉請求驗證，請選取**無**。如需每個選項的詳細資訊，請參閱「[API Gateway 中的 REST API 的請求驗證](api-gateway-method-request-validation.md)」。

1. 選取**需要 API 金鑰**，以要求提供 API 金鑰。啟用時，可使用[用量方案](api-gateway-api-usage-plans.md)中的 API 金鑰來調節用戶端流量。

1. (選用) 若要在此 API 的 Java SDK 中指派 API Gateway 所產生的操作名稱，請在**操作名稱**中輸入名稱。例如，對於 `GET /pets/{petId}` 的方法請求，對應的 Java 開發套件操作名稱預設為 `GetPetsPetId`。此名稱是從方法的 HTTP 動詞 (`GET`) 以及資源路徑變數名稱 (`Pets` 與 `PetId`) 建構而來。如果您將操作名稱設定為 `getPetById`，開發套件操作名稱會變成 `GetPetById`。

1. 若要將查詢字串參數新增至方法，請執行下列動作：

   1. 選擇**URL 查詢字串參數**，然後選擇**新增查詢字串**。

   1. 針對**名稱**，輸入查詢字串參數的名稱。

   1. 若要使用新建立的查詢字串參數進行請求驗證，請選取**必要**。如需請求驗證的詳細資訊，請參閱「[API Gateway 中的 REST API 的請求驗證](api-gateway-method-request-validation.md)」。

   1. 若要將新建立的查詢字串參數當作快取金鑰的一部分來使用，請選取**快取**。如需快取的詳細資訊，請參閱「[使用方法或整合參數作為快取金鑰來編製快取回應的索引](api-gateway-caching.md#enable-api-gateway-cache-keys)」。

   若要移除查詢字串參數，請選擇**移除**。

1. 若要將標頭參數新增至方法，請執行下列操作：

   1. 選擇 **HTTP 請求標頭**，然後選擇**新增標頭**。

   1. 在**名稱**中，輸入標頭的名稱。

   1. 若要使用新建立的標頭進行請求驗證，請選取**必要**。如需請求驗證的詳細資訊，請參閱「[API Gateway 中的 REST API 的請求驗證](api-gateway-method-request-validation.md)」。

   1. 若要將新建立的標頭當作快取金鑰的一部分來使用，請選取**快取**。如需快取的詳細資訊，請參閱「[使用方法或整合參數作為快取金鑰來編製快取回應的索引](api-gateway-caching.md#enable-api-gateway-cache-keys)」。

   若要移除標頭，請選擇**移除**。

1.  若要使用 `POST`、`PUT` 或 `PATCH` HTTP 動詞來宣告方法請求的承載格式，請選擇**請求內文**，然後執行下列操作：

   1. 選擇 **Add model (新增模型)**。

   1. 針對**內容類型**，輸入 MIME 類型 (例如 `application/json`)。

   1. 對於**模型**，從下拉式選單中選取模型。目前 API 的可用模型包括預設的 `Empty` 與 `Error` 模型，以及您已建立並新增至 API 之[模型](https://docs.aws.amazon.com/apigateway/latest/api/API_Model.html)集合的任何模型。如需建立模型的詳細資訊，請參閱「[REST API 的資料模型](models-mappings-models.md)」。
**注意**  
 此模型可用來通知用戶端預期的承載資料格式。它對產生骨架映射範本很有幫助。請務必使用 Java、C\$1、Objective-C 與 Swift 等語言，來產生 API 的強型別開發套件。只有對承載啟用請求驗證時才需要這樣做。

1. 選擇**儲存**。

## 使用 API Gateway 主控台設定 API Gateway 方法回應
<a name="how-to-method-response-settings-console"></a>

 一個 API 方法可以有一或多個回應。每個回應是由其 HTTP 狀態碼編製索引。API Gateway 主控台預設會將 `200` 回應新增至方法回應。您可以修改它；例如，讓方法改為傳回 `201`。您可以新增其他回應；例如，`409` 表示拒絕存取，而 `500` 表示使用了未初始化的階段變數。

 若要使用 API Gateway 主控台來修改、刪除回應或將回應新增至 API 方法，請遵循下列說明進行。

1. 在**資源**窗格中，選擇您的方法，然後選擇**方法回應**標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

1. 在**方法回應設定**區段中，選擇**建立回應**。

1. 針對 **HPPT 狀態碼**，輸入 HTTP 狀態碼，例如 `200`、`400` 或 `500`。

    當後端傳回的回應未定義對應的方法回應時，API Gateway 無法將回應傳回至用戶端。相反地，它會傳回 `500 Internal server error` 錯誤回應。

1. 選擇**新增標頭**。

1.  在**標頭名稱**中輸入名稱。

    若要從後端傳回標頭至用戶端，請在方法回應中新增標頭。

1.  選擇**新增模型**，以定義方法回應內文的格式。

   針對**內容類型**輸入回應承載的媒體類型，然後從**模型**下拉式選單中選擇模型。

1. 選擇**儲存**。

若要修改現有回應，請瀏覽至您的方法回應，然後選擇**編輯**。若要變更 **HTTP 狀態碼**，請選擇**刪除**並建立新的方法回應。

對於從後端傳回的每個回應，您必須將相容的回應設定為方法回應。不過，除非您將結果從後端映射到方法回應，再傳回用戶端，否則設定方法回應標頭與承載模型為選擇性。此外，如果您想要為 API 產生強型別開發套件，方法回應承載模型就很重要。

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

API Gateway 支援多種機制來控制和管理 API 的存取。

您可以使用下列機制進行身分驗證和授權：
+ **資源政策**可讓您建立以資源為基礎的政策，以從指定的來源 IP 地址或 VPC 端點允許或拒絕存取您的 API 和方法。如需詳細資訊，請參閱[使用 API Gateway 資源政策來控制對 REST API 的存取](apigateway-resource-policies.md)。
+ **標準 AWS IAM 角色和政策**提供靈活且強大的存取控制，可套用至整個 API 或個別方法。您可以使用 IAM 角色和政策來控制誰可以建立和管理您的 API，以及誰可以呼叫它們。如需詳細資訊，請參閱[使用 IAM 許可權控制 REST API 的存取](permissions.md)。
+ **IAM 標籤**可搭配 IAM 政策一起用來控制存取。如需詳細資訊，請參閱[使用標籤來控制對 API Gateway REST API 資源的存取](apigateway-tagging-iam-policy.md)。
+ **界面 VPC 端點的端點政策**可讓您將 IAM 資源政策連接至界面 VPC 端點，以提高[私有 API](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-apis.html) 的安全性。如需詳細資訊，請參閱[在 API Gateway 中使用私有 API 的 VPC 端點政策](apigateway-vpc-endpoint-policies.md)。
+ **Lambda 授權方**是 Lambda 函數，其可使用承載字符身分驗證以及標頭、路徑、查詢字串、階段變數或上下文變數請求參數所述的資訊，控制 REST API 方法的存取。Lambda 授權方用來控制誰可以叫用 REST API 方法。如需詳細資訊，請參閱[使用 API Gateway Lambda 授權方](apigateway-use-lambda-authorizer.md)。
+ **Amazon Cognito 使用者集區**可讓您為 REST API 建立可自訂的身分驗證和授權解決方案。Amazon Cognito 使用者集區可用來控制誰可以叫用 REST API 方法。如需詳細資訊，請參閱[使用 Amazon Cognito 使用者集區做為授權方，藉以控制對 REST API 的存取](apigateway-integrate-with-cognito.md)。

您可以使用以下機制來執行其他與存取控制相關的任務：
+ **跨來源資源共享 (CORS)** 可讓您控制 REST API 回應跨網域資源請求的方式。如需詳細資訊，請參閱[API Gateway 中 REST API 的 CORS](how-to-cors.md)。
+ **用戶端 SSL 憑證**可用來驗證對後端系統的 HTTP 請求是否來自 API Gateway。如需詳細資訊，請參閱[在 API Gateway 中產生和設定後端驗證的 SSL 憑證](getting-started-client-side-ssl-authentication.md)。
+ **AWS WAF** 可用來保護您的 API Gateway API 免受常見的網路攻擊。如需詳細資訊，請參閱[使用 AWS WAF 來保護 API Gateway APIs 中的 REST API](apigateway-control-access-aws-waf.md)。

您可以使用以下機制來追蹤和限制您已授與授權用戶端之存取：
+ **用量計劃**可讓您將 **API 金鑰**提供給您的客戶，然後為每個 API 金鑰追蹤和限制 API 階段和方法的用量。如需詳細資訊，請參閱[API Gateway 中 REST API 的用量計畫和 API 金鑰](api-gateway-api-usage-plans.md)。

# 使用 API Gateway 資源政策來控制對 REST API 的存取
<a name="apigateway-resource-policies"></a>

Amazon API Gateway *資源政策*為連接到 API 的 JSON 政策文件，以控制指定的委託人 (通常是 IAM 角色或群組) 是否可以叫用 API。您可以使用 API Gateway 資源政策，允許您的 API 由以下來源安全地呼叫：
+ 來自指定 AWS 帳戶的使用者。
+ 指定來源 IP 地址範圍或 CIDR 區塊。
+ 指定 Virtual Private Cloud (VPC) 或 VPC 端點 (在任何帳戶)。

您可以使用 、 AWS CLI 或 AWS SDKs AWS 管理主控台，在 API Gateway 中連接任何 API 端點類型的資源政策。處理[私有 API](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-apis.html) 時，您可以將資源政策與 VPC 端點政策搭配使用，藉此控制能具備存取權限的委託人，以及其可存取的資源和動作。如需詳細資訊，請參閱[在 API Gateway 中使用私有 API 的 VPC 端點政策](apigateway-vpc-endpoint-policies.md)。

 API Gateway 資源政策與 IAM 身分政策不同。IAM 身分政策會連接到 IAM 使用者、群組或角色，並定義這些身分能對哪些資源執行什麼動作。API Gateway 資源政策連接至資源。您可以使用 API Gateway 資源政策搭配 IAM 政策。如需更多詳細資訊，請參閱 [以身份為基礎和以資源為基礎的政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_identity-vs-resource.html)。

**Topics**
+ [Amazon API Gateway 的存取原則語言概觀](apigateway-control-access-policy-language-overview.md)
+ [API Gateway 資源政策如何影響授權工作流程](apigateway-authorization-flow.md)
+ [API Gateway 資源政策範例](apigateway-resource-policies-examples.md)
+ [建立 API Gateway 資源政策並連接至 API](apigateway-resource-policies-create-attach.md)
+ [AWS 可用於 API Gateway 資源政策的條件索引鍵](apigateway-resource-policies-aws-condition-keys.md)

# Amazon API Gateway 的存取原則語言概觀
<a name="apigateway-control-access-policy-language-overview"></a>

本頁說明 Amazon API Gateway 資源政策中使用的基本元素。

資源政策是使用與 IAM 政策相同的語法來進行指定。如需完整的政策語言資訊，請參閱 *IAM 使用者指南*中的 [IAM 政策概觀](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html)和 [AWS Identity and Access Management 政策參考](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html)。

如需有關 AWS 服務如何決定是否應允許或拒絕特定請求的資訊，請參閱[決定是否允許或拒絕請求](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow)。

## 存取政策中的常用元素
<a name="apigateway-common-elements-in-an-access-policy"></a>

就其最基本意義而言，資源政策包含下列元素：
+ **資源** – API 是您可允許或拒絕許可的 Amazon API Gateway 資源。在政策中，您可以使用 Amazon Resource Name (ARN) 來識別資源。您也可以使用縮寫語法，當您儲存資源政策時，API Gateway 語法會自動將它展開為完整 ARN。如需詳細資訊，請參閱 [API Gateway 資源政策範例](apigateway-resource-policies-examples.md)。

  如需完整 `Resource` 元素的格式，請參閱[在 API Gateway 中執行 API 之許可的資源格式](api-gateway-control-access-using-iam-policies-to-invoke-api.md#api-gateway-iam-policy-resource-format-for-executing-api)。
+ **動作** - 針對每個資源，Amazon API Gateway 皆支援一組操作。您可使用動作關鍵字，來識別允許 (或拒絕) 資源操作。

  例如，`execute-api:Invoke` 許可讓使用者在使用者請求時有權叫用 API。

  如需 `Action` 元素的格式，請參閱 [在 API Gateway 中執行 API 之許可的動作格式](api-gateway-control-access-using-iam-policies-to-invoke-api.md#api-gateway-iam-policy-action-format-for-executing-api)。
+ **效果** - 當使用者請求特定動作時會有什麼效果，它可以是 `Allow` 或 `Deny`。您也可以明確拒絕存取資源，您可能會這樣做，以確保使用者無法存取資源，即使另有其他政策授予存取。
**注意**  
「隱含拒絕」與「預設拒絕」是相同的。  
「隱含拒絕」與「明確拒絕」不同。如需詳細資訊，請參閱[預設拒絕與明確拒絕間的差異](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#AccessPolicyLanguage_Interplay)。
+ **委託人** - 允許存取陳述式中動作與資源的帳戶或使用者。在資源政策中，委託人是接收此許可的使用者或帳戶。

下列範例資源政策會顯示先前的常用政策元素。此政策會將指定*區域*中指定 *account-id* 下 API 的存取權，授與其來源 IP 地址是在地址區塊 *123.4.5.6/24* 中的任何使用者。如果使用者的來源 IP 不在範圍內，則政策會拒絕所有對 API 的存取。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:111111111111:*"
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:111111111111:*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": "123.4.5.6/24"
                }
            }
        }
    ]
}
```

------

# API Gateway 資源政策如何影響授權工作流程
<a name="apigateway-authorization-flow"></a>

API Gateway 評估連接到您 API 的資源政策時，其結果會受到您為 API 定義的身分驗證類型所影響，如下節流程圖所示。

**Topics**
+ [僅限 API Gateway 資源政策](#apigateway-authorization-flow-resource-policy-only)
+ [Lambda 授權方和資源政策](#apigateway-authorization-flow-lambda)
+ [IAM 身分驗證和資源政策](#apigateway-authorization-flow-iam)
+ [Amazon Cognito 身分驗證和資源政策](#apigateway-authorization-flow-cognito)
+ [政策評估結果表](#apigateway-resource-policies-iam-policies-interaction)

## 僅限 API Gateway 資源政策
<a name="apigateway-authorization-flow-resource-policy-only"></a>

在此工作流程中，API Gateway 資源政策連接到 API，但未替 API 定義身分驗證類型。評估政策涉及根據呼叫者的傳入條件來尋求明確允許。隱含拒絕或任何明確拒絕會導致拒絕呼叫者。

![\[僅限資源政策的授權流程。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/apigateway-auth-resource-policy-only.png)


以下是這種資源政策的範例。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:111111111111:api-id/",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": ["192.0.2.0/24", "198.51.100.0/24" ]
                }
            }
        }
    ]
}
```

------

## Lambda 授權方和資源政策
<a name="apigateway-authorization-flow-lambda"></a>

在此工作流程中，除了資源政策，也為 API 設定 Lambda 授權方。資源政策將以兩個階段評估。在呼叫 Lambda 授權方之前，API Gateway 會先評估政策並檢查是否有任何明確的拒絕。若有找到，會立即拒絕呼叫者存取。否則，會呼叫 Lambda 授權方，而它將會傳回[政策文件](api-gateway-lambda-authorizer-output.md)，並與資源政策一起評估。如果您的授權方使用快取，API Gateway 可能會傳回快取的政策文件。結果會根據[表 A](#apigateway-resource-policies-iam-policies-interaction) 來判斷。

以下資源政策範例僅允許來自 VPC 端點 ID 為 `vpce-1a2b3c4d` 之 VPC 端點的呼叫。在預先授權評估期間，只會允許範例中來自以下指定之 VPC 端點的呼叫前進並評估 Lambda 授權方。所有剩餘的呼叫都會遭到封鎖。如果您針對私有 API 使用自訂網域名稱，則此授權工作流程相同。

![\[資源政策和 Lambda 授權方的授權流程。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/apigateway-auth-lambda-resource-policy.png)


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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "arn:aws:execute-api:us-east-1:111111111111:api-id/"
            ],
            "Condition" : {
                "StringNotEquals": {
                    "aws:SourceVpce": "vpce-1a2b3c4d"
                }
            }
        }
    ]
}
```

------

## IAM 身分驗證和資源政策
<a name="apigateway-authorization-flow-iam"></a>

在此工作流程中，除了資源政策外，您也會為 API 設定 IAM 身分驗證。在您使用 IAM 服務對使用者進行身份驗證後，API 會評估連接到使用者的政策和資源政策。結果會根據發起人是位於 AWS 帳戶與 API 擁有者相同的 AWS 帳戶 還是單獨的 而有所不同。

如果發起人和 API 擁有者來自不同的帳戶，IAM 政策和資源政策都需明確允許發起人繼續。如需更多詳細資訊，請參閱[表 B](#apigateway-resource-policies-iam-policies-interaction)。

然而，如果發起人和 API 擁有者位於相同的 AWS 帳戶，則 IAM 使用者政策或資源政策必須明確允許發起人繼續。如需更多詳細資訊，請參閱[表 A](#apigateway-resource-policies-iam-policies-interaction)。

![\[資源政策和 IAM 驗證的授權流程。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/apigateway-auth-iam-resource-policy.png)


以下是跨帳戶資源政策的範例。假設 IAM 政策包含允許效果，則該資源政策僅允許來自 VPC ID 為 `vpc-2f09a348` 的 VPC 的呼叫。如需更多詳細資訊，請參閱[表 B](#apigateway-resource-policies-iam-policies-interaction)。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "arn:aws:execute-api:us-east-1:111111111111:api-id/"
            ],
            "Condition" : {
                "StringEquals": {
                    "aws:SourceVpc": "vpc-2f09a348"
                    }
            }
        }
    ]
}
```

------

## Amazon Cognito 身分驗證和資源政策
<a name="apigateway-authorization-flow-cognito"></a>

在此工作流程中，除了資源政策之外，還會為 API 設定 [Amazon Cognito 使用者集區](apigateway-integrate-with-cognito.md)。API Gateway 會先嘗試透過 Amazon Cognito 驗證發起人。這通常會透過發起人提供的 [JWT 字符](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html)來執行。如果身分驗證成功，則會獨立評估資源政策，並需要明確允許。拒絕或既不允許也不拒絕會產生拒絕。以下是可搭配 Amazon Cognito 使用者集區使用的資源政策範例。

![\[資源政策和 Amazon Cognito 授權方的授權流程。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/apigateway-auth-cognito-resource-policy.png)


以下是僅允許來自指定來源 IP 之呼叫的資源政策範例，其中假設 Amazon Cognito 身分驗證字符包含 Allow (允許)。如需更多詳細資訊，請參閱[表 B](#apigateway-resource-policies-iam-policies-interaction)。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": "arn:aws:execute-api:us-east-1:111111111111:api-id/",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": ["192.0.2.0/24", "198.51.100.0/24" ]
                }
            }
        }
    ]
}
```

------

## 政策評估結果表
<a name="apigateway-resource-policies-iam-policies-interaction"></a>

表 A 列出對 API Gateway API 的存取是由 IAM 政策或 Lambda 授權方以及 API Gateway 資源政策控制 (這兩者位於相同的 AWS 帳戶中) 時，所產生的行為。


| **IAM 政策 (或 Lambda 授權方)** | **API Gateway 資源政策** | **產生行為** | 
| --- | --- | --- | 
| Allow | Allow | Allow | 
| Allow | 不允許也不拒絕 | Allow | 
| Allow | 拒絕 | 明確拒絕 | 
| 不允許也不拒絕 | Allow | Allow | 
| 不允許也不拒絕 | 不允許也不拒絕 | 隱含拒絕 | 
| 不允許也不拒絕 | 拒絕 | 明確拒絕 | 
| 拒絕 | Allow | 明確拒絕 | 
| 拒絕 | 不允許也不拒絕 | 明確拒絕 | 
| 拒絕 | 拒絕 | 明確拒絕 | 

表 B 列出 API Gateway API 的存取是由 IAM 政策或 Amazon Cognito 使用者集區授權方和 API Gateway 資源政策控制時所產生的行為，這些政策位於不同位置 AWS 帳戶。如果其中一個無訊息 (不允許也不拒絕)，則會拒絕跨帳戶存取。這是因為跨帳戶存取權需要資源政策和 IAM 政策或 Amazon Cognito 使用者集區授權方明確授與存取權。


| **IAM 政策 (或 Amazon Cognito 使用者集區授權方)** | **API Gateway 資源政策** | **產生行為** | 
| --- | --- | --- | 
| Allow | Allow | Allow | 
| Allow | 不允許也不拒絕 | 隱含拒絕 | 
| Allow | 拒絕 | 明確拒絕 | 
| 不允許也不拒絕 | Allow | 隱含拒絕 | 
| 不允許也不拒絕 | 不允許也不拒絕 | 隱含拒絕 | 
| 不允許也不拒絕 | 拒絕 | 明確拒絕 | 
| 拒絕 | Allow | 明確拒絕 | 
| 拒絕 | 不允許也不拒絕 | 明確拒絕 | 
| 拒絕 | 拒絕 | 明確拒絕 | 

# API Gateway 資源政策範例
<a name="apigateway-resource-policies-examples"></a>

本頁面顯示 API Gateway 資源政策之一般使用案例的一些範例。

下列範例政策使用簡化的語法來指定 API 資源。這種簡化的語法是您可以參考 API 資源的縮寫方式，而不是指定完整的 Amazon Resource Name (ARN)。當您儲存政策時，API Gateway 會將縮寫的語法轉換為完整的 ARN。例如，您可以在資源政策中指定資源 `execute-api:/stage-name/GET/pets`。當您儲存資源政策時，API Gateway 會將資源轉換為 `arn:aws:execute-api:us-east-2:123456789012:aabbccddee/stage-name/GET/pets`。API Gateway 會使用目前的區域、 AWS 您的帳戶 ID 和與資源政策相關聯的 REST API ID 來建置完整的 ARN。您可以使用 `execute-api:/*` 來表示目前 API 中的所有階段、方法和路徑。如需存取原則語言的詳細資訊，請參閱 [Amazon API Gateway 的存取原則語言概觀](apigateway-control-access-policy-language-overview.md)。

**Topics**
+ [範例：允許另一個 AWS 帳戶中的角色使用 API](#apigateway-resource-policies-cross-account-example)
+ [範例：拒絕根據來源 IP 地址或範圍的 API 流量](#apigateway-resource-policies-source-ip-address-example)
+ [範例：使用私有 API 時，根據來源 IP 位址或範圍拒絕 API 流量](#apigateway-resource-policies-source-ip-address-vpc-example)
+ [範例：允許以來源 VPC 或 VPC 端點為依據的私有 API 流量](#apigateway-resource-policies-source-vpc-example)

## 範例：允許另一個 AWS 帳戶中的角色使用 API
<a name="apigateway-resource-policies-cross-account-example"></a>

下列範例資源政策會透過 [Signature 第 4 ](https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html)版 (SigV4) 或 [Signature 第 4a 版](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html#how-sigv4a-works) (SigV4a) 通訊協定，將一個 AWS 帳戶中的 API 存取權授予不同 AWS 帳戶中的兩個角色。具體而言， 所識別 AWS 帳戶的開發人員和管理員角色`account-id-2`會獲授予 `execute-api:Invoke`動作，以對您 AWS 帳戶中`pets`的資源 (API) 執行 `GET`動作。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::111122223333:role/developer",
                    "arn:aws:iam::111122223333:role/Admin"
                ]
            },
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/stage/GET/pets"
            ]
        }
    ]
}
```

------

## 範例：拒絕根據來源 IP 地址或範圍的 API 流量
<a name="apigateway-resource-policies-source-ip-address-example"></a>

以下範例資源政策會拒絕 (封鎖) 從兩個指定的來源 IP 位址區塊傳入 API 流量。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
               "execute-api:/*"
            ],
            "Condition" : {
                "IpAddress": {
                    "aws:SourceIp": ["192.0.2.0/24", "198.51.100.0/24" ]
                }
            }
        }
    ]
}
```

------

如果您使用任何 IAM 使用者政策或 API Gateway 資源政策來控制 API Gateway 或任何 API Gateway API 的存取權，請確認您的政策已更新並包含 IPv6 位址範圍。若政策未更新，因而無法處理 IPv6 位址，則可能在用戶端開始使用雙堆疊端點時，影響用戶端對 API Gateway 的存取。如需詳細資訊，請參閱[在 IAM 原則中使用 IPv6 地址](api-ref.md#api-reference-service-endpoints-dualstack-iam)。

## 範例：使用私有 API 時，根據來源 IP 位址或範圍拒絕 API 流量
<a name="apigateway-resource-policies-source-ip-address-vpc-example"></a>

以下範例資源政策會拒絕 (封鎖) 從兩個指定的來源 IP 位址區塊傳入 API 流量。使用私有 API 時，`execute-api` 的 VPC 端點會重新寫入原始來源 IP 位址。`aws:VpcSourceIp` 條件會根據原始請求者 IP 位址篩選請求。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
               "execute-api:/*"
            ],
            "Condition" : {
                "IpAddress": {
                    "aws:VpcSourceIp": ["192.0.2.0/24", "198.51.100.0/24"]
                }
            }
        }
    ]
}
```

------

## 範例：允許以來源 VPC 或 VPC 端點為依據的私有 API 流量
<a name="apigateway-resource-policies-source-vpc-example"></a>

以下範例資源政策僅允許來自指定的 Virtual Private Cloud (VPC) 或 VPC 端點的流量傳入私有 API。

此範例資源政策會指定來源 VPC：

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ],
            "Condition" : {
                "StringNotEquals": {
                   "aws:SourceVpc": "vpc-1a2b3c4d"
                }
            }
        }
    ]
}
```

------

此範例資源政策會指定來源 VPC 端點：

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ]
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/*"
            ],
            "Condition" : {
                "StringNotEquals": {
                    "aws:SourceVpce": "vpce-1a2b3c4d"
                }
            }
        }
    ]
}
```

------

# 建立 API Gateway 資源政策並連接至 API
<a name="apigateway-resource-policies-create-attach"></a>

為了讓使用者透過呼叫 API 執行服務來存取您的 API，您必須建立 API Gateway 資源政策，並將政策連接到 API。當您將政策附加至 API，會將政策中的許可權套用至 API 中的方法。如果更新資源政策，您需要部署 API。

**Topics**
+ [先決條件](#apigateway-resource-policies-prerequisites)
+ [將資源政策連接至 API Gateway API](#apigateway-resource-policies-create-attach-procedure)
+ [為資源政策進行疑難排解](#apigateway-resource-policies-troubleshoot)

## 先決條件
<a name="apigateway-resource-policies-prerequisites"></a>

 若要更新 API Gateway 資源政策，您需要 `apigateway:UpdateRestApiPolicy` 許可和 `apigateway:PATCH` 許可。

對於邊緣最佳化的或區域 API，您可以在建立資源政策時或部署之後，將資源政策連接至 API。對於私有 API，您無法在沒有資源政策的情況下部署 API。如需詳細資訊，請參閱[API Gateway 中的私有 REST API](apigateway-private-apis.md)。

## 將資源政策連接至 API Gateway API
<a name="apigateway-resource-policies-create-attach-procedure"></a>

下列程序顯示如何將資源政策連接至 API Gateway API。

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

**將資源政策連接至 API Gateway API**

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

1. 選擇 REST API。

1. 在主導覽窗格中，選擇**資源政策**。

1. 選擇**建立政策**。

1. (選用) 選擇**選取範本**以產生範例政策。

   在範例政策中，預留位置位於雙大括號中 (`"{{placeholder}}"`)。將每個預留位置 (包括大括號) 取代為所需的資訊。

1. 如果您不使用其中一個範本範例，請輸入您的資源政策。

1. 選擇**儲存變更**。

如果先前已在 API Gateway 主控台中部署該 API，您將需要為資源政策重新部署 API，才能生效。

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

若要使用 AWS CLI 建立新的 API 並連接資源政策，請使用下列 [create-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-rest-api.html) 命令：

```
aws apigateway create-rest-api \
    --name "api-name" \
    --policy "{\"jsonEscapedPolicyDocument\"}"
```

若要使用 AWS CLI 將資源政策連接至現有的 API，請使用下列 [update-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-rest-api.html) 命令：

```
aws apigateway update-rest-api \
    --rest-api-id api-id \
    --patch-operations op=replace,path=/policy,value='"{\"jsonEscapedPolicyDocument\"}"'
```

您也可以將您的資源政策附加為不同的 `policy.json` 檔案，並將其包含在 [create-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-rest-api.html) 命令中。以下 [create-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-rest-api.html) 命令會建立具有資源政策的新 API：

```
aws apigateway create-rest-api \
    --name "api-name" \
    --policy file://policy.json
```

`policy.json` 是 API Gateway 資源政策，例如 [範例：拒絕根據來源 IP 地址或範圍的 API 流量](apigateway-resource-policies-examples.md#apigateway-resource-policies-source-ip-address-example)。

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

您可以使用 CloudFormation 建立具有資源政策的 API。下列範例會使用範例資源政策 [範例：拒絕根據來源 IP 地址或範圍的 API 流量](apigateway-resource-policies-examples.md#apigateway-resource-policies-source-ip-address-example) 建立 REST API。

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: testapi
      Policy:
        Statement:
          - Action: 'execute-api:Invoke'
            Effect: Allow
            Principal: '*'
            Resource: 'execute-api:/*'
          - Action: 'execute-api:Invoke'
            Effect: Deny
            Principal: '*'
            Resource: 'execute-api:/*'
            Condition:
              IpAddress: 
                'aws:SourceIp': ["192.0.2.0/24", "198.51.100.0/24" ]
        Version: 2012-10-17		 	 	 
  Resource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref Api
      ParentId: !GetAtt Api.RootResourceId
      PathPart: 'helloworld'
  MethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref Resource
      HttpMethod: GET
      ApiKeyRequired: false
      AuthorizationType: NONE
      Integration:
        Type: MOCK
        RequestTemplates:
          application/json: '{"statusCode": 200}'
        IntegrationResponses:
          - StatusCode: 200
            ResponseTemplates:
              application/json: '{}'
      MethodResponses:
        - StatusCode: 200
          ResponseModels:
            application/json: 'Empty'
  ApiDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn:
      - MethodGet
    Properties:
      RestApiId: !Ref Api
      StageName: test
```

------

## 為資源政策進行疑難排解
<a name="apigateway-resource-policies-troubleshoot"></a>

下列疑難排解指引可能有助於解決您的資源政策問題。

### 我的 API 傳回 \$1"Message":"User: anonymous is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-1:\$1\$1\$1\$1\$1\$1\$1\$1/\$1\$1\$1\$1/\$1\$1\$1\$1/"\$1
<a name="apigateway-resource-policies-troubleshoot-auth"></a>

在您的資源政策中，如果您將主體設定為 AWS 委託人，如下所示：

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::111111111111:role/developer",
                    "arn:aws:iam::111111111111:role/Admin"
                ]
            },
            "Action": "execute-api:Invoke",
            "Resource": [
                "execute-api:/stage/GET/pets"
            ]
        }
    ]
}
```

------

您必須對 API 中的每個方法使用 `AWS_IAM` 授權，否則您的 API 會傳回先前的錯誤訊息。如需有關如何為方法開啟 `AWS_IAM` 授權的詳細資訊，請參閱 [API Gateway 中 REST API 的方法](how-to-method-settings.md)。

### 我的資源政策未更新
<a name="apigateway-resource-policies-troubleshoot-deploy"></a>

 如果您在 API 建立後更新資源政策，您會需要部署 API 以在您連接更新的政策後傳播變更。單獨更新或儲存政策不會變更 API 的執行階段行為。如需部署 API 的詳細資訊，請參閱 [在 API Gateway 中部署 REST API](how-to-deploy-api.md)。

### 我的資源政策傳回下列錯誤：政策文件無效。請檢查政策語法，並確保主體有效。
<a name="apigateway-resource-policies-troubleshoot-invalid-principal"></a>

若要針對此錯誤進行疑難排解，建議您先檢查政策語法。如需詳細資訊，請參閱[Amazon API Gateway 的存取原則語言概觀](apigateway-control-access-policy-language-overview.md)。我們也建議您確認所有指定的主體是否有效，且尚未刪除。

此外，如果您的 API 位於[選擇加入區域](https://docs.aws.amazon.com/glossary/latest/reference/glos-chap.html?icmpid=docs_homepage_addtlrcs#optinregion)，請確認資源政策中的所有帳戶都已啟用區域。

# AWS 可用於 API Gateway 資源政策的條件索引鍵
<a name="apigateway-resource-policies-aws-condition-keys"></a>

下表包含 AWS 條件索引鍵，可用於 APIs Gateway 中每個授權類型的 API 資源政策。

如需 AWS 條件金鑰的詳細資訊，請參閱[AWS 全域條件內容金鑰](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html)。


| **條件索引鍵** | **條件** | **需要 `AuthN`？** | **授權類型** | 
| --- | --- | --- | --- | 
| aws:CurrentTime | 無 | 否 | 全部 | 
| aws:EpochTime | 無 | 否 | 全部 | 
| aws:TokenIssueTime | 金鑰僅在使用臨時安全登入資料簽署的要求中才會出現。 | 是 | IAM | 
| aws:MultiFactorAuthPresent | 金鑰僅在使用臨時安全登入資料簽署的要求中才會出現。 | 是 | IAM | 
| aws:MultiFactorAuthAge | 金鑰僅在 MFA 存在於請求時才會出現。 | 是 | IAM | 
| aws:PrincipalAccount | 無 | 是 | IAM | 
| aws:PrincipalArn | 無 | 是 | IAM | 
| aws:PrincipalOrgID | 只有在委託人是組織的成員時，請求內容中才會包含此金鑰。 | 是 | IAM | 
| aws:PrincipalOrgPaths | 只有在委託人是組織的成員時，請求內容中才會包含此金鑰。 | 是 | IAM | 
| aws:PrincipalTag | 若委託人搭配連接標籤使用 IAM 使用者，此鍵會包含在請求內容中。其會針對委託人，使用具備連接標籤或工作階段標籤的 IAM 角色包含在其中。 | 是 | IAM | 
| aws:PrincipalType | 無 | 是 | IAM | 
| aws:Referer | 金鑰僅在 HTTP 標頭中的呼叫者提供值時才會出現。 | 否 | 全部 | 
| aws:SecureTransport | 無 | 否 | 全部 | 
| aws:SourceArn | 無 | 否 | 全部 | 
| aws:SourceIp | 無 | 否 | 全部 | 
| aws:SourceVpc | 此金鑰只能用於私有 API。 | 否 | 全部 | 
| aws:SourceVpce | 此金鑰只能用於私有 API。 | 否 | 全部 | 
| aws:VpcSourceIp | 此金鑰只能用於私有 API。 | 否 | 全部 | 
| aws:UserAgent | 金鑰僅在 HTTP 標頭中的呼叫者提供值時才會出現。 | 否 | 全部 | 
| aws:userid | 無 | 是 | IAM | 
| aws:username | 無 | 是 | IAM | 

# 使用 IAM 許可權控制 REST API 的存取
<a name="permissions"></a>

 透過控制對下列兩個 API Gateway 元件程序的存取，您可以使用 [IAM 許可](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_controlling.html)控制對 Amazon API Gateway API 的存取：
+  若要在 API Gateway 中建立、部署及管理 API，您必須授予 API 開發人員許可來執行 API Gateway 之 API 管理元件支援的必要動作。
+  若要呼叫已部署的 API 或重新整理 API 快取，您必須授予 API 發起人許可來執行 API Gateway 的 API 執行元件支援的必要 IAM 動作。

 這兩個處理的存取控制需要不同的許可模型，以下將進行說明。

## 建立與管理 API 的 API Gateway 許可模型
<a name="api-gateway-control-access-iam-permissions-model-for-managing-api"></a>

 若要讓 API 開發人員在 API Gateway 中建立及管理 API，您必須[建立 IAM 許可政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html)，允許指定的 API 開發人員建立、更新、部署、檢視或刪除必要的 [API 實體](https://docs.aws.amazon.com/apigateway/latest/api/API_Resource.html)。您會將許可政策附加到使用者、角色或群組。

若要提供存取權，請新增權限至您的使用者、群組或角色：
+ 中的使用者和群組 AWS IAM Identity Center：

  建立權限合集。請按照《*AWS IAM Identity Center 使用者指南*》中的[建立權限合集](https://docs.aws.amazon.com//singlesignon/latest/userguide/howtocreatepermissionset.html)說明進行操作。
+ 透過身分提供者在 IAM 中管理的使用者：

  建立聯合身分的角色。遵循《*IAM 使用者指南*》的[為第三方身分提供者 (聯合) 建立角色](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_create_for-idp.html)中的指示。
+ IAM 使用者：
  + 建立您的使用者可擔任的角色。請按照《*IAM 使用者指南*》的[為 IAM 使用者建立角色](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_create_for-user.html)中的指示。
  + (不建議) 將政策直接附加至使用者，或將使用者新增至使用者群組。請遵循《*IAM 使用者指南*》的[新增許可到使用者 (主控台)](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_users_change-permissions.html#users_change_permissions-add-console) 中的指示。

如需如何使用此許可模型的詳細資訊，請參閱「[API Gateway 身分類型政策](security_iam_service-with-iam.md#security_iam_service-with-iam-id-based-policies)」。

## 用於呼叫 API 的 API Gateway 許可模型
<a name="api-gateway-control-access-iam-permissions-model-for-calling-api"></a>

若要讓 API 發起人呼叫 API 或重新整理其快取，您必須建立 IAM 政策，允許已啟用使用者身分驗證的指定 API 發起人呼叫 API 方法。API 開發人員可將方法的 `authorizationType` 屬性設定為 `AWS_IAM`，以要求發起人提交使用者的憑證以進行身份驗證。API Gateway 支援第 4a 版簽署程序 (SigV4a) 和第 4 版簽署程序 (SigV4) 來驗證使用者的憑證。如需詳細資訊，請參閱 [AWS 第 4 版簽署程序](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html)。然後您可以將政策連接至使用者、角色或群組。

在此 IAM 許可政策陳述式中，IAM `Resource` 元素包含指定 HTTP 動詞與 API Gateway [資源路徑](https://docs.aws.amazon.com/apigateway/latest/api/API_Resource.html)所識別的已部署 API 方法清單。IAM `Action` 元素包含必要的 API Gateway API 執行動作。這些動作包含 `execute-api:Invoke` 或 `execute-api:InvalidateCache`，其中 `execute-api` 指定 API Gateway 的基礎 API 執行元件。

如需如何使用此許可模型的詳細資訊，請參閱「[控制對 API 的呼叫存取權](api-gateway-control-access-using-iam-policies-to-invoke-api.md)」。

 當 API 在後端與 AWS 服務 （例如， AWS Lambda) 整合時，API Gateway 也必須具有代表 API 發起人存取整合 AWS 資源 （例如，叫用 Lambda 函數） 的許可。若要授予這些許可，請建立**適用於 API Gateway 的AWS 服務**類型的 IAM 角色。當您在 IAM 管理主控台建立此角色時，所產生的角色會包含下列 IAM 信任政策，其中宣告 API Gateway 是允許擔任該角色的受信任實體：

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "apigateway.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

如果您藉由呼叫 [create-role](https://docs.aws.amazon.com/cli/latest/reference/iam/create-role.html) 的 CLI 命令或是藉由對應的軟體開發套件方法來建立 IAM 角色，則您必須將 `assume-role-policy-document` 的輸入參數提供給上述政策。請勿嘗試直接在 IAM 管理主控台或 calling AWS CLI [create-policy](https://docs.aws.amazon.com/cli/latest/reference/iam/create-policy.html) 命令或對應的 SDK 方法中建立此類政策。

若要讓 API Gateway 呼叫整合 AWS 服務，您還必須將 連接到此角色，以呼叫整合 AWS 服務的合適 IAM 許可政策。例如，若要呼叫 Lambda 函數，您必須在 IAM 角色中納入下列 IAM 許可政策：

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": "*"
        }
    ]
}
```

------

請注意，Lambda 支援合併信任與許可政策的資源類型存取政策。使用 API Gateway 主控台整合 API 與 Lambda 函數時，不會要求您明確設定此 IAM 角色，因為主控台會在您的同意下，為您設定 Lambda 函數的資源型許可。

**注意**  
 若要對 AWS 服務制定存取控制，您可以使用以發起人為基礎的許可模型，其中許可政策直接連接到發起人的使用者或群組，或以角色為基礎的許可模型，其中許可政策連接到 API Gateway 可以擔任的 IAM 角色。這兩個模型的許可政策可能有所不同。例如，發起人類型政策會封鎖存取，而角色類型政策則會允許存取。您可以利用此功能，要求使用者只能透過 API Gateway API 存取 AWS 服務。

# 控制對 API 的呼叫存取權
<a name="api-gateway-control-access-using-iam-policies-to-invoke-api"></a>

在本節中，您會了解使用 IAM 許可控制 API 存取權的許可模型。啟用 IAM 授權時，用戶端必須使用 Signature 第 4a 版 (SigV4a) 和 Signature 第 4 版 (SigV4) 以 AWS 登入資料簽署其請求。如需詳細資訊，請參閱 [AWS 第 4 版簽署程序](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html)。

在此區段中，我們會展示範本 IAM 政策聲明和政策聲明參考。政策聲明參考包括與 API 執行服務相關之 `Action` 與 `Resource` 欄位的格式。使用這些參考來建立您的 IAM 政策聲明。建立 IAM 政策聲明時，您可能需要考慮 API Gateway 資源政策影響授權工作流程的方式。如需詳細資訊，請參閱[API Gateway 資源政策如何影響授權工作流程](apigateway-authorization-flow.md)。

處理私有 API 時，您應結合使用 API Gateway 資源政策與 VPC 端點政策。如需詳細資訊，請參閱下列主題：
+ [使用 API Gateway 資源政策來控制對 REST API 的存取](apigateway-resource-policies.md)
+ [在 API Gateway 中使用私有 API 的 VPC 端點政策](apigateway-vpc-endpoint-policies.md)

## 控制誰可以使用 IAM 政策呼叫 API Gateway API 方法
<a name="api-gateway-who-can-invoke-an-api-method-using-iam-policies"></a>

 若要控制誰可以或無法使用 IAM 許可呼叫已部署的 API，請以必要的許可建立 IAM 政策文件。這類政策文件的範本如下所示。

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Permission",
      "Action": [
        "execute-api:Execution-operation"           
      ],
      "Resource": [
        "arn:aws:execute-api:region:123456789012:api-id/stage/METHOD_HTTP_VERB/Resource-path"
      ]
    }
  ]
}
```

------

 在本例中，`Permission` 將根據您要授予或撤銷內含許可，取代為 `Allow` 或 `Deny`。`Execution-operation`​ 將取代為 API 執行服務支援的操作。`METHOD_HTTP_VERB`​ 代表指定資源支援的 HTTP 動詞。`Resource-path` 是支援上述 `METHOD_HTTP_VERB` 之已部署 API `[Resource](https://docs.aws.amazon.com/apigateway/latest/api/API_Resource.html)` 執行個體的 URL 路徑預留位置。如需詳細資訊，請參閱[在 API Gateway 中執行 API 之 IAM 政策的陳述式參考](#api-gateway-calling-api-permissions)。

**注意**  
若要讓 IAM 政策生效，您必須將方法的 `[authorizationType](https://docs.aws.amazon.com/apigateway/latest/api/API_Method.html#authorizationType)` 屬性設定為 `AWS_IAM`，以啟用 API 方法上的 IAM 身分驗證。不這樣做會使這些 API 方法可供公開存取。

 例如，若要授予使用者檢視指定 API 所公開之寵物清單的許可，但拒絕使用者將寵物新增至清單的許可，您可以在 IAM 政策中包含下列陳述式：

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "execute-api:Invoke"           
      ],
      "Resource": [
        "arn:aws:execute-api:us-east-1:111111111111:api-id/*/GET/pets"
      ]
    },
    {
      "Effect": "Deny",
      "Action": [
        "execute-api:Invoke"           
      ],
      "Resource": [
        "arn:aws:execute-api:us-east-1:111111111111:api-id/*/POST/pets"
      ]
    }
  ]
}
```

------

若要授予使用者許可，讓他們可以檢視設定為 `GET /pets/{petId}` 之 API 所公開的特定寵物，您可以在 IAM 政策中包含以下陳述式：

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "execute-api:Invoke"
            ],
            "Resource": [
                "arn:aws:execute-api:us-east-1:111122223333:api-id/*/GET/pets/a1b2"
            ]
        }
    ]
}
```

------

## 在 API Gateway 中執行 API 之 IAM 政策的陳述式參考
<a name="api-gateway-calling-api-permissions"></a>

下列資訊說明執行 API 的存取許可之 IAM 政策陳述式的動作與資源格式。

### 在 API Gateway 中執行 API 之許可的動作格式
<a name="api-gateway-iam-policy-action-format-for-executing-api"></a>

API 執行 `Action` 表達式具有下列一般格式：

```
execute-api:action
```

其中 *action* 是可用的 API 執行動作：
+ **\$1**，表示下列所有動作。
+ **Invoke**，在用戶端請求下用來呼叫 API。
+ **InvalidateCache**，在用戶端請求下用來使 API 快取失效。

### 在 API Gateway 中執行 API 之許可的資源格式
<a name="api-gateway-iam-policy-resource-format-for-executing-api"></a>

API 執行 `Resource` 表達式具有下列一般格式：

```
arn:aws:execute-api:region:account-id:api-id/stage-name/HTTP-VERB/resource-path-specifier
```

其中：
+ *region* 是對應至 方法之已部署 API AWS 的區域 （例如 **us-east-1**或**\$1**所有 AWS 區域的 )。
+ *account-id* 是 REST API 擁有者的 12 位數 AWS 帳戶 ID。
+ *api-id* 是 API Gateway 分配給該方法之 API 的標識符。
+ *stage-name* 是與方法相關聯的階段名稱。
+ *HTTP-VERB* 是方法的 HTTP 動詞。它可以是下列其中一項：GET、POST、PUT、DELETE、PATCH。
+ *resource-path-specifier* 是所需方法的路徑

**注意**  
如果您指定萬用字元 (`*`)，則 `Resource` 表達式會將萬用字元套用至表達式的其餘部分。

一些範例資源表達式包括：
+ **arn:aws:execute-api:\$1:\$1:\$1** 用於任何階段中的任何資源路徑， 用於任何 AWS 區域中的任何 API。
+ **arn:aws:execute-api:us-east-1:\$1:\$1** 對於任何階段中的任何資源路徑，對於 AWS 區域中的任何 API`us-east-1`。
+ **arn:aws:execute-api:us-east-1:\$1:*api-id*/\$1** 對於任何階段中的任何資源路徑，對於 us-east-1 AWS 區域中識別符為 *api-id* 的 API。
+ **arn:aws:execute-api:us-east-1:\$1:*api-id*/`test`/\$1**，表示 us-east-1 的 AWS 區域中識別符為 *api-id* 之 API `test` 階段的任何資源路徑。

如需詳細資訊，請參閱 [API Gateway Amazon Resource Name (ARN) 參考資料](arn-format-reference.md)。

# API 執行許可的 IAM 政策範例
<a name="api-gateway-iam-policy-examples-for-api-execution"></a>

如需許可模型與其他背景資訊，請參閱「[控制對 API 的呼叫存取權](api-gateway-control-access-using-iam-policies-to-invoke-api.md)」。

下列政策聲明會授予使用者許可，以呼叫識別符為 `a123456789` 之 API 的 `test` 階段中沿著 `mydemoresource` 路徑的任何 POST 方法 (假設對應的 API 已部署至 us-east-1 的 AWS 區域)：

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "execute-api:Invoke"
      ],
      "Resource": [
        "arn:aws:execute-api:us-east-1:*:a123456789/test/POST/my-demo-resource-path/*"
      ]
    }
  ]
}
```

------

下列範例政策陳述式會提供使用者許可，在已部署識別符為 `petstorewalkthrough/pets` 之 API 的 `a123456789` 區域中，呼叫對應 API 之任何階段中資源路徑 AWS 上的任何方法：

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "execute-api:Invoke"
      ],
      "Resource": [
        "arn:aws:execute-api:*:*:a123456789/*/*/petstorewalkthrough/pets"
      ]
    }
  ]
}
```

------

# 在 API Gateway 中使用私有 API 的 VPC 端點政策
<a name="apigateway-vpc-endpoint-policies"></a>

若要提高私有 API 的安全性，您可以建立 VPC 端點政策。VPC 端點政策為 IAM 資源政策，您可將其連接至 VPC 端點。如需詳細資訊，請參閱[使用 VPC 端點控制服務的存取](https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-endpoints-access.html)。

您可能會想要建立 VPC 端點政策來執行下列任務。
+ 僅允許特定組織或資源存取您的 VPC 端點，並調用您的 API。
+ 使用單一政策，避免使用工作階段型或角色型政策控制 API 的流量。
+ 從現場部署遷移到 時，請緊固應用程式的安全周邊 AWS。

## VPC 端點政策考量事項
<a name="apigateway-vpc-endpoint-policies-considerations"></a>

以下是 VPC 端點政策的考量事項：
+ 呼叫者的身分是根據 `Authorization` 標頭值進行評估。首先會評估 VPC 端點政策，然後 API Gateway 會根據方法請求上設定的授權類型評估請求。下表顯示如何根據 `Authorization` 標頭值的內容評估 VPC 端點政策。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-vpc-endpoint-policies.html)
+ 如果您的存取控制取決於使用持有人權杖，例如 Lambda 或 Amazon Cognito 授權方，則您可以使用[資源的屬性](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resource-properties)來控制您的安全邊界。
+  如果您的授權控制項使用 IAM 授權，則您可以使用[資源的屬性](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resource-properties)和[主體的屬性](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resource-principal)來控制您的安全邊界。
+ VPC 端點政策可與 API Gateway 資源政策搭配使用。API Gateway 資源政策指定由哪個主體存取 API。端點政策指定誰可以存取 VPC，以及可以從 VPC 端點呼叫哪些 API。您的私有 API 需要資源政策，但您不需要建立自訂 VPC 端點政策。

## VPC 端點政策範例
<a name="apigateway-vpc-endpoint-policies-examples"></a>

您可以為 Amazon API Gateway 建立 Amazon Virtual Private Cloud 端點的政策，您可以在其中指定如下：
+ 可執行動作的主體。
+ 可執行的動作。
+ 可對其執行動作的資源。

這可能取決於授權標頭的內容。如需詳細資訊，請參閱[VPC 端點政策考量事項](#apigateway-vpc-endpoint-policies-considerations)。如需其他範例政策，請參閱 GitHub 網站上的[資料周界政策範例](https://github.com/aws-samples/data-perimeter-policy-examples)。

您需要使用 VPC 主控台，才能將政策連接至 VPC 端點。如需詳細資訊，請參閱[使用 VPC 端點控制服務的存取](https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-endpoints-access.html)。

## 範例 1：授予兩個 API 存取權限的 VPC 端點政策
<a name="apigateway-vpc-endpoint-policies-example-1"></a>

以下範例政策會透過連接政策的 VPC 端點，僅授予使用者存取兩個特定 API 的權限。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Principal": "*",
            "Action": [
                "execute-api:Invoke"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:execute-api:us-east-1:123412341234:a1b2c3d4e5/*",
                "arn:aws:execute-api:us-east-1:123412341234:aaaaa11111/*"
            ]
        }
    ]
}
```

------

## 範例 2：授予 GET 方法存取權限的 VPC 端點政策
<a name="apigateway-vpc-endpoint-policies-example-2"></a>

以下範例政策會透過連接政策的 VPC 端點，授予使用者存取特定 API `GET` 方法的權限。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Principal": "*",
            "Action": [
                "execute-api:Invoke"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:execute-api:us-east-1:123412341234:a1b2c3d4e5/stageName/GET/*"
            ]
        }
    ]
}
```

------

## 範例 3：授予某個使用者特定 API 存取權限的 VPC 端點政策
<a name="apigateway-vpc-endpoint-policies-example-3"></a>

以下範例政策會透過連接政策的 VPC 端點，授予某個使用者存取特定 API 的權限。

在此情況下，由於政策限制對特定 IAM 主體的存取，您必須將方法 `authorizationType` 設定為 `AWS_IAM` 或 `NONE`。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Principal": {
                "AWS": [
                    "arn:aws:iam::123412341234:user/MyUser"
                ]
            },
            "Action": [
                "execute-api:Invoke"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:execute-api:us-east-1:123412341234:a1b2c3d4e5/*"
            ]
        }
    ]
}
```

------

## 範例 4：VPC 端點政策授予使用者對於特定自訂網域名稱，和每個映射到網域的 API 存取權
<a name="apigateway-vpc-endpoint-policies-example-4"></a>

以下範例政策會透過連接政策的 VPC 端點，授予使用者存取私有 API 之特定自訂網域名稱的權限。若使用此政策，只要使用者已在 VPC 端點與自訂網域名稱之間建立網域名稱存取關聯，並被授予調用自訂網域名稱和映射至自訂網域名稱的任何私有 API 的存取權，則使用者即可調用映射至此自訂網域名稱的任何 API。如需詳細資訊，請參閱[API Gateway 中的 API 私有 API 的自訂網域名稱](apigateway-private-custom-domains.md)。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "execute-api:Invoke",
      "Resource": [
        "*"
      ],
       "Condition": {
        "ArnEquals": {
          "execute-api:viaDomainArn": "arn:aws:execute-api:us-west-2:111122223333:/domainnames/private.test.com+f4g5h6",
        }
      }
    }
  ]
}
```

------

## 範例 5：授予或拒絕存取特定 API 和網域資源的 VPC 端點政策
<a name="apigateway-vpc-endpoint-policies-example-5"></a>

下列範例政策會授予使用者對特定 API 和網域資源的存取權。若使用此政策，只要使用者已在 VPC 端點與自訂網域名稱之間建立網域名稱存取關聯，並被授予調用自訂網域名稱和映射至自訂網域名稱的任何私有 API 的存取權，使用者即可調用允許的私有 API 和網域資源。如需詳細資訊，請參閱[API Gateway 中的 API 私有 API 的自訂網域名稱](apigateway-private-custom-domains.md)。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "execute-api:Invoke",
      "Resource": [
        "arn:aws:execute-api:us-west-2:111122223333:/domainnames/private.test.com+f4g5h6",
        "arn:aws:execute-api:us-west-2:111122223333:a1b2c3d4e5/*"
      ]
    },
    {
      "Effect": "Deny",
      "Principal": {
        "AWS": "*"
      },
      "Action": "execute-api:Invoke",
      "Resource": [
        "arn:aws:execute-api:us-west-2:111122223333:a1b2c3d4e5/admin/*",
        "arn:aws:execute-api:us-west-2:111122223333:bcd123455/*"
      ]
    }
  ]
}
```

------

## 範例 6：授予或拒絕屬於組織的主體和資源進行存取的 VPC 端點政策
<a name="apigateway-vpc-endpoint-policies-example-6"></a>

下列範例政策會將存取權授予屬於組織的主體和資源。

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Condition": {
                "StringEquals": {
                    "aws:ResourceOrgID": "o-abcd1234",
                    "aws:PrincipalOrgID": "o-abcd1234"
                }
            },
            "Action": "*",
            "Resource": "*",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Sid": "AllowRequestsByOrgsIdentitiesToOrgsResources"
        }
    ]
}
```

------

# 使用標籤控制 API Gateway 中的 REST API 存取權
<a name="apigateway-control-access-tags"></a>

您可以在 IAM 政策中使用屬性型存取控制，以微調對 REST API 的存取許可。

如需詳細資訊，請參閱[使用標籤來控制對 API Gateway REST API 資源的存取](apigateway-tagging-iam-policy.md)。

# 使用 API Gateway Lambda 授權方
<a name="apigateway-use-lambda-authorizer"></a>

使用 *Lambda 授權方* (先前稱為*自訂授權方*) 控制存取 API。當用戶端請求 API 的方法時，API Gateway 會呼叫您的 Lambda 授權方。Lambda 授權方會將呼叫者的身分當作輸入項，並傳回 IAM 政策做為輸出。

使用 Lambda 授權方實作自訂授權機制。您的方案可以使用請求參數來判斷呼叫者的身分，或使用承載字符驗證策略，例如 OAuth 或 SAML。在 API Gateway REST API 主控台中使用 AWS CLI或 AWS SDK 建立 Lambda 授權方。

## Lambda 授權方授權工作流程
<a name="api-gateway-lambda-authorizer-flow"></a>

下圖說明 Lambda 授權方的授權工作流程。

![\[API Gateway Lambda 授權工作流程\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/custom-auth-workflow.png)


**API Gateway Lambda 授權工作流程**

1. 用戶端在 API Gateway API 上呼叫方法，傳遞承載字符或請求參數。

1. API Gateway 會確認是否有使用 Lambda 授權方設定方法請求。如果已設定，API Gateway 將會呼叫 Lambda 函式。

1. Lambda 函數會驗證呼叫者。函數可以利用以下方式進行驗證：
   + 呼叫 OAuth 提供者以取得 OAuth 存取字符。
   + 呼叫 SAML 提供者以取得 SAML 聲明。
   + 根據請求參數值產生 IAM 政策。
   + 從資料庫擷取憑證。

1. Lambda 函數會傳回 IAM 政策和主體識別碼。如果 Lambda 函數未傳回該資訊，呼叫便失敗。

1. API Gateway 會評估 IAM 政策。
   + 如果拒絕存取，API Gateway 會傳回一個適當的 HTTP 狀態碼，例如 `403 ACCESS_DENIED`。
   + 如果允許存取，API Gateway 會調用該方法。

     如果啟用授權快取，API Gateway 會快取該政策，如此就不需要再次調用 Lambda 授權方函式。請確認您的政策適用於 API 中的所有資源和方法。

您可以自訂 `403 ACCESS_DENIED` 或 `401 UNAUTHORIZED` 閘道回應。如需詳細資訊，請參閱 [API Gateway 中 REST API 的閘道回應](api-gateway-gatewayResponse-definition.md)。

## 選擇 Lambda 授權方的類型
<a name="api-gateway-lambda-authorizer-choose"></a>

Lambda 授權方有兩種類型：

**請求參數型 Lambda 授權方 (`REQUEST` 授權方)**  
`REQUEST` 授權方利用標頭、查詢字串參數、[`stageVariables`](api-gateway-mapping-template-reference.md#stagevariables-template-reference) 和 [`$context`](api-gateway-mapping-template-reference.md#context-variable-reference) 變數的組合方式接呼叫者的身分。您可以使用 `REQUEST` 授權方，以根據來自多個身分來源的資訊建立精細政策，例如 `$context.path` 和 `$context.httpMethod` 內容變數。  
如果您開啟 `REQUEST` 授權方的授權快取，API Gateway 會驗證請求中是否存在所有指定的身分來源。如果指定的身分來源遺漏、為 Null 或空白，API Gateway 會傳回 `401 Unauthorized` HTTP 回應，而無需呼叫 Lambda 授權方函數。定義多個身分來源時，會使用這些來源衍生授權方的快取金鑰，並保留順序。您可以使用多個身分來源來定義精細快取金鑰。  
如果您變更任何快取金鑰部分並重新部署您的 API，則授權方會捨棄快取的政策文件，並產生新的政策文件。  
如果關閉 `REQUEST` 授權方的授權快取，則 API Gateway 會直接將請求傳遞給 Lambda 函數。

**以字符為基礎的 Lambda 授權方 (`TOKEN` 授權方)**  
`TOKEN` 授權方會以承載字符接收呼叫者的身分，例如 JSON Web Token (JWT) 或 OAuth 字符。  
如果您開啟 `TOKEN` 授權方的授權快取，則字符來源中指定的標頭名稱會成為快取金鑰。  
此外，您可以使用字符驗證來輸入 RegEx 陳述式。API Gateway 會對此表達式執行輸入字符的初始驗證，並在成功驗證時調用 Lambda 授權方函數。這樣做有助於減少對 API 的呼叫。  
`IdentityValidationExpression` 屬性僅支援 `TOKEN` 授權方。如需詳細資訊，請參閱[x-amazon-apigateway-authorizer 物件](api-gateway-swagger-extensions-authorizer.md)。

**注意**  
建議您使用 `REQUEST` 授權方來控制對 API 的存取。與使用 `TOKEN` 授權方時的單一身分來源相比，您可以在使用 `REQUEST` 授權方時，根據多個身分來源控制對 API 的存取。此外，您可以使用 `REQUEST` 授權方的多個身分來源來分隔快取金鑰。

## `REQUEST` 授權方 Lambda 函數範例
<a name="api-gateway-lambda-authorizer-request-lambda-function-create"></a>

下列範例程式碼會建立 Lambda 授權方函數，當用戶端提供的 `HeaderAuth1` 標頭、`QueryString1` 查詢參數和階段變數 `StageVar1` 分別符合 `headerValue1`、`queryValue1` 和 `stageValue1` 指定值時，允許請求。

------
#### [ Node.js ]

```
// A simple request-based authorizer example to demonstrate how to use request 
// parameters to allow or deny a request. In this example, a request is  
// authorized if the client-supplied HeaderAuth1 header, QueryString1
// query parameter, and stage variable of StageVar1 all match
// specified values of 'headerValue1', 'queryValue1', and 'stageValue1',
// respectively.
    
export const handler = function(event, context, callback) {
    console.log('Received event:', JSON.stringify(event, null, 2));
    
    // Retrieve request parameters from the Lambda function input:
    var headers = event.headers;
    var queryStringParameters = event.queryStringParameters;
    var pathParameters = event.pathParameters;
    var stageVariables = event.stageVariables;
        
    // Parse the input for the parameter values
    var tmp = event.methodArn.split(':');
    var apiGatewayArnTmp = tmp[5].split('/');
    var awsAccountId = tmp[4];
    var region = tmp[3];
    var restApiId = apiGatewayArnTmp[0];
    var stage = apiGatewayArnTmp[1];
    var method = apiGatewayArnTmp[2];
    var resource = '/'; // root resource
    if (apiGatewayArnTmp[3]) {
        resource += apiGatewayArnTmp[3];
    }
        
    // Perform authorization to return the Allow policy for correct parameters and 
    // the 'Unauthorized' error, otherwise.

     
    if (headers.HeaderAuth1 === "headerValue1"
        && queryStringParameters.QueryString1 === "queryValue1"
        && stageVariables.StageVar1 === "stageValue1") {
        callback(null, generateAllow('me', event.methodArn));
    }  else {
        callback(null, generateDeny('me', event.methodArn));
    }
}
     
// Help function to generate an IAM policy
var generatePolicy = function(principalId, effect, resource) {
    // Required output:
    var authResponse = {};
    authResponse.principalId = principalId;
    if (effect && resource) {
        var policyDocument = {};
        policyDocument.Version = '2012-10-17'; // default version
        policyDocument.Statement = [];
        var statementOne = {};
        statementOne.Action = 'execute-api:Invoke'; // default action
        statementOne.Effect = effect;
        statementOne.Resource = resource;
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    }
    // Optional output with custom properties of the String, Number or Boolean type.
    authResponse.context = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": true
    };
    return authResponse;
}
     
var generateAllow = function(principalId, resource) {
    return generatePolicy(principalId, 'Allow', resource);
}
     
var generateDeny = function(principalId, resource) {
    return generatePolicy(principalId, 'Deny', resource);
}
```

------
#### [ Python ]

```
# A simple request-based authorizer example to demonstrate how to use request
# parameters to allow or deny a request. In this example, a request is
# authorized if the client-supplied headerauth1 header, QueryString1
# query parameter, and stage variable of StageVar1 all match
# specified values of 'headerValue1', 'queryValue1', and 'stageValue1',
# respectively.

def lambda_handler(event, context):
    print(event)

    # Retrieve request parameters from the Lambda function input:
    headers = event['headers']
    queryStringParameters = event['queryStringParameters']
    pathParameters = event['pathParameters']
    stageVariables = event['stageVariables']

    # Parse the input for the parameter values
    tmp = event['methodArn'].split(':')
    apiGatewayArnTmp = tmp[5].split('/')
    awsAccountId = tmp[4]
    region = tmp[3]
    restApiId = apiGatewayArnTmp[0]
    stage = apiGatewayArnTmp[1]
    method = apiGatewayArnTmp[2]
    resource = '/'

    if (apiGatewayArnTmp[3]):
        resource += apiGatewayArnTmp[3]

    # Perform authorization to return the Allow policy for correct parameters
    # and the 'Unauthorized' error, otherwise.

    if (headers['HeaderAuth1'] == "headerValue1" and queryStringParameters['QueryString1'] == "queryValue1" and stageVariables['StageVar1'] == "stageValue1"):
        response = generateAllow('me', event['methodArn'])
        print('authorized')
        return response
    else:
        print('unauthorized')
        response = generateDeny('me', event['methodArn'])
        return response
    # Help function to generate IAM policy


def generatePolicy(principalId, effect, resource):
    authResponse = {}
    authResponse['principalId'] = principalId
    if (effect and resource):
        policyDocument = {}
        policyDocument['Version'] = '2012-10-17'
        policyDocument['Statement'] = []
        statementOne = {}
        statementOne['Action'] = 'execute-api:Invoke'
        statementOne['Effect'] = effect
        statementOne['Resource'] = resource
        policyDocument['Statement'] = [statementOne]
        authResponse['policyDocument'] = policyDocument

    authResponse['context'] = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": True
    }

    return authResponse


def generateAllow(principalId, resource):
    return generatePolicy(principalId, 'Allow', resource)


def generateDeny(principalId, resource):
    return generatePolicy(principalId, 'Deny', resource)
```

------

在此範例中，Lambda 授權方函數會檢查輸入參數，並運作如下：
+ 如果所有的必要參數值皆符合預期值，授權方函數會傳回一個 `200 OK` HTTP 回應和一個如下的 IAM 政策，而且方法請求會成功：

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

****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow",
        "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/"
      }
    ]
  }
  ```

------
+ 否則，授權方函數會傳回 `401 Unauthorized` HTTP 回應，而且方法請求失敗。

除了傳回 IAM 政策，Lambda 授權方函數還必須傳回發起人的主要識別符。也可以選擇傳回 `context` 物件，其中包含可傳入整合後端的其他資訊。如需詳細資訊，請參閱[來自 API Gateway Lambda 授權方的輸出](api-gateway-lambda-authorizer-output.md)。

在生產程式碼中，您可能需要驗證使用者，再授予授權。您可以在 Lambda 函數中新增驗證邏輯，方法為依照該提供者文件中的指示來呼叫驗證提供者。

## `TOKEN` 授權方 Lambda 函數範例
<a name="api-gateway-lambda-authorizer-token-lambda-function-create"></a>

下列範例程式碼會建立 `TOKEN` Lambda 授權方函數，允許呼叫者在用戶端提供的字符值為 `allow` 時，調用方法。如果字符值為 `deny`，則不允許呼叫者調用請求。如果字符值為 `unauthorized` 或空字串，則授權方函數會傳回 `401 UNAUTHORIZED` 回應。

------
#### [ Node.js ]

```
// A simple token-based authorizer example to demonstrate how to use an authorization token 
// to allow or deny a request. In this example, the caller named 'user' is allowed to invoke 
// a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke 
// the request if the token value is 'deny'. If the token value is 'unauthorized' or an empty
// string, the authorizer function returns an HTTP 401 status code. For any other token value, 
// the authorizer returns an HTTP 500 status code. 
// Note that token values are case-sensitive.

export const handler =  function(event, context, callback) {
    var token = event.authorizationToken;
    switch (token) {
        case 'allow':
            callback(null, generatePolicy('user', 'Allow', event.methodArn));
            break;
        case 'deny':
            callback(null, generatePolicy('user', 'Deny', event.methodArn));
            break;
        case 'unauthorized':
            callback("Unauthorized");   // Return a 401 Unauthorized response
            break;
        default:
            callback("Error: Invalid token"); // Return a 500 Invalid token response
    }
};

// Help function to generate an IAM policy
var generatePolicy = function(principalId, effect, resource) {
    var authResponse = {};
    
    authResponse.principalId = principalId;
    if (effect && resource) {
        var policyDocument = {};
        policyDocument.Version = '2012-10-17'; 
        policyDocument.Statement = [];
        var statementOne = {};
        statementOne.Action = 'execute-api:Invoke'; 
        statementOne.Effect = effect;
        statementOne.Resource = resource;
        policyDocument.Statement[0] = statementOne;
        authResponse.policyDocument = policyDocument;
    }
    
    // Optional output with custom properties of the String, Number or Boolean type.
    authResponse.context = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": true
    };
    return authResponse;
}
```

------
#### [ Python ]

```
# A simple token-based authorizer example to demonstrate how to use an authorization token
# to allow or deny a request. In this example, the caller named 'user' is allowed to invoke
# a request if the client-supplied token value is 'allow'. The caller is not allowed to invoke
# the request if the token value is 'deny'. If the token value is 'unauthorized' or an empty
# string, the authorizer function returns an HTTP 401 status code. For any other token value,
# the authorizer returns an HTTP 500 status code.
# Note that token values are case-sensitive.

import json


def lambda_handler(event, context):
    token = event['authorizationToken']
    if token == 'allow':
        print('authorized')
        response = generatePolicy('user', 'Allow', event['methodArn'])
    elif token == 'deny':
        print('unauthorized')
        response = generatePolicy('user', 'Deny', event['methodArn'])
    elif token == 'unauthorized':
        print('unauthorized')
        raise Exception('Unauthorized')  # Return a 401 Unauthorized response
        return 'unauthorized'
    try:
        return json.loads(response)
    except BaseException:
        print('unauthorized')
        return 'unauthorized'  # Return a 500 error


def generatePolicy(principalId, effect, resource):
    authResponse = {}
    authResponse['principalId'] = principalId
    if (effect and resource):
        policyDocument = {}
        policyDocument['Version'] = '2012-10-17'
        policyDocument['Statement'] = []
        statementOne = {}
        statementOne['Action'] = 'execute-api:Invoke'
        statementOne['Effect'] = effect
        statementOne['Resource'] = resource
        policyDocument['Statement'] = [statementOne]
        authResponse['policyDocument'] = policyDocument
    authResponse['context'] = {
        "stringKey": "stringval",
        "numberKey": 123,
        "booleanKey": True
    }
    authResponse_JSON = json.dumps(authResponse)
    return authResponse_JSON
```

------

在此範例中，當 API 收到方法請求時，API Gateway 會在 `event.authorizationToken` 屬性中將來源字符傳遞至此 Lambda 授權方函數。Lambda 授權方函數會讀取字符，並運作如下：
+ 如果字符值為 `allow`，授權方函數會傳回一個 `200 OK` HTTP 回應和一個如下的 IAM 政策，而且方法請求會成功：

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

****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow",
        "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/"
      }
    ]
  }
  ```

------
+ 如果字符值為 `deny`，授權方函數會傳回一個 `200 OK` HTTP 回應和一個如下的 `Deny` IAM 政策，而且方法請求會失敗：

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

****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Deny",
        "Resource": "arn:aws:execute-api:us-east-1:123456789012:ivdtdhp7b5/ESTestInvoke-stage/GET/"
      }
    ]
  }
  ```

------
**注意**  
在測試環境之外，則 API Gateway 會傳回 `403 Forbidden` HTTP 回應，而且方法請求會失敗。
+ 如果符記值為 `unauthorized` 或空字串，授權方函數會傳回 `401 Unauthorized` HTTP 回應，而且方法呼叫會失敗。
+ 如果符記為其他值，用戶端會收到 `500 Invalid token` 回應，而且方法呼叫會失敗。

除了傳回 IAM 政策，Lambda 授權方函數還必須傳回發起人的主要識別符。也可以選擇傳回 `context` 物件，其中包含可傳入整合後端的其他資訊。如需詳細資訊，請參閱[來自 API Gateway Lambda 授權方的輸出](api-gateway-lambda-authorizer-output.md)。

在生產程式碼中，您可能需要驗證使用者，再授予授權。您可以在 Lambda 函數中新增驗證邏輯，方法為依照該提供者文件中的指示來呼叫驗證提供者。

## Lambda 授權方函數的其他範例
<a name="api-gateway-lambda-authorizer-lambda-function-create"></a>

下列清單顯示 Lambda 授權方函數的其他範例。您可以在與您建立 API 的相同帳戶或不同帳戶中建立 Lambda 函數。

對於先前的範例 Lambda 函數，您可以使用內建的 [AWSLambdaBasicExecutionRole](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)，因為這些函數不會呼叫其他 AWS 服務。如果您的 Lambda 函數呼叫其他 AWS 服務，您將需要將 IAM 執行角色指派給 Lambda 函數。若要建立角色，請依照 [AWS Lambda 執行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)中的指示。

**Lambda 授權方函數的其他範例**
+  如需範例應用程式，請參閱 GitHub 上的 [Open Banking Brazil - Authorization Samples](https://github.com/aws-samples/openbanking-brazilian-auth-samples)。
+  如需更多的範例 Lambda 函數，請參閱 GitHub 上的 [aws-apigateway-lambda-authorizer-blueprints](https://github.com/awslabs/aws-apigateway-lambda-authorizer-blueprints)。
+ 您可以建立 Lambda 授權方，以使用 Amazon Cognito 使用者集區對使用者進行驗證，並使用 Verified Permissions 根據政策存放區授權給呼叫者。如需詳細資訊，請參閱[利用 Verified Permissions 根據身分的屬性控制存取權](apigateway-lambda-authorizer-verified-permissions.md)。
+ Lambda 主控台會提供 Python 藍圖，您可以選擇 **Use a blueprint (使用藍圖)**，並選擇 **api-gateway-authorizer-python** 藍圖來使用此藍圖。

# 設定 API Gateway Lambda 授權方
<a name="configure-api-gateway-lambda-authorization"></a>

建立 Lambda 函數後，可以將 Lambda 函數設定為 API 的授權方。然後，可以設定方法來調用 Lambda 授權方，以判斷呼叫者是否可以調用您的方法。您可以在與您建立 API 的相同帳戶或不同帳戶中建立 Lambda 函數。

您可以使用 API Gateway 主控台的內建工具，或使用 [Postman](https://www.postman.com/) 來測試 Lambda 授權方。如需有關如何使用 Postman 測試 Lambda 授權方函數的指示，請參閱 [使用 API Gateway Lambda 授權方呼叫 API](call-api-with-api-gateway-lambda-authorization.md)。

## 設定 Lambda 授權方 (主控台)
<a name="configure-api-gateway-lambda-authorization-with-console"></a>

 下列程序顯示如何在 API Gateway REST API 主控台建立 Lambda 授權方。若要進一步了解不同類型的 Lambda 授權方，請參閱 [選擇 Lambda 授權方的類型](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-choose)。

------
#### [ REQUEST authorizer ]

**設定 `REQUEST` Lambda 授權方**

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

1. 選取 API，然後選擇**授權方**。

1. 選擇**建立授權方**。

1. 針對**授權方名稱**，輸入授權方的名稱。

1. 針對**授權方類型**，選取 **Lambda**。

1. 針對 **Lambda 函數**，選取您建立 Lambda 授權方函數 AWS 區域 的 ，然後輸入函數名稱。

1. 將 **Lambda 調用角色**保留空白，以便讓 API Gateway REST API 主控台設定資源型政策。此政策會授與 API Gateway 許可，以調用 Lambda 授權方函數。您也可以選擇輸入 IAM 角色的名稱，以允許 API Gateway 調用 Lambda 授權方函數。如需範例角色，請參閱 [建立可擔任的 IAM 角色](integrating-api-with-aws-services-lambda.md#api-as-lambda-proxy-setup-iam-role-policies)。

1. 針對 **Lambda 事件承載**，選取**請求**。

1. 針對**身分來源類型**，選取參數類型。支援的參數類型為 `Header`、`Query string`、`Stage variable` 與 `Context`。若要新增更多身分來源，請選擇**新增參數**。

1. 若要快取授權方產生的授權政策，請將**授權快取**保持開啟狀態。啟用政策快取時，您可以修改 **TTL** 值。將 **TTL** 設定為零會停用政策快取。

   如果啟用快取，您的授權方必須傳回適用於 API 之所有方法的政策。若要強制執行方法特定的政策，請使用內容變數 `$context.path` 和 `$context.httpMethod`。

1. 選擇**建立授權方**。

------
#### [ TOKEN authorizer ]

**設定 `TOKEN` Lambda 授權方**

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

1. 選取 API，然後選擇**授權方**。

1. 選擇**建立授權方**。

1. 針對**授權方名稱**，輸入授權方的名稱。

1. 針對**授權方類型**，選取 **Lambda**。

1. 針對 **Lambda 函數**，選取您建立 Lambda 授權方函數 AWS 區域 的 ，然後輸入函數名稱。

1. 將 **Lambda 調用角色**保留空白，以便讓 API Gateway REST API 主控台設定資源型政策。此政策會授與 API Gateway 許可，以調用 Lambda 授權方函數。您也可以選擇輸入 IAM 角色的名稱，以允許 API Gateway 調用 Lambda 授權方函數。如需範例角色，請參閱 [建立可擔任的 IAM 角色](integrating-api-with-aws-services-lambda.md#api-as-lambda-proxy-setup-iam-role-policies)。

1. 針對 **Lambda 事件承載**，選取**權杖**。

1. 針對**權杖來源**，輸入包含授權權杖的標頭名稱。呼叫者必須包含此名稱的標頭，才能將授權字符傳送到 Lambda 授權方。

1. 或者，針對**符記驗證**，輸入 RegEx 陳述式。API Gateway 會對此表達式執行輸入字符的初始驗證，並在成功驗證時調用授權方。

1. 若要快取授權方產生的授權政策，請將**授權快取**保持開啟狀態。啟用政策快取時，**權杖來源**中指定的標頭名稱會成為快取金鑰。啟用政策快取時，您可以修改 **TTL** 值。將 **TTL** 設定為零會停用政策快取。

   如果啟用快取，您的授權方必須傳回適用於 API 之所有方法的政策。若要強制執行方法特定政策，您可以關閉**授權快取**。

1. 選擇**建立授權方**。

------

建立 Lambda 授權方之後，您可以測試該授權方。下列程序顯示如何測試您的 Lambda 授權方。

------
#### [ REQUEST authorizer ]

**測試 `REQUEST` Lambda 授權方**

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

1. 選取授權方的名稱。

1. 在**測試授權方**下，輸入身分來源的值。

   如果您使用的是 [`REQUEST` 授權方 Lambda 函數範例](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-request-lambda-function-create)，請執行以下操作：

   1. 選取**標頭**並輸入 **headerValue1**，然後選擇**新增參數**。

   1. 在**身分來源類型**底下，選取**查詢字串**並輸入 **queryValue1**，然後選擇**新增參數**。

   1. 在**身分來源類型**底下，選取**階段變數**並輸入 **stageValue1**。

   您無法修改測試調用的內容變數，但您可以修改 Lambda 函數的 **API Gateway Authorizer** 測試事件範本。然後，您可以使用修訂內容變數來測試 Lambda 授權方函數。如需詳細資訊，請參閱《AWS Lambda 開發人員指南》**中的[在主控台測試 Lambda 函數](https://docs.aws.amazon.com/lambda/latest/dg/testing-functions.html)。

1. 選擇**測試授權方**。

------
#### [ TOKEN authorizer ]

**測試 `TOKEN` Lambda 授權方**

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

1. 選取授權方的名稱。

1. 在**測試授權方**下，輸入字符的值。

   如果您使用的是 [`TOKEN` 授權方 Lambda 函數範例](apigateway-use-lambda-authorizer.md#api-gateway-lambda-authorizer-token-lambda-function-create)，請執行以下操作：

   1. 對於 **authorizationToken** 值，輸入 **allow**。

1. 選擇**測試授權方**。

    如果您的 Lambda 授權方成功拒絕測試環境中的請求，測試會以 `200 OK` HTTP 回應來回應。然而，在測試環境之外，API Gateway 會傳回 `403 Forbidden` HTTP 回應，方法請求失敗。

------

## 設定 Lambda 授權方 (AWS CLI)
<a name="configure-api-gateway-lambda-authorization-cli"></a>

以下 [create-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-authorizer.html) 命令指示使用 AWS CLI建立 Lambda 授權方。

------
#### [ REQUEST authorizer ]

以下 [create-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-authorizer.html) 命令會建立 `REQUEST` 授權方，並使用 `Authorizer` 標頭和 `accountId` 內容變數作為身分來源：

```
aws apigateway create-authorizer \
    --rest-api-id 1234123412 \
    --name 'First_Request_Custom_Authorizer' \
    --type REQUEST \
    --authorizer-uri 'arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123412341234:function:customAuthFunction/invocations' \
    --identity-source 'method.request.header.Authorization,context.accountId' \
    --authorizer-result-ttl-in-seconds 300
```

------
#### [ TOKEN authorizer ]

以下 [create-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-authorizer.html) 命令會建立 `TOKEN` 授權方，並使用 `Authorization` 標頭作為身分來源：

```
aws apigateway create-authorizer \
    --rest-api-id 1234123412 \
    --name 'First_Token_Custom_Authorizer' \
    --type TOKEN \
    --authorizer-uri 'arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123412341234:function:customAuthFunction/invocations' \
    --identity-source 'method.request.header.Authorization' \
    --authorizer-result-ttl-in-seconds 300
```

------

建立 Lambda 授權方之後，您可以測試該授權方。以下 [test-invoke-authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigateway/test-invoke-authorizer.html) 命令會測試 Lambda 授權方：

```
aws apigateway test-invoke-authorizer --rest-api-id 1234123412 \
   --authorizer-id efg1234 \
   --headers Authorization='Value'
```

## 設定使用 Lambda 授權方 (主控台) 的方法
<a name="configure-api-gateway-lambda-authorization-method-console"></a>

設定 Lambda 授權方之後，您必須將其連接至 API 的方法。如果您的授權方使用授權快取，請務必更新政策以控制其他方法的存取。

**設定 API 方法使用 Lambda 授權方**

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

1. 選取 API。

1. 選擇**資源**，然後選擇新方法，或選擇現有方法。

1. 在**方法請求**索引標籤的**方法請求設定**下，選擇**編輯**。

1. 針對**授權方**，從下拉式選單選取您剛才建立的 Lambda 授權方。

1.  (選用) 如果您要將授權權杖傳遞至後端，請選擇 **HTTP 請求標頭**。選擇**新增標頭**，然後新增授權標頭的名稱。在**名稱**中，輸入標頭名稱，此名稱須符合您在建立 API 的 Lambda 授權方時指定的**符記來源**名稱。此步驟不適用於 `REQUEST` 授權方。

1. 選擇**儲存**。

1. 選擇**部署 API** 將 API 部署到階段。針對使用階段變數的 `REQUEST` 授權方，您還必須定義必要的階段變數，並在**階段編輯器**頁面上指定這些變數的值。

## 設定使用 Lambda 授權方的方法 (AWS CLI)
<a name="configure-api-gateway-lambda-authorization-method-cli"></a>

設定 Lambda 授權方之後，您必須將其連接至 API 的方法。您可以建立新的方法，或使用修補程式操作，將授權方連接到現有方法。如果您的授權方使用授權快取，請務必更新政策以控制其他方法的存取。

以下 [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) 命令會建立使用 Lambda 授權方的新方法：

```
aws apigateway put-method --rest-api-id 1234123412 \
  --resource-id a1b2c3 \
  --http-method PUT \
  --authorization-type CUSTOM \
  --authorizer-id efg1234
```

以下 [update-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-method.html) 命令會更新現有方法以使用 Lambda 授權方：

```
aws apigateway update-method \
    --rest-api-id 1234123412 \
    --resource-id a1b2c3 \
    --http-method PUT \
    --patch-operations op="replace",path="/authorizationType",value="CUSTOM" op="replace",path="/authorizerId",value="efg1234"
```

# 輸入至 API Gateway Lambda 授權方
<a name="api-gateway-lambda-authorizer-input"></a>

下一節說明從 API Gateway 到 Lambda 授權方的輸入格式。

## `TOKEN` 輸入格式
<a name="w2aac15b9c23c25c19b5"></a>

 針對 `TOKEN` 類型的 Lambda 授權方 (先前稱作自訂授權方)，您必須在設定 API 的授權方時，將自訂標頭指定為**字符來源**。API 用戶端必須在傳入請求中以該標頭傳遞必要的授權符記。收到傳入方法請求時，API Gateway 會從自訂標頭中擷取字符。然後，它會傳遞字符作為 Lambda 函數之 `event` 物件的 `authorizationToken` 屬性，並傳遞方法 ARN 作為 `methodArn` 屬性：

```
{
    "type":"TOKEN",
    "authorizationToken":"{caller-supplied-token}",
    "methodArn":"arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
}
```

 在此範例中，`type` 屬性會指定 `TOKEN` 授權方做為授權方類型。`{caller-supplied-token}` 源自用戶端要求的授權標頭，可以是任何字串值。`methodArn` 是傳入方法請求的 ARN，並會由 API Gateway 根據 Lambda 授權方組態填入。

## `REQUEST` 輸入格式
<a name="w2aac15b9c23c25c19b7"></a>

針對 `REQUEST` 類型的 Lambda 授權方，API Gateway 會將請求參數傳遞到授權方 Lambda 函數，做為 `event` 物件的一部分。請求參數包括標頭、路徑參數、查詢字串參數、階段變數與一些請求上下文變數。API 發起人可以設定路徑參數、標頭與查詢字串參數。API 開發人員必須在 API 部署期間設定階段變數，而 API Gateway 則會在執行時間提供請求內容。

**注意**  
路徑參數可作為請求參數傳遞到 Lambda 授權方函數，但無法作為身分來源使用。

 下列範例顯示具有代理整合之 API 方法 (`REQUEST`) 的 `GET /request` 授權方輸入：

```
{
  "type": "REQUEST",
  "methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request",
  "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"
  }
}
```

 `requestContext` 是鍵值對的對應，並對應到 [\$1context](api-gateway-mapping-template-reference.md#context-variable-reference) 變數。它的結果是與 API 相關。

 API Gateway 可能會將新的金鑰加入至地圖。如需 Lambda 代理整合中 Lambda 函數輸入的詳細資訊，請參閱[代理整合之 Lambda 函數的輸入格式](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-input-format)。

# 來自 API Gateway Lambda 授權方的輸出
<a name="api-gateway-lambda-authorizer-output"></a>

Lambda 授權方函數的輸出是類似字典的物件，其中必須包含主要識別符 (`principalId`) 以及列出政策陳述式的政策文件 (`policyDocument`)。此輸出也可包含由鍵值對組成的 `context` 對應。如果 API 使用用量計劃 ([https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html#apiKeySource](https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html#apiKeySource) 設為 `AUTHORIZER`)，Lambda 授權方函數必須傳回其中一個用量計劃的 API 金鑰做為 `usageIdentifierKey` 屬性值。

以下示範此輸出。

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

****  

```
{
  "principalId": "yyyyyyyy", 
  "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": {
    "stringKey": "value",
    "numberKey": "1",
    "booleanKey": "true"
  },
  "usageIdentifierKey": "{api-key}"
}
```

------

 在本例中，政策陳述式會指定要允許或拒絕 (`Effect`) API Gateway 執行服務呼叫 (`Action`) 指定的 API 方法 (`Resource`)。您可能需要根據您的授權方來控制對多個資源的存取。您可以使用萬用字元 (`*`) 來指定資源類型 (方法)。如需設定有效政策來呼叫 API 的資訊，請參閱「[在 API Gateway 中執行 API 之 IAM 政策的陳述式參考](api-gateway-control-access-using-iam-policies-to-invoke-api.md#api-gateway-calling-api-permissions)」。

針對啟用授權的方法 ARN (例如 `arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]`)，長度上限為 1600 位元組。路徑參數值是在執行時間所決定的大小，可能會導致 ARN 長度超過限制。發生此情況時，API 用戶端會收到 `414 Request URI too long` 回應。

此外，授權方之政策陳述式輸出中所示的資源 ARN 長度目前限制為 512 個字元。因此，您不得在請求 URI 中，使用 JWT 字符長度很長的 URI。反之，您可以在請求標頭中安全傳遞此 JWT 字符。

 您可以使用 `principalId` 變數，來存取對應範本中的 `$context.authorizer.principalId` 值。如果您想要將此值傳遞到後端，這會很有用。如需詳細資訊，請參閱 [資料轉換的內容變數](api-gateway-mapping-template-reference.md#context-variable-reference)。

 您可以分別呼叫 `stringKey`、`numberKey` 或 `booleanKey`，來存取對應範本中 `"value"` 對應的 `"1"`、`"true"` 或 `context` 值 (例如 `$context.authorizer.stringKey`、`$context.authorizer.numberKey` 或 `$context.authorizer.booleanKey`)。傳回的值全部都已字串化。請注意，您無法將 JSON 物件或陣列設定為 `context` 對應中任何金鑰的有效值。

 您可以透過整合請求對應範本，使用 `context` 對應將快取的登入資料從授權方傳回後端。這可讓後端使用快取的登入資料來降低存取秘密金鑰的需求，並開啟每個請求的授權字符，藉此提供改善的使用者體驗。

 對於 Lambda 代理整合，API Gateway 會將 `context` 物件從 Lambda 授權方直接傳遞至後端 Lambda 函式，做為輸入 `event` 的一部分。您可以呼叫 `$event.requestContext.authorizer.key`，來擷取 Lambda 函數中的 `context` 索引鍵/值組。

API 階段用量計劃中，`{api-key}` 代表 API 金鑰。如需詳細資訊，請參閱 [API Gateway 中 REST API 的用量計畫和 API 金鑰](api-gateway-api-usage-plans.md)。

 以下顯示範例 Lambda 授權方的範例輸出。範例輸出包含政策陳述式，可針對 AWS 帳戶 (`Deny`) 的 API () `dev`階段封鎖 (`ymy8tbxw7b`) 對 `GET` 方法的呼叫`123456789012`。

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

****  

```
{
  "principalId": "user",
  "policyDocument": {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Deny",
        "Resource": "arn:aws:execute-api:us-west-2:123456789012:ymy8tbxw7b/dev/GET/"
      }
    ]
  }
}
```

------

# 使用 API Gateway Lambda 授權方呼叫 API
<a name="call-api-with-api-gateway-lambda-authorization"></a>

 設定 Lambda 授權方 (先前稱作自訂授權方) 並部署 API 之後，您應該測試啟用 Lambda 授權方的 API。為此，您需要一個 REST 用戶端，例如 cURL 或 [Postman](https://www.postman.com/)。在下列範例中，我們使用 Postman。

**注意**  
 呼叫啟用授權方的方法時，如果 `TOKEN` 授權方的必要字符未設定、為 Null 或因指定的 **Token validation expression (字符驗證表達式)** 而失效，則 API Gateway 不會將呼叫記錄到 CloudWatch。同樣地，如果 `REQUEST` 授權方的任何必要身分來源未設定、為 Null 或空白，API Gateway 不會將呼叫記錄到 CloudWatch。

 以下示範如何使用 Postman 來呼叫或測試具有 Lambda `TOKEN` 授權方的 API。如果您明確指定必要的路徑、標頭或查詢字串參數，則可以套用此方法呼叫具有 Lambda `REQUEST` 授權方的 API。

**呼叫具有自訂 `TOKEN` 授權方的 API**

1.  開啟 **Postman**，選擇 **GET** 方法，然後將 API 的 **Invoke URL (呼叫 URL)** 貼到相鄰的 URL 欄位中。

    新增 Lambda 授權字符標頭，並將值設定為 `allow`。選擇 **Send (傳送)**。  
![\[使用 Lambda 授權 Allow (允許) 字符呼叫 API\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/custom-auth-call-api-with-allow-token.png)

    回應顯示 API Gateway Lambda 授權方傳回 **200 OK (200 OK)** 回應，並成功授權呼叫存取與方法整合的 HTTP 端點 (http://httpbin.org/get)。

1.  同樣在 Postman 中，將 Lambda 授權字符標頭值變更為 `deny`。選擇 **Send (傳送)**。  
![\[使用 Lambda 授權 Deny (拒絕) 字符呼叫 API\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/custom-auth-call-api-with-deny-token.png)

   回應顯示 API Gateway Lambda 授權方傳回 **403 Forbidden (403 禁止)** 回應，而不授權呼叫存取 HTTP 端點。

1.  在 Postman 中，將 Lambda 授權字符標頭值變更為 `unauthorized`，然後選擇 **Send (傳送)**。  
![\[使用 Lambda 授權 Unauthorized (未經授權) 字符呼叫 API\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/custom-auth-call-api-with-unauthorized-token.png)

    回應顯示 API Gateway 傳回 **401 Unauthorized (401 未經授權)** 回應，而不授權呼叫存取 HTTP 端點。

1.  現在，將 Lambda 授權字符標頭值變更為 `fail`。選擇 **Send (傳送)**。  
![\[使用 Lambda 授權 Fail (失敗) 字符呼叫 API\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/custom-auth-call-api-with-fail-token.png)

    回應顯示 API Gateway 傳回 **500 Internal Server Error (500 內部伺服器錯誤)** 回應，而不授權呼叫存取 HTTP 端點。

# 設定跨帳戶 API Gateway Lambda 授權方
<a name="apigateway-lambda-authorizer-cross-account-lambda-authorizer"></a>

您現在可以使用來自不同 AWS 帳戶的 AWS Lambda 函數做為 API 授權方函數。每個帳戶可以位於 Amazon API Gateway 可用的任何區域。Lambda 授權方函數可以使用承載字符身分驗證策略，例如 OAuth 或 SAML。這可讓您輕鬆地集中管理和分享跨多個 API Gateway API 的中央 Lambda 授權方函數。

在本節中，我們將示範如何使用 Amazon API Gateway 主控台設定跨帳戶 Lambda 授權方功能。

這些指示假設您在一個 AWS 帳戶中已有 API Gateway API，而在另一個帳戶中已有 Lambda 授權方函數。

## 使用 API Gateway 主控台設定跨帳戶 Lambda 授權方
<a name="apigateway-cross-account-lambda-auth-configure-cross-account-authorizer"></a>

在您 API 所在的帳戶中，登入 Amazon API Gateway 主控台，然後執行下列操作：

1. 選擇您的 API，然後在主導覽窗格中選擇**授權方**。

1. 選擇**建立授權方**。

1. 針對**授權方名稱**，輸入授權方的名稱。

1. 針對**授權方類型**，選取 **Lambda**。

1. 對於 **Lambda 函數**，輸入您在第二個帳戶中擁有之 Lambda 授權方函數的完整 ARN。
**注意**  
在 Lambda 主控台中，您可以在主控台視窗的右上角找到適用於您函數的 ARN。

1. 此時會出現包含 `aws lambda add-permission` 命令的警告。此政策會授與 API Gateway 許可，以調用授權方 Lambda 函數。複製指令並儲存，以供日後使用。建立授權方之後，您可以執行命令。

1. 針對 **Lambda 事件承載**，選擇**權杖**代表 `TOKEN` 授權方，或選擇**請求**代表 `REQUEST` 授權方。

1. 根據上一個步驟的選擇，執行下列其中一項操作：

   1.  針對**權杖**選項，執行下列操作：
      + 針對**權杖來源**，輸入包含授權權杖的標頭名稱。API 用戶端必須包含此名稱的標頭，才能將授權字符傳送到 Lambda 授權方。
      + 或者，針對**權杖驗證**，輸入 RegEx 陳述式。API Gateway 會對此表達式執行輸入字符的初始驗證，並在成功驗證時調用授權方。這樣做有助於減少對 API 的呼叫。
      + 若要快取授權方產生的授權政策，請將**授權快取**保持開啟狀態。啟用政策快取時，您可以選擇修改 **TTL** 值。將 **TTL** 設定為零會停用政策快取。啟用政策快取時，**權杖來源**中指定的標頭名稱會成為快取金鑰。如果在請求中將多個值傳遞給此標頭，則所有值都將成為快取金鑰，並會保留順序。
**注意**  
預設 **TTL** 值為 300 秒。最大值為 3600 秒，而且無法增加此限制。

   1. 針對 **請求** 選項，執行下列操作：
      + 針對**身分來源類型**，選取參數類型。支援的參數類型為 `Header`、`Query string`、`Stage variable` 與 `Context`。若要新增更多身分來源，請選擇**新增參數**。
      + 若要快取授權方產生的授權政策，請將**授權快取**保持開啟狀態。啟用政策快取時，您可以選擇修改 **TTL** 值。將 **TTL** 設定為零會停用政策快取。

        API Gateway 使用指定的身分來源作為請求授權方快取金鑰。啟用快取時，只有在成功驗證執行時間存在所有指定的身分來源之後，API Gateway 才會呼叫授權方的 Lambda 函數。如果指定的身分來源遺漏、為 null 或是空白，則 API Gateway 會傳回 `401 Unauthorized` 回應，而不會呼叫授權方 Lambda 函式。

        定義多個身分來源時，會使用這些來源衍生授權方的快取金鑰。變更任何快取金鑰部分都會使授權方捨棄快取的政策文件，並產生新的文件。如果在請求中傳遞具有多個值的標頭，則所有值將成為快取金鑰的一部分，並會保留順序。
      + 快取關閉時，不需指定身分來源。
**注意**  
 若要啟用快取，您的授權方必須傳回適用於 API 之所有方法的政策。若要強制執行方法特定政策，您可以關閉**授權快取**。

1. 選擇**建立授權方**。

1. 將您在上一個步驟中複製的`aws lambda add-permission`命令字串貼到為第二個帳戶設定的 AWS CLI 視窗中。將授權方 ID 取代為 `AUTHORIZER_ID` 。這會授與您的第一個帳戶對第二個帳戶的 Lambda 授權方函數的存取權。

# 利用 Verified Permissions 根據身分的屬性控制存取權
<a name="apigateway-lambda-authorizer-verified-permissions"></a>

使用 Amazon Verified Permissions 控制對 API Gateway API 的存取。當您搭配 Verified Permissions 使用 API Gateway 時，Verified Permissions 會建立 Lambda 授權方，該授權方會使用精細的授權決策來控制對 API 的存取。Verified Permissions 會根據政策存放區結構描述和政策，使用 Cedar 政策語言來授權呼叫者，以定義應用程式使用者的精細許可權。如需詳細資訊，請參閱《*Amazon Verified Permissions 使用者指南*》中的[使用連線 API 和身分提供者建立政策存放區](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/getting-started-api-policy-store.html)。

Verified Permissions 支援 Amazon Cognito 使用者集區或 OpenID Connect (OIDC) 身分提供者做為身分來源。Verified Permissions 假設主體先前已識別，並已驗證身分。Verified Permissions 僅支援區域和邊緣最佳化的 REST API。

## 使用 Verified Permissions 建立 Lambda 授權方
<a name="apigateway-lambda-authorizer-verified-permissions-attach"></a>

Verified Permissions 會建立 Lambda 授權方，用以判斷主體是否可在 API 上採取行動。您可以建立 Verified Permissions 用來執行其授權任務的 Cedar 政策。

以下是一個 Cedar 策略範例，允許 `developer` 群組基於 Amazon Cognito 使用者集區 `us-east-1_ABC1234` 對 API 的 `GET /users` 資源調用 API。Verified Permissions 會剖析呼叫者身分的承載字符來判定群組成員資格。

```
permit(
  principal in MyAPI::UserGroup::"us-east-1_ABC1234|developer",
  action in [ MyAPI::Action::"get /users" ],
  resource
  );
```

或者，Verified Permissions 可以將授權方附加至 API 的方法。在 API 的生產階段，建議您不要允許 Verified Permissions 為您附加授權方。

下列清單顯示如何設定 Verified Permissions，以附加或不附加 Lambda 授權方至 API 方法的方法請求。

**為您附加授權方 (AWS 管理主控台)**  
當您在 Verified Permissions 主控台選擇**建立政策存放區**時，請在**部署應用程式整合**頁面上選擇**現在**。

**請勿為您附加授權方 (AWS 管理主控台)**  
當您在 Verified Permissions 主控台選擇**建立政策存放區**時，請在**部署應用程式整合**頁面上選擇**稍後**。  
Verified Permissions 仍會為您建立 Lambda 授權方。Lambda 授權方以 `AVPAuthorizerLambda-` 開頭。如需有關如何在方法上附加授權方的詳細資訊，請參閱 [設定使用 Lambda 授權方 (主控台) 的方法](configure-api-gateway-lambda-authorization.md#configure-api-gateway-lambda-authorization-method-console)。

**為您附加授權方 (CloudFormation)**  
在 Verified Permissions 產生的 CloudFormation 範本中，在 `Conditions`區段中，將 `"Ref": "shouldAttachAuthorizer"`設定為 `true`。

**請勿為您附加授權方 (CloudFormation)**  
在 Verified Permissions 產生的 CloudFormation 範本中，在 `Conditions`區段中，將 `"Ref": "shouldAttachAuthorizer"`設定為 `false`。  
Verified Permissions 仍會為您建立 Lambda 授權方。Lambda 授權方以 `AVPAuthorizerLambda-` 開頭。如需有關如何在方法上附加授權方的詳細資訊，請參閱 [設定使用 Lambda 授權方的方法 (AWS CLI)](configure-api-gateway-lambda-authorization.md#configure-api-gateway-lambda-authorization-method-cli)。

## 使用 Verified Permissions 呼叫 Lambda 授權方
<a name="apigateway-lambda-authorizer-verified-permissions-call"></a>

您可以在 `Authorization` 標頭中提供身分或存取字符，以呼叫 Lambda 授權方。如需詳細資訊，請參閱[使用 API Gateway Lambda 授權方呼叫 API](call-api-with-api-gateway-lambda-authorization.md)。

API Gateway 會花 120 秒時間快取 Lambda 授權方傳回的政策。您可以在 API Gateway 主控台或使用 AWS CLI修改 TTL。

# 使用 Amazon Cognito 使用者集區做為授權方，藉以控制對 REST API 的存取
<a name="apigateway-integrate-with-cognito"></a>

除了使用 [IAM 角色和政策](permissions.md)或 [Lambda 授權方](apigateway-use-lambda-authorizer.md) (先前稱為自訂授權方) 之外，您還可以使用 [Amazon Cognito 使用者集區](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html)來控制誰可以在 Amazon API Gateway 中存取您的 API。

若要搭配使用 Amazon Cognito 使用者集區與您的 API，您必須先建立 `COGNITO_USER_POOLS` 類型的授權方，然後設定 API 方法使用該授權方。API 部署後，用戶端必須先將使用者登入使用者集區，取得該使用者的[身分或存取字符](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html)，然後透過通常會設定為請求 `Authorization` 標頭的字符其中之一來呼叫 API 方法。API 呼叫只有在您提供有效的字符時才會成功；否則，用戶端無權發出呼叫，因為用戶端沒有可獲得授權的登入資料。

身分字符是根據登入使用者宣告的身分，用來授權 API 呼叫。存取字符是根據指定的受存取保護資源的自訂範圍，用來授權 API 呼叫。如需詳細資訊，請參閱[將字符用於使用者集區](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html)和[資源伺服器和自訂範圍](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-define-resource-servers.html)。

若要為您的 API 建立和設定 Amazon Cognito 使用者集區，您要執行下列任務：
+ 使用 Amazon Cognito 主控台、CLI/SDK 或 API 來建立使用者集區，或使用另一個 AWS 帳戶擁有的使用者集區。
+ 使用 API Gateway 主控台、CLI/軟體開發套件或 API 建立 API Gateway authorizer 與所選的使用者集區。
+ 使用 API Gateway 主控台、CLI/軟體開發套件或 API 在選取的 API 方法中啟用授權方。

 若要在使用者集區啟用的狀況下呼叫任何 API 方法，您的 API 用戶端要執行下列任務：
+  使用 Amazon Cognito CLI/[軟體開發套件](https://github.com/aws/amazon-cognito-identity-js/)或 API 將使用者登入至所選擇的使用者集區，並取得身分字符或存取字符。若要進一步了解如何使用 SDKs，請參閱 [Amazon Cognito AWS SDKs程式碼範例](https://docs.aws.amazon.com/cognito/latest/developerguide/service_code_examples.html)。
+  使用用戶端特定架構呼叫已部署的 API Gateway API，並在 `Authorization` 標頭中提供適當的字符。

身為 API 開發人員，您必須為您的用戶端開發人員提供使用者集區 ID、用戶端 ID，以及定義為使用者集區一部分之相關聯的用戶端密碼 (如可能)。

**注意**  
為了讓使用者使用 Amazon Cognito 登入資料登入，同時取得暫時性登入資料以使用 IAM 角色的許可，請使用 [Amazon Cognito 聯合身分](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html)。對於每個 API 資源端點 HTTP 方法，將授權類型 `Method Execution` 設定為 `AWS_IAM`。

我們會在本節中說明如何建立使用者集區、如何整合 API Gateway API 與使用者集區，以及如何呼叫與使用者集區整合的 API。

**Topics**
+ [為 REST API 建立 Amazon Cognito 使用者集區](apigateway-create-cognito-user-pool.md)
+ [整合 REST API 與 Amazon Cognito 使用者集區](apigateway-enable-cognito-user-pool.md)
+ [呼叫與 Amazon Cognito 使用者集區整合的 REST API](apigateway-invoke-api-integrated-with-cognito-user-pool.md)
+ [使用 API Gateway 主控台為 REST API 設定跨帳戶的 Amazon Cognito 授權方](apigateway-cross-account-cognito-authorizer.md)
+ [使用 為 REST API 建立 Amazon Cognito 授權方 CloudFormation](apigateway-cognito-authorizer-cfn.md)

# 為 REST API 建立 Amazon Cognito 使用者集區
<a name="apigateway-create-cognito-user-pool"></a>

整合您的 API 和使用者集區之前，您必須先在 Amazon Cognito 中建立使用者集區。您的使用者集區組態必須遵循所有 [Amazon Cognito 的資源配額](https://docs.aws.amazon.com/cognito/latest/developerguide/limits.html)。所有使用者定義的 Amazon Cognito 變數 (例如群組、使用者和角色) 僅可使用英數字元。如需如何建立使用者集區的說明，請參閱《Amazon Cognito 開發人員指南》**中的[教學課程：建立使用者集區](https://docs.aws.amazon.com/cognito/latest/developerguide/tutorial-create-user-pool.html)。

請記下使用者集區 ID、用戶端 ID 和任何用戶端密碼。用戶端必須將這些資訊提供給 Amazon Cognito 以讓使用者註冊使用者集區、登入使用者集區，以及取得要包含在請求中的身分或存取字符，來呼叫以使用者集區設定的 API 方法。此外，當您在 API Gateway 中將使用者集區設定為授權方時，必須指定使用者集區名稱，如下所述。

如果您使用存取字符授權 API 方法呼叫，請務必設定應用程式與使用者集區整合，以設定您想要的指定資源伺服器自訂範圍。如需將字符用於 Amazon Cognito 使用者集區的詳細資訊，請參閱[將字符用於使用者集區](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html)。如需資源伺服器的詳細資訊，請參閱[為您的使用者集區定義資源伺服器](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-define-resource-servers.html)。

請記下已設定的資源伺服器識別符和自訂範圍名稱。您需要它們來建構 **OAuth Scopes (OAuth 範圍)** 的存取範圍完整名稱，這是由 `COGNITO_USER_POOLS` 授權方使用。

![\[Amazon Cognito 使用者集區資源伺服器和範圍\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/cognito-user-pool-custom-scopes-new-console.png)


# 整合 REST API 與 Amazon Cognito 使用者集區
<a name="apigateway-enable-cognito-user-pool"></a>

建立 Amazon Cognito 使用者集區後，您必須在 API Gateway 中建立使用該使用者集區的 `COGNITO_USER_POOLS` 授權方。下列程序示範如何使用 API Gateway 主控台來執行此操作。

**注意**  
您可以使用 [https://docs.aws.amazon.com/apigateway/latest/api/API_CreateAuthorizer.html](https://docs.aws.amazon.com/apigateway/latest/api/API_CreateAuthorizer.html) 動作來建立使用多個使用者集區的 `COGNITO_USER_POOLS` 授權者。一個 `COGNITO_USER_POOLS` 授權者最多可以使用 1,000 個使用者集區。此限制無法提高。

**重要**  
執行下列任何程序之後，您需要部署或重新部署您的 API 以傳播變更。如需部署 API 的詳細資訊，請參閱 [在 API Gateway 中部署 REST API](how-to-deploy-api.md)。

**使用 API Gateway 主控台建立 `COGNITO_USER_POOLS` 授權方**

1. 在 API Gateway 中建立新的 API 或選取現有的 API。

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

1. 選擇**建立授權方**。

1. 若要設定新的授權方使用使用者集區，請執行下列操作：

   1.  針對**授權方名稱**，輸入名稱。

   1. 針對**授權方類型**，選取 **Cognito**。

   1. 針對 **Cognito 使用者集區**，選擇您建立 Amazon Cognito AWS 區域 的 ，然後選取可用的使用者集區。

      您可以使用階段變數來定義使用者集區。使用者集區可使用下列格式：`arn:aws:cognito-idp:us-east-2:111122223333:userpool/${stageVariables.MyUserPool}`。

   1.  針對**權杖來源**，輸入 **Authorization** 作為標頭名稱，以在使用者成功登入時，傳遞 Amazon Cognito 傳回的身分或存取權杖。

   1. (選用) 在**權杖驗證**欄位中輸入規則表達式，以驗證身分權杖的 `aud` (對象) 欄位，再透過 Amazon Cognito 授權請求。請注意，當使用存取字符時，由於存取字符不包含該 `aud` 字段，所以此驗證拒絕該請求。

   1. 選擇**建立授權方**。

1. 建立 `COGNITO_USER_POOLS` 授權方之後，您可以提供從使用者集區佈建的身分字符來測試其調用情形。您無法使用存取字符來測試調用授權方。

   您可以呼叫 [Amazon Cognito 身分軟體開發套件](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-integrate-apps.html)來取得此身分字符，藉此執行使用者登入。您也可以使用 [https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html](https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_InitiateAuth.html)​ 動作。如果您未設定任何**授權範圍**，API Gateway 會將提供的權杖視為身分權杖。

上述程序會建立使用新建立之 Amazon Cognito 使用者集區的 `COGNITO_USER_POOLS` 授權方。視您在 API 方法中啟用授權方的方式而定，您可以使用從已整合使用者集區佈建的身分字符或存取字符。

**在方法中設定 `COGNITO_USER_POOLS` 授權方**

1. 選擇**資源**。選擇新方法或選擇現有方法。如有需要，請建立資源。

1. 在**方法請求**索引標籤的**方法請求設定**下，選擇**編輯**。

1. 針對**授權方**，從下拉式選單選取您剛才建立的 **Amazon Cognito 使用者集區授權方**。

1.  若要使用身分字符，請執行下列操作：

   1. 將**授權範圍**保留空白。

   1. 如有需要，在**整合請求**中，於內文對應範本中新增 `$context.authorizer.claims['property-name']` 或 `$context.authorizer.claims.property-name` 表達式，將指定的身分宣告屬性從使用者集區傳遞到後端。對於簡單的屬性名稱，例如 `sub` 或 `custom-sub`，兩個表示法完全相同。至於複雜的屬性名稱，例如 `custom:role`，則無法使用點表示法。例如，下列映射表達式會將宣告的[標準欄位](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims) `sub` 和 `email` 傳送到後端：

      ```
      {
      	"context" : {
      		"sub" : "$context.authorizer.claims.sub",
      		"email" : "$context.authorizer.claims.email"
      	}
      }
      ```

      如已在設定使用者集區時宣告自訂的宣告欄位，您可以遵循相同的模式來存取自訂欄位。下列範例會取得自訂的宣告 `role` 欄位：

      ```
      {
      	"context" : {
      		"role" : "$context.authorizer.claims.role"
          }
      }
      ```

      如果自訂宣告欄位宣告為 `custom:role`，請使用下列範例來取得宣告的屬性：

      ```
      {
      	"context" : {
      		"role" : "$context.authorizer.claims['custom:role']"
          }
      }
      ```

1.  若要使用存取字符，請執行下列操作：

   1. 針對**授權範圍**，輸入在建立 Amazon Cognito 使用者集區時所設定之範圍的一或多個完整名稱。例如，在 [為 REST API 建立 Amazon Cognito 使用者集區](apigateway-create-cognito-user-pool.md) 提供的範例之後，其中一個範圍是 `https://my-petstore-api.example.com/cats.read`。

      在執行時間，如果在這個步驟中，方法內指定的任何範圍符合傳入字符宣告的範圍，則方法呼叫就會成功。否則，呼叫失敗並傳回 `401 Unauthorized` 回應。

   1.  選擇**儲存**。

1. 為您選擇的其他方法重複這些步驟。

使用 `COGNITO_USER_POOLS` 授權方，如果不指定 **OAuth Scopes (OAuth 範圍)** 選項，API Gateway 會將提供的字符視為身分字符，並使用使用者集區中的身分來驗證宣告的身分。否則，API Gateway 會將提供的字符視為存取字符，並根據方法中宣告的授權範圍來驗證字符中宣告的存取範圍。

除了使用 API Gateway 主控台之外，您也可以指定 OpenAPI 定義檔並將 API 定義匯入 API Gateway，在方法中啟用 Amazon Cognito 使用者集區。

**使用 OpenAPI 定義檔匯入 COGNITO\$1USER\$1POOLS 授權方**

1. 為您的 API 建立 (或匯出) OpenAPI 定義檔。

1. 指定 `COGNITO_USER_POOLS` 授權方 (`MyUserPool`) JSON 定義，做為 OpenAPI 3.0 的 `securitySchemes` 部分或 Open API 2.0 的 `securityDefinitions` 部分，如下所示：

------
#### [ OpenAPI 3.0 ]

   ```
     "securitySchemes": {
       "MyUserPool": {
         "type": "apiKey",
         "name": "Authorization",
         "in": "header",
         "x-amazon-apigateway-authtype": "cognito_user_pools",
         "x-amazon-apigateway-authorizer": {
           "type": "cognito_user_pools",
           "providerARNs": [
             "arn:aws:cognito-idp:{region}:{account_id}:userpool/{user_pool_id}"
           ]
         }
       }
   ```

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

   ```
     "securityDefinitions": {
       "MyUserPool": {
         "type": "apiKey",
         "name": "Authorization",
         "in": "header",
         "x-amazon-apigateway-authtype": "cognito_user_pools",
         "x-amazon-apigateway-authorizer": {
           "type": "cognito_user_pools",
           "providerARNs": [
             "arn:aws:cognito-idp:{region}:{account_id}:userpool/{user_pool_id}"
           ]
         }
       }
   ```

------

1. 若要使用身分字符授權方法，請將 `{ "MyUserPool": [] }` 新增到方法的 `security` 定義，如下列根資源中的 GET 方法所示。

   ```
     "paths": {
       "/": {
         "get": {
           "consumes": [
             "application/json"
           ],
           "produces": [
             "text/html"
           ],
           "responses": {
             "200": {
               "description": "200 response",
               "headers": {
                 "Content-Type": {
                   "type": "string"
                 }
               }
             }
           },
           "security": [
             {
               "MyUserPool": []
             }
           ],        
           "x-amazon-apigateway-integration": {
             "type": "mock",
             "responses": {
               "default": {
                 "statusCode": "200",
                 "responseParameters": {
                   "method.response.header.Content-Type": "'text/html'"
                 },
               }
             },
             "requestTemplates": {
               "application/json": "{\"statusCode\": 200}"
             },
             "passthroughBehavior": "when_no_match"
           }
         },
         ...
      }
   ```

1.  若要使用存取字符授權方法，請將上述安全性定義變更為 `{ "MyUserPool": [resource-server/scope, ...] }`：

   ```
     "paths": {
       "/": {
         "get": {
           "consumes": [
             "application/json"
           ],
           "produces": [
             "text/html"
           ],
           "responses": {
             "200": {
               "description": "200 response",
               "headers": {
                 "Content-Type": {
                   "type": "string"
                 }
               }
             }
           },
           "security": [
             {
               "MyUserPool": ["https://my-petstore-api.example.com/cats.read", "http://my.resource.com/file.read"]
             }
           ],        
           "x-amazon-apigateway-integration": {
             "type": "mock",
             "responses": {
               "default": {
                 "statusCode": "200",
                 "responseParameters": {
                   "method.response.header.Content-Type": "'text/html'"
                 },
               }
             },
             "requestTemplates": {
               "application/json": "{\"statusCode\": 200}"
             },
             "passthroughBehavior": "when_no_match"
           }
         },
         ...
      }
   ```

1. 如有需要，您可以使用適當的 OpenAPI 定義或延伸，設定其他的 API 組態設定。如需詳細資訊，請參閱[API Gateway 的 OpenAPI 擴充功能](api-gateway-swagger-extensions.md)。

# 呼叫與 Amazon Cognito 使用者集區整合的 REST API
<a name="apigateway-invoke-api-integrated-with-cognito-user-pool"></a>

若要呼叫已設定使用者集區授權方的方法，用戶端必須執行下列操作：
+ 讓使用者以使用者集區註冊。
+ 讓使用者登入使用者集區。
+ 從使用者集區取得已登入使用者的[身分或存取字符](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html)。
+ 在 `Authorization` 標頭 (或您在建立授權方時指定的另一個標頭) 中包含字符。

您可以使用 [AWS Amplify]() 來執行這些任務。如需詳細資訊，請參閱[將 Amazon Cognito 與 Web 和行動應用程式整合](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-integrate-apps.html)。
+ 如果是 Android 版，請參閱 [Android 版 Amplify 入門](https://docs.amplify.aws/android/build-a-backend/auth/)。
+ 若要使用 iOS，請參閱 [iOS 版 Amplify 入門](https://docs.amplify.aws/swift/build-a-backend/auth/)。
+ 若要使用 JavaScript，請參閱 [JavaScript 版 Amplify 入門](https://docs.amplify.aws/javascript/build-a-backend/auth/)。

# 使用 API Gateway 主控台為 REST API 設定跨帳戶的 Amazon Cognito 授權方
<a name="apigateway-cross-account-cognito-authorizer"></a>

您現在可以使用來自不同 AWS 帳戶的 Amazon Cognito 使用者集區做為您的 API 授權方。Amazon Cognito 使用者集區可以使用承載字符身分驗證政策，例如 OAuth 或 SAML。這可讓您輕鬆集中管理並跨多個 API Gateway API 共用一個中央 Amazon Cognito 使用者集區授權方。

在本節中，我們示範如何使用 Amazon API Gateway 主控台設定跨帳戶的 Amazon Cognito 使用者集區。

這些指示假設您在一個 AWS 帳戶中已有 API Gateway API，而另一個帳戶中已有 Amazon Cognito 使用者集區。

## 為 REST API 設定跨帳戶 Amazon Cognito 授權方
<a name="apigateway-configure-cross-account-cognito-authorizer"></a>

在您 API 所在的帳戶中，登入 Amazon API Gateway 主控台，然後執行下列操作：

1. 在 API Gateway 中建立新的 API 或選取現有的 API。

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

1. 選擇**建立授權方**。

1. 若要設定新的授權方使用使用者集區，請執行下列操作：

   1.  針對**授權方名稱**，輸入名稱。

   1. 針對**授權方類型**，選取 **Cognito**。

   1. 針對 **Cognito 使用者集區**，輸入您在第二個帳戶中擁有之使用者集區的完整 ARN。
**注意**  
在 Amazon Cognito 主控台中，您可以在 **General Settings (一般設定)** 窗格的 **Pool ARN (集區 ARN)** 欄位中找到適用於您使用者集區的 ARN。

   1.  針對**權杖來源**，輸入 **Authorization** 作為標頭名稱，以在使用者成功登入時，傳遞 Amazon Cognito 傳回的身分或存取權杖。

   1. (選用) 在**權杖驗證**欄位中輸入規則表達式，以驗證身分權杖的 `aud` (對象) 欄位，再透過 Amazon Cognito 授權請求。請注意，當使用存取字符時，由於存取字符不包含該 `aud` 字段，所以此驗證拒絕該請求。

   1. 選擇**建立授權方**。

# 使用 為 REST API 建立 Amazon Cognito 授權方 CloudFormation
<a name="apigateway-cognito-authorizer-cfn"></a>

您可以使用 CloudFormation 建立 Amazon Cognito 使用者集區和 Amazon Cognito 授權方。範本範例 CloudFormation 會執行下列動作：
+ 建立 Amazon Cognito 使用者集區。用戶端必須先將使用者登入使用者集區，並取得[身分或存取字符](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html)。如果您使用存取字符授權 API 方法呼叫，請務必設定應用程式與使用者集區整合，以設定您想要的指定資源伺服器自訂範圍。
+ 使用 `GET` 方法建立 API Gateway API。
+ 建立使用 `Authorization` 標頭作為字符來源的 Amazon Cognito 授權方。

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  UserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      AccountRecoverySetting:
        RecoveryMechanisms:
          - Name: verified_phone_number
            Priority: 1
          - Name: verified_email
            Priority: 2
      AdminCreateUserConfig:
        AllowAdminCreateUserOnly: true
      EmailVerificationMessage: The verification code to your new account is {####}
      EmailVerificationSubject: Verify your new account
      SmsVerificationMessage: The verification code to your new account is {####}
      VerificationMessageTemplate:
        DefaultEmailOption: CONFIRM_WITH_CODE
        EmailMessage: The verification code to your new account is {####}
        EmailSubject: Verify your new account
        SmsMessage: The verification code to your new account is {####}
    UpdateReplacePolicy: Retain
    DeletionPolicy: Retain
  CogAuthorizer:
    Type: AWS::ApiGateway::Authorizer
    Properties:
      Name: CognitoAuthorizer
      RestApiId:
        Ref: Api
      Type: COGNITO_USER_POOLS
      IdentitySource: method.request.header.Authorization
      ProviderARNs:
        - Fn::GetAtt:
            - UserPool
            - Arn
  Api:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Name: MyCogAuthApi
  ApiDeployment:
    Type: AWS::ApiGateway::Deployment
    Properties:
      RestApiId:
        Ref: Api
    DependsOn:
      - CogAuthorizer
      - ApiGET
  ApiDeploymentStageprod:
    Type: AWS::ApiGateway::Stage
    Properties:
      RestApiId:
        Ref: Api
      DeploymentId:
        Ref: ApiDeployment
      StageName: prod
  ApiGET:
    Type: AWS::ApiGateway::Method
    Properties:
      HttpMethod: GET
      ResourceId:
        Fn::GetAtt:
          - Api
          - RootResourceId
      RestApiId:
        Ref: Api
      AuthorizationType: COGNITO_USER_POOLS
      AuthorizerId:
        Ref: CogAuthorizer
      Integration:
        IntegrationHttpMethod: GET
        Type: HTTP_PROXY
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets
Outputs:
  ApiEndpoint:
    Value:
      Fn::Join:
        - ""
        - - https://
          - Ref: Api
          - .execute-api.
          - Ref: AWS::Region
          - "."
          - Ref: AWS::URLSuffix
          - /
          - Ref: ApiDeploymentStageprod
          - /
```

# API Gateway 中 REST API 的整合
<a name="how-to-integration-settings"></a>

 設定 API 方法後，您必須整合它與後端的端點。後端端點也稱為整合端點，可以是 Lambda 函數、HTTP 網頁或服務 AWS 動作。

如同使用 API 方法一樣，API 整合有整合請求和整合回應。整合請求會封裝後端收到的 HTTP 請求。它可能會，也可能不會與用戶端提交的方法不同。整合回應是封裝後端傳回輸出的 HTTP 回應。

設定整合請求包括以下內容：設定如何將用戶端提交的方法請求傳送到後端；設定如何轉換請求資料，如有必要，轉換成整合請求資料；指定呼叫哪個 Lambda 函數、指定傳入請求要轉送到哪個 HTTP 伺服器，或指定要叫用的 AWS 服務動作。

設定只適用於非代理整合的整合回應，包括下列內容：設定如何將後端傳回的結果傳送到指定狀態碼的方法回應、設定如何將指定的整合回應參數轉換成預先設定的方法回應參數、以及設定如何根據指定的內文映射範本，將整合回應內文映射到方法回應內文。

以程式設計方式，整合請求由 [https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html) 資源封裝，而整合回應由 API Gateway 的 [https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html) 資源回應。

若要設定整合請求，您要建立 [https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html) 資源，並用它設定整合端點 URL。然後，設定 IAM 許可以存取後端，並指定映射以轉換傳入的請求資料，然後將它傳送到後端。若要設定非代理整合的整合回應，您要建立 [https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html) 資源，並用它設定其目標方法回應。然後，設定如何將後端輸出映射到方法回應。

**Topics**
+ [在 API Gateway 中設定整合請求](api-gateway-integration-settings-integration-request.md)
+ [在 API Gateway 中設定整合回應](api-gateway-integration-settings-integration-response.md)
+ [API Gateway 中 REST API 的 Lambda 整合](set-up-lambda-integrations.md)
+ [API Gateway 中 REST API 的 HTTP 整合](setup-http-integrations.md)
+ [在 API Gateway 中串流代理整合的整合回應](response-transfer-mode.md)
+ [API Gateway 中 REST API 的私有整合](private-integration.md)
+ [API Gateway 中 REST API 的模擬整合](how-to-mock-integration.md)

# 在 API Gateway 中設定整合請求
<a name="api-gateway-integration-settings-integration-request"></a>

若要設定整合請求，您要執行下列必要和選用任務：

1.  選擇決定如何將方法請求資料傳送到後端的整合類型。

1.  針對非模擬整合，指定 HTTP 方法和目標整合端點的 URI，`MOCK` 整合除外。

1.  對於與 Lambda 函數和其他 AWS 服務動作的整合，請設定具有必要許可的 IAM 角色，讓 API Gateway 代表您呼叫後端。

1.  針對非代理整合，設定必要的參數映射，將預先定義的方法請求參數映射到合適的整合請求參數。

1.  針對非代理整合，設定必要的內文映射，根據指定的映射範本映射傳入的特定內容類型方法請求內文。

1.  針對非代理整合，指定依現狀將傳入的方法請求資料傳送到後端的條件。

1.  (選擇性) 也可以指定如何處理二進位承載的類型轉換。

1.  (選擇性) 宣告快取命名空間名稱和快取金鑰參數，啟用 API 快取。

 執行這些任務包括建立 API Gateway 的[整合](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html)資源，以及設定適當的屬性值。您可以使用 API Gateway 主控台、 AWS CLI 命令、 AWS SDK 或 API Gateway REST API 來執行此操作。

**Topics**
+ [API 整合請求的基本任務](integration-request-basic-setup.md)
+ [選擇 API Gateway API 整合類型](api-gateway-api-integration-types.md)
+ [設定代理整合與代理資源](api-gateway-set-up-simple-proxy.md)
+ [使用 API Gateway 主控台設定 API 整合請求](how-to-method-settings-console.md)

# API 整合請求的基本任務
<a name="integration-request-basic-setup"></a>

 整合請求是一項 HTTP 請求，由 API Gateway 提交到後端，隨用戶端提交的請求資料一併傳送，並在必要時轉換資料。HTTP 方法 (或動詞) 和整合請求的 URI 是由後端 (即整合端點) 提出。它們分別和方法請求的 HTTP 方法和 URI 可以相同或不同。

例如，當 Lambda 函數傳回從 Amazon S3 擷取的檔案時，您可以直覺地向用戶端公開此操作為 `GET` 方法請求，即使對應的整合請求需要使用 `POST` 請求呼叫 Lambda 函數。若為 HTTP 端點，有可能方法請求和對應的整合請求都使用相同的 HTTP 動詞。不過，這不是必要的。您可以整合以下方法請求：

```
GET /{var}?query=value
Host: api.domain.net
```

使用以下整合請求：

```
POST /
Host: service.domain.com
Content-Type: application/json
Content-Length: ...

{
   path: "{var}'s value",
   type: "value"
}
```

 身為 API 開發人員，您可以使用任何滿足您需求的方法請求 HTTP 動詞和 URI。但是，您必須遵循整合端點的需求。當方法請求資料和整合請求資料不同時，您可以提供方法請求資料到整合請求資料的映射，以調節差異。

在上述範例中，映射會將 `{var}` 方法請求的路徑變數 (`query`) 和查詢參數 (`GET`) 值轉譯為整合請求承載屬性 `path` 和 `type` 的值。其他可映射請求資料包括請求標頭和內文。「[API Gateway 中 REST API 的參數映射](rest-api-parameter-mapping.md)」中會詳加說明。

設定 HTTP 或 HTTP 代理整合請求時，您要將後端 HTTP 端點 URL 指派為整合請求 URI 值。例如，在 PetStore API 中，取得寵物頁面的方法請求有以下整合請求 URI：

```
http://petstore-demo-endpoint.execute-api.com/petstore/pets
```

設定 Lambda 或 Lambda 代理整合時，您要將呼叫 Lambda 函數的 Amazon Resource Name (ARN) 指派為整合請求 URI 值。此 ARN 的格式如下：

```
arn:aws:apigateway:api-region:lambda:path//2015-03-31/functions/arn:aws:lambda:lambda-region:account-id:function:lambda-function-name/invocations
```

`arn:aws:apigateway:api-region:lambda:path/` 後面的部分，亦即 `/2015-03-31/functions/arn:aws:lambda:lambda-region:account-id:function:lambda-function-name/invocations`，是 Lambda [Invoke](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html) 動作的 REST API URI 路徑。如果您使用 API Gateway 主控台設定 Lambda 整合，API Gateway 就會建立 ARN，並在提示您從區域選擇 `lambda-function-name` 後，將它指派給整合 URI。

使用另一個 AWS 服務動作設定整合請求時，整合請求 URI 也是 ARN，類似於與 Lambda `Invoke`動作的整合。例如，與 Amazon S3 [GetBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html) 動作的整合，其整合請求 URI 是以下格式的 ARN：

```
arn:aws:apigateway:api-region:s3:path/{bucket}
```

整合請求 URI 是指定動作的路徑慣例，其中 `{bucket}` 是儲存貯體名稱的預留位置。或者，可以透過其名稱來參考 AWS 服務動作。使用動作名稱，Amazon S3 `GetBucket` 動作的整合請求 URI 會變成如下：

```
arn:aws:apigateway:api-region:s3:action/GetBucket
```

使用動作型整合請求 URI，您必須在整合請求內文 (`{bucket}`) 中指定儲存貯體名稱 (`{ Bucket: "{bucket}" }`)，遵循 `GetBucket` 動作的輸入格式。

對於 AWS 整合，您還必須設定[登入](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html#credentials)資料，以允許 API Gateway 呼叫整合的動作。您可以針對 API Gateway 建立新的或選擇現有的 IAM 角色來呼叫動作，然後使用其 ARN 指定角色。以下所示為此 ARN 範例：

```
arn:aws:iam::account-id:role/iam-role-name
```

此 IAM 角色必須包含允許執行動作的政策。它還必須讓 API Gateway 宣告 (在角色的信任關係中) 為信任的實體以擔任該角色。這種許可能夠授予動作本身。它們稱為資源型許可。針對 Lambda 整合，您可以呼叫 Lambda 的 [addPermission](https://docs.aws.amazon.com/lambda/latest/dg/API_AddPermission.html) 動作來設定資源型許可，然後在 API Gateway 整合請求中將 `credentials` 設定為 null。

我們已討論過基本的整合設定。進階設定涉及將方法請求資料映射到整合請求資料。如需詳細資訊，請參閱[API Gateway 中用於 REST API 的資料轉換](rest-api-data-transformations.md)。

# 選擇 API Gateway API 整合類型
<a name="api-gateway-api-integration-types"></a>



 您可以根據您要使用的整合端點類型以及希望資料移入移出整合端點的方式，選擇 API 整合類型。對於 Lambda 函數，您可以擁有 Lambda 代理整合或 Lambda 自訂整合。HTTP 端點可以有 HTTP 代理整合或 HTTP 自訂整合。對於 AWS 服務動作，您只能 AWS 整合非代理類型。API Gateway 也支援以 API Gateway 作為整合端點回應方法請求的模擬整合。

Lambda 自訂整合是 AWS 整合的特殊案例，其中整合端點對應至 Lambda [服務的函數叫用動作](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html)。

您可以程式設計的方式，在 [https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html) 資源上設定 [https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html#type](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html#type) 屬性，來選擇整合類型。Lambda 代理整合的值為 `AWS_PROXY`。至於 Lambda 自訂整合和所有其他 AWS 整合，其值為 `AWS`。HTTP 代理整合和 HTTP 整合的值分別為 `HTTP_PROXY` 和 `HTTP`。若為模擬整合，`type` 值為 `MOCK`。

Lambda 代理整合支援以單一 Lambda 函數簡化的整合設定。設定很簡單，而且可隨後端發展，不必縮減現有的設定。基於這些原因，強烈建議您用於使用 Lambda 函數的整合。

反之，Lambda 自訂整合允許輸入和輸出資料格式有類似需求的各種整合端點，重複使用設定的映射範本。更進階的應用程式案例中，建議使用更為複雜的設定。

同樣地，HTTP 代理整合有簡化的整合設定，可隨後端發展，不必縮減現有的設定。HTTP 自訂整合與設定更密切，但允許其他整合端點重複使用設定的映射範本。

以下清單摘要說明支援的整合類型：
+ `AWS`：這類整合可讓 API 公開 AWS 服務動作。在 `AWS` 整合中，您必須同時設定整合請求和整合回應，並設定從方法請求到整合請求以及從整合回應到方法回應的必要資料映射。
+  `AWS_PROXY`：這類整合可將 API 方法與 Lambda 函數叫用動作，以靈活、多樣化和簡化的整合設定進行整合。這個整合依賴用戶端和已整合 Lambda 函數之間的直接互動。

  使用這類整合，也稱為 Lambda 代理整合，您就不需要設定整合請求或整合回應。API Gateway 將來自用戶端的傳入請求當作輸入傳送到後端 Lambda 函數。已整合的 Lambda 函數採用[此格式的輸入](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-input-format)並剖析所有可用來源的輸入，包括請求標頭、URL 路徑變數、查詢字串參數和適用的內文。函數會按照這個[輸出格式](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-output-format)傳回結果。

  這是透過 API Gateway 呼叫 Lambda 函數的偏好整合類型，不適用於任何其他 AWS 服務動作，包括函數叫用動作以外的 Lambda 動作。
+ `HTTP`：這類整合可讓 API 公開後端的 HTTP 端點。使用 `HTTP` 整合，也稱為 HTTP 自訂整合，您必須設定整合請求和整合回應，缺一不可。您必須設定從方法請求到整合請求以及從整合回應到方法回應的必要資料映射。
+  `HTTP_PROXY`：HTTP 代理整合可讓用戶端使用單一 API 方法的簡化整合設定，存取後端的 HTTP 端點。您不用設定整合請求或整合回應。API Gateway 會將傳入請求從用戶端傳送到 HTTP 端點，將傳出回應從 HTTP 端點傳送到用戶端。
+ `MOCK`：這類整合可讓 API Gateway 傳回回應，卻無需進一步將請求傳送到後端。這對 API 測試很有用，因為它可用來測試整合設定，卻不會產生使用後端的費用，而且可以啟用 API 協作開發。

  在協作開發中，小組可以使用 `MOCK` 整合設定模擬其他小組擁有的 API 元件，區隔他們的開發成果。它也可用來傳回 CORS 相關的標頭，確保 API 方法允許 CORS 存取。事實上，API Gateway 主控台會整合 `OPTIONS` 方法以模擬整合支援 CORS。[閘道回應](api-gateway-gatewayResponse-definition.md#customize-gateway-responses)是其他模擬整合的範例。

# 設定代理整合與代理資源
<a name="api-gateway-set-up-simple-proxy"></a>

若要在具有[代理資源](api-gateway-method-settings-method-request.md#api-gateway-proxy-resource)的 API Gateway API 中設定代理整合，您可以執行下列任務：
+ 使用 Greedy 路徑變數 `{proxy+}` 建立代理資源。
+ 在代理資源上設定 `ANY` 方法。
+ 使用 HTTP 或 Lambda 整合類型來整合資源/方法與後端。

**注意**  
Greedy 路徑變數、`ANY` 方法與代理整合類型是獨立功能，但通常會一起使用。您可以在 Greedy 資源上設定特定 HTTP 方法，或將非代理整合類型套用至代理資源。

使用 Lambda 代理整合或 HTTP 代理整合處理方法時，API Gateway 會實施特定約束與限制。如需詳細資訊，請參閱[Amazon API Gateway 重要說明](api-gateway-known-issues.md)。

**注意**  
 搭配傳遞使用代理整合時，如果未指定承載的內容類型，API Gateway 會傳回預設的 `Content-Type:application/json` 標頭。

使用 HTTP 代理整合或 Lambda 代理[整合](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html)與後端整合時，代理資源最強大。

## HTTP 代理整合與代理資源
<a name="api-gateway-proxy-integration-types"></a>

HTTP 代理整合是由 API Gateway REST API 中的 `HTTP_PROXY` 所指定，適用於整合方法請求與後端 HTTP 端點。有了此整合類型，API Gateway 可根據特定[約束與限制](api-gateway-known-issues.md)，直接在前端與後端之間傳遞整個請求與回應。

**注意**  
HTTP 代理整合支援多值標頭和查詢字串。

將 HTTP 代理整合套用至代理資源時，您可以設定 API 透過單一整合設定，公開 HTTP 後端的部分或整個端點階層。例如，假設網站的後端從根節點 (`/site`) 組織成樹狀目錄節點的多個分支：`/site/a0/a1/.../aN`、`/site/b0/b1/.../bM` 等等。如果您將 `ANY` 之代理資源上的 `/api/{proxy+}` 方法與 `/site/{proxy}` 之 URL 路徑的後端端點整合，單一整合請求可支援任何 `[a0, a1, ..., aN, b0, b1, ...bM, ...]` 上的 HTTP 操作 (GET、POST 等)。如果您將代理整合套用至特定 HTTP 方法 (例如 `GET`)；相反地，產生的整合請求適用於任何後端節點上的指定 (也就是 `GET`) 操作。

## Lambda 代理整合與代理資源
<a name="lambda-proxy-integration-with-proxy-resource"></a>

Lambda 代理整合是由 API Gateway REST API 中的 `AWS_PROXY` 所指定，適用於整合方法請求與後端 Lambda 函數。有了此整合類型，API Gateway 可套用預設映射範本將整個請求傳送到 Lambda 函數，並將來自 Lambda 函數的輸出轉換成 HTTP 回應。

同樣地，您可以將 Lambda 代理整合套用至 `/api/{proxy+}` 的代理資源來設定單一整合，讓後端 Lambda 函數對 `/api` 下的任何 API 資源變更個別做出回應。

# 使用 API Gateway 主控台設定 API 整合請求
<a name="how-to-method-settings-console"></a>

 API 方法設定會定義方法並描述其行為。若要設定方法，您必須指定資源，包括公開方法的根目錄 ("/")、HTTP 方法 (`GET`、`POST` 等等)，以及與目標後端整合的方法。方法請求和回應會指定呼叫應用程式的合約，規定 API 收到哪些參數以及回應的外觀。

 下列程序說明如何使用 API Gateway 主控台來建立整合請求。

**Topics**
+ [設定 Lambda 整合](#how-to-method-settings-console-lambda)
+ [設定 HTTP 整合](#how-to-method-settings-console-http)
+ [設定 AWS 服務整合](#how-to-method-settings-console-aws)
+ [設定模擬整合](#how-to-method-settings-console-mock)

## 設定 Lambda 整合
<a name="how-to-method-settings-console-lambda"></a>

使用 Lambda 函數整合，將您的 API 與 Lambda 函數整合。在 API 層級，如果您建立非代理整合，則這會是 `AWS` 整合類型，如果您建立代理整合，則這會是 `AWS_PROXY` 整合類型。

**設定 Lambda 整合**

1. 在**資源**窗格中，選擇**建立方法**。

1. 針對**方法類型**，選取 HTTP 方法。

1. 對於 **Integration type** (整合類型)，請選擇 **Lambda function** (Lambda 函數)。

1. 若要使用 Lambda 代理整合，請開啟 **Lambda 代理整合**。若要深入了解 Lambda 代理整合，請參閱 [了解 API Gateway Lambda 代理整合](set-up-lambda-proxy-integrations.md#api-gateway-create-api-as-simple-proxy)。

1. 針對 **Lambda 函數**，輸入 Lambda 函數的名稱。

    如果您在與 API 不同的區域中使用 Lambda 函數，請從下拉式選單中選取區域，並輸入 Lambda 函數的名稱。如果您使用的是跨帳戶 Lambda 函數，請輸入函數 ARN。

1. 若要使用 29 秒的預設逾時值，請將**預設逾時**保持開啟。若要設定自訂逾時，請選擇**預設逾時**，然後輸入介於 `50` 和 `29000` 毫秒之間的逾時值。

1. (選用) 您可以使用下列下拉式選單來配置方法請求設定值。選擇**方法請求設定**，並設定您的方法請求。如需詳細資訊，請參閱 [在 API Gateway 主控台編輯 API Gateway 方法請求](how-to-set-up-method-using-console.md#how-to-method-settings-callers-console) 的步驟 3。

   您也可以在建立方法後配置方法請求設定值。

1. 選擇**建立方法**。

## 設定 HTTP 整合
<a name="how-to-method-settings-console-http"></a>

使用 HTTP 整合將您的 API 與 HTTP 端點整合。在 API 層級，這是 `HTTP` 整合類型。

**設定 HTTP 整合**

1. 在**資源**窗格中，選擇**建立方法**。

1. 針對**方法類型**，選取 HTTP 方法。

1. 對於**整合類型**，選擇 **HTTP**。

1. 若要使用 HTTP 代理整合，請開啟 **HTTP 代理整合**。若要進一步了解 HTTP 代理整合，請參閱 [在 API Gateway 中設定 HTTP 代理整合](setup-http-integrations.md#api-gateway-set-up-http-proxy-integration-on-proxy-resource)。

1. 針對 **HTTP method (HTTP 方法)**，選擇最符合 HTTP 後端中方法的 HTTP 方法類型。

1. 針對**端點 URL**，輸入您希望此方法使用之 HTTP 後端的 URL。

1. 針對**內容處理**，選取內容處理行為。

1. 若要使用 29 秒的預設逾時值，請將**預設逾時**保持開啟。若要設定自訂逾時，請選擇**預設逾時**，然後輸入介於 `50` 和 `29000` 毫秒之間的逾時值。

1. (選用) 您可以使用下列下拉式選單來配置方法請求設定值。選擇**方法請求設定**，並設定您的方法請求。如需詳細資訊，請參閱 [在 API Gateway 主控台編輯 API Gateway 方法請求](how-to-set-up-method-using-console.md#how-to-method-settings-callers-console) 的步驟 3。

   您也可以在建立方法後配置方法請求設定值。

1. 選擇**建立方法**。

## 設定 AWS 服務整合
<a name="how-to-method-settings-console-aws"></a>

使用 AWS 服務整合將您的 API 直接與 AWS 服務整合。在 API 層級，這是 `AWS` 整合類型。

若要設定 API Gateway API，請執行下列任一個動作：
+ 建立新 Lambda 函數。
+ 在 Lambda 函數上設定資源許可。
+ 執行任何其他 Lambda 服務動作。

您必須選擇 **AWS 服務**。

**設定 AWS 服務整合**

1. 在**資源**窗格中，選擇**建立方法**。

1. 針對**方法類型**，選取 HTTP 方法。

1. 對於**整合類型**，選擇 **AWS 服務**。

1. 針對**AWS 區域**，選擇 AWS 您希望此方法用來呼叫 動作的區域。

1. 針對**AWS 服務**，選擇您希望此方法呼叫 AWS 的服務。

1.  針對**AWS 子網域**，輸入 AWS 服務所使用的子網域。這個項目一般會保持空白。有些 AWS 服務可支援子網域做為主機的一部分。請參閱服務文件以了解可用性及詳細資訊 (如有)。

1. 針對 **HTTP method (HTTP 方法)**，選擇對應動作的 HTTP 方法類型。對於 HTTP 方法類型，請參閱您為 AWS 服務選擇之**AWS 服務的** API 參考文件。

1. 針對**動作類型**，選取**使用動作名稱**以使用 API 動作，或選取**使用路徑覆寫**以使用自訂資源路徑。如需可用的動作和自訂資源路徑，請參閱您為 AWS 服務選擇之**AWS 服務的** API 參考文件。

1. 輸入**動作名稱**或**路徑覆寫**。

1. 針對**執行角色**，輸入方法將用於呼叫動作之 IAM 角色的 ARN。

   若要建立 IAM 角色，您可以調整 [步驟 1：建立 AWS 服務代理執行角色](getting-started-aws-proxy.md#getting-started-aws-proxy-add-roles) 中的指示。指定包含所需動作數和資源陳述式的存取政策。如需詳細資訊，請參閱[Amazon API Gateway 與 IAM 搭配運作的方式](security_iam_service-with-iam.md)。

   如需動作和資源陳述式語法，請參閱您為 AWS 服務選擇**AWS 之服務**的文件。

   如需 IAM 角色的信任關係，請指定以下動作，讓 API Gateway 代表您的 AWS 帳戶採取行動：

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

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Sid": "",
         "Effect": "Allow",
         "Principal": {
           "Service": "apigateway.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   ```

------

1. 若要使用 29 秒的預設逾時值，請將**預設逾時**保持開啟。若要設定自訂逾時，請選擇**預設逾時**，然後輸入介於 `50` 和 `29000` 毫秒之間的逾時值。

1. (選用) 您可以使用下列下拉式選單來配置方法請求設定值。選擇**方法請求設定**，並設定您的方法請求。如需詳細資訊，請參閱 [在 API Gateway 主控台編輯 API Gateway 方法請求](how-to-set-up-method-using-console.md#how-to-method-settings-callers-console) 的步驟 3。

   您也可以在建立方法後配置方法請求設定值。

1. 選擇**建立方法**。

## 設定模擬整合
<a name="how-to-method-settings-console-mock"></a>

 如果您希望 API Gateway 充當您的後端傳回靜態回應，請使用模擬整合。在 API 層級，這是 `MOCK` 整合類型。一般而言，當您的 API 尚未到達最終形態，但您希望產生 API 回應解鎖相依小組進行測試時，您可以使用 `MOCK` 整合。針對 `OPTION` 方法，API Gateway 會將 `MOCK` 整合設為預設值，針對已套用的 API 資源傳回 CORS 啟用的標頭。

**設定模擬整合**

1. 在**資源**窗格中，選擇**建立方法**。

1. 針對**方法類型**，選取 HTTP 方法。

1. 對於**整合類型**，選擇**模擬**。

1. (選用) 您可以使用下列下拉式選單來配置方法請求設定值。選擇**方法請求設定**，並設定您的方法請求。如需詳細資訊，請參閱 [在 API Gateway 主控台編輯 API Gateway 方法請求](how-to-set-up-method-using-console.md#how-to-method-settings-callers-console) 的步驟 3。

   您也可以在建立方法後配置方法請求設定值。

1. 選擇**建立方法**。

# 在 API Gateway 中設定整合回應
<a name="api-gateway-integration-settings-integration-response"></a>

 針對非代理整合，您必須至少設定一個整合回應，並讓它成為預設的回應，才能將後端傳回的結果傳送到用戶端。您可以選擇依現狀傳送結果，或將整合回應資料轉換成方法回應資料，如果它們兩個格式不同。

如需代理整合，API Gateway 會自動將後端輸出當作 HTTP 回應傳送至用戶端。您不用設定整合回應或方法回應。

若要設定整合回應，您要執行下列必要和選用任務：

1.  指定整合回應資料映射的方法回應 HTTP 狀態碼。這是必要的。

1.  定義規則表達式選取此整合回應要代表的後端輸出。如果此項目保留空白，此回應是用來擷取所有尚未設定回應的預設回應。

1.  如有需要，請宣告使用鍵值對組成的映射，將指定的整合回應參數映射到指定的方法回應參數。

1. 如有需要，請新增內文映射範本，將指定的整合回應承載傳送到指定的方法回應承載。

1.  如有需要，請指定如何處理二進位承載的類型轉換。

整合回應是封裝後端回應的 HTTP 回應。HTTP 端點的後端回應是 HTTP 回應。整合回應狀態碼可以採用後端傳回的狀態碼，整合回應內文是後端傳回的承載。Lambda 端點的後端回應是從 Lambda 函數傳回的輸出。使用 Lambda 整合，Lambda 函數輸出會傳回為 `200 OK` 回應。承載可以包含結果當作 JSON 資料，包括 JSON 字串或 JSON 物件，或當作 JSON 物件的錯誤訊息。您可以將規則表達式指派給 [selectionPattern](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html#selectionPattern) 屬性，將錯誤回應映射到適當的 HTTP 錯誤回應。如需 Lambda 函數錯誤回應的詳細資訊，請參閱[處理 API Gateway 中的 Lambda 錯誤](handle-errors-in-lambda-integration.md)。使用 Lambda 代理整合，Lambda 函數必須傳回格式如下的輸出：

```
{
    statusCode: "...",            // a valid HTTP status code
    headers: { 
        custom-header: "..."      // any API-specific custom header
    },
    body: "...",                  // a JSON string.
    isBase64Encoded:  true|false  // for binary support
}
```

您不必將 Lambda 函數回應映射到其正確的 HTTP 回應。

若要將結果傳回給用戶端，請設定整合回應依現狀將端點回應傳送到對應的方法回應。或者，您可以將端點回應資料映射到方法回應資料。可映射的回應資料包括回應狀態碼、回應標頭參數和回應內文。傳回的狀態碼如果未定義任何方法回應，API Gateway 會傳回 500 錯誤。如需詳細資訊，請參閱[覆寫 API Gateway 中 REST API 的 API 請求和回應參數及狀態碼](apigateway-override-request-response-parameters.md)。



# API Gateway 中 REST API 的 Lambda 整合
<a name="set-up-lambda-integrations"></a>

 您可以使用 Lambda 代理整合或 Lambda 非代理 (自訂) 整合，將 API 方法與 Lambda 函數整合。

在 Lambda 代理整合中，必要設定非常簡單。將整合的 HTTP 方法設定為 POST、將整合端點 URI 設定為特定 Lambda 函數之 Lambda 函數呼叫動作的 ARN，並且允許 API Gateway 代表您呼叫 Lambda 函數。

在 Lambda 非代理整合中，除了代理整合設定步驟之外，您也可以指定如何將傳入請求資料映射至整合請求，以及如何將產生的整合回應資料映射至方法回應。

**Topics**
+ [API Gateway 中的 Lambda 代理整合](set-up-lambda-proxy-integrations.md)
+ [在 API Gateway 中設定 Lambda 自訂整合](set-up-lambda-custom-integrations.md)
+ [設定後端 Lambda 函數的非同步叫用](set-up-lambda-integration-async.md)
+ [處理 API Gateway 中的 Lambda 錯誤](handle-errors-in-lambda-integration.md)

# API Gateway 中的 Lambda 代理整合
<a name="set-up-lambda-proxy-integrations"></a>

下一節顯示如何使用 Lambda 代理整合。

**Topics**
+ [了解 API Gateway Lambda 代理整合](#api-gateway-create-api-as-simple-proxy)
+ [支援多值標頭和查詢字串參數](#apigateway-multivalue-headers-and-parameters)
+ [代理整合之 Lambda 函數的輸入格式](#api-gateway-simple-proxy-for-lambda-input-format)
+ [代理整合之 Lambda 函數的輸出格式](#api-gateway-simple-proxy-for-lambda-output-format)
+ [使用 設定 API Gateway 的 Lambda 代理整合 AWS CLI](set-up-lambda-proxy-integration-using-cli.md)
+ [使用 Lambda 代理整合與 OpenAPI 定義設定代理資源](api-gateway-set-up-lambda-proxy-integration-on-proxy-resource.md)

## 了解 API Gateway Lambda 代理整合
<a name="api-gateway-create-api-as-simple-proxy"></a>

Amazon API Gateway Lambda 代理整合是一個簡單、強大且靈活的機制，可透過設定單一 API 方法來建置 API。Lambda 代理整合可讓用戶端在後端呼叫單一 Lambda 函數。函數會存取其他服務的許多資源或功能 AWS ，包括呼叫其他 Lambda 函數。

 在 Lambda 代理整合中，當用戶端提交一個 API 請求時，API Gateway 會對整合的 Lambda 函數傳遞[事件物件](#api-gateway-simple-proxy-for-lambda-input-format)，但不會保留請求參數的順序。此[請求資料](#api-gateway-simple-proxy-for-lambda-input-format)包含請求標頭、查詢字串參數、URL 路徑變數、承載與 API 組態資料。組態資料可包含目前的部署階段名稱、階段變數、使用者身分或授權內容 (如果有)。後端 Lambda 函數會剖析傳入請求資料，以判斷其所傳回的回應。若要讓 API Gateway 將 Lambda 輸出當作 API 回應傳遞至用戶端，Lambda 函數必須以[此格式](#api-gateway-simple-proxy-for-lambda-output-format)傳回結果。

 由於 API Gateway 不用在用戶端與後端 Lambda 函數之間介入太多就可進行 Lambda 代理整合，因此用戶端與整合的 Lambda 函數可以根據彼此的變更進行調整，而不需要中斷 API 的現有整合設定。若要啟用這項功能，用戶端必須遵循後端 Lambda 函數所制定的應用程式通訊協定。

 您可以設定任何 API 方法的 Lambda 代理整合。但針對涉及一般代理資源的 API 方法設定時，Lambda 代理整合會更有效。一般代理資源可由 `{proxy+}` 的特殊樣板化路徑變數、catch-all `ANY` 方法預留位置或兩者來表示。用戶端可以在傳入請求中將輸入當作請求參數或適用的承載傳遞到後端 Lambda 函數。這些請求參數包含標頭、URL 路徑變數、查詢字串參數與適用的承載。整合的 Lambda 函數會驗證所有輸入來源，再處理請求，如果遺失所要求的任何輸入，則會以有意義的錯誤訊息來回應用戶端。

 呼叫與 `ANY` 的泛型 HTTP 方法以及 `{proxy+}` 的一般資源整合的 API 方法時，用戶端會以特定 HTTP 方法取代 `ANY` 來提交請求。用戶端也會指定特定 URL 路徑 (而不是 `{proxy+}`)，並包含任何必要的標頭、查詢字串參數或適用的承載。

 下列清單摘要說明不同 API 方法與 Lambda 代理整合的執行時間行為：
+ `ANY /{proxy+}`：用戶端必須選擇特定 HTTP 方法、必須設定特定資源路徑階層，並可設定任何標頭、查詢字串參數與適用的承載，以將資料作為輸入傳遞至整合的 Lambda 函數。
+ `ANY /res`：用戶端必須選擇特定 HTTP 方法，並可設定任何標頭、查詢字串參數與適用的承載，以將資料作為輸入傳遞至整合的 Lambda 函數。
+ `GET|POST|PUT|... /{proxy+}`：用戶端可設定特定資源路徑階層、任何標頭、查詢字串參數與適用的承載，以將資料作為輸入傳遞至整合的 Lambda 函數。
+  `GET|POST|PUT|... /res/{path}/...`：用戶端必須選擇特定路徑區段 (針對 `{path}` 變數)，並可設定任何請求標頭、查詢字串參數與適用的承載，以將輸入資料傳遞至整合的 Lambda 函數。
+  `GET|POST|PUT|... /res`：用戶端可選擇任何請求標頭、查詢字串參數與適用的承載，以將輸入資料傳遞至整合的 Lambda 函數。

 `{proxy+}` 的代理資源與 `{custom}` 的自訂資源都可使用樣板化路徑變數來表示。不過，`{proxy+}` 可參考沿著路徑階層的任何資源，但 `{custom}` 只能參考特定路徑區段。例如，雜貨店可能會依部門名稱、產品類別與產品類型，來組織其線上產品庫存。雜貨店的網站可接著透過自訂資源的下列樣板化路徑變數來表示可用的產品：`/{department}/{produce-category}/{product-type}`。例如，蘋果是以 `/produce/fruit/apple` 表示，而紅蘿蔔是以 `/produce/vegetables/carrot` 表示。它也可以使用 `/{proxy+}` 來表示客戶在線上商店購物時可搜尋的任何部門、任何產品類別或任何產品類型。例如，`/{proxy+}` 可參考下列任何項目：
+ `/produce`
+ `/produce/fruit`
+ `/produce/vegetables/carrot`

 若要讓客戶搜尋任何可用的產品、其產品類別與相關聯的商店部門，您可以公開 `GET /{proxy+}` 的單一方法並授予唯讀許可。同樣地，若要讓主管更新 `produce` 部門的庫存，您可以設定 `PUT /produce/{proxy+}` 的另一個單一方法並授予讀取/寫入許可。若要讓出納員更新蔬菜的計算加總，您可以設定 `POST /produce/vegetables/{proxy+}` 方法並授予讀取/寫入許可。若要讓商店經理對任何可用的產品執行任何可能的動作，線上商店開發人員可以公開 `ANY /{proxy+}` 方法並授予讀取/寫入許可。在任何情況下，客戶或員工都必須在執行階段選取所選部門中指定類型的特定產品、所選部門中的特定產品類別或特定部門。



如需設定 API Gateway 代理整合的詳細資訊，請參閱[設定代理整合與代理資源](api-gateway-set-up-simple-proxy.md)。

 代理整合需要用戶端更詳細了解後端需求。因此，若要確保最佳應用程式效能與使用者體驗，後端開發人員必須向用戶端開發人員清楚表達後端的需求，並提供未符合需求時的完善錯誤回饋機制。

## 支援多值標頭和查詢字串參數
<a name="apigateway-multivalue-headers-and-parameters"></a>

API Gateway 現在支援具有相同名稱的多個標頭和查詢字串參數。多值標頭以及單值標頭和參數可在相同的請求和回應中結合使用。如需詳細資訊，請參閱[代理整合之 Lambda 函數的輸入格式](#api-gateway-simple-proxy-for-lambda-input-format)及[代理整合之 Lambda 函數的輸出格式](#api-gateway-simple-proxy-for-lambda-output-format)。

## 代理整合之 Lambda 函數的輸入格式
<a name="api-gateway-simple-proxy-for-lambda-input-format"></a>

在 Lambda 代理整合中，API Gateway 會將整個用戶端請求映射至後端 Lambda 函數的輸入 `event` 參數。下列範例顯示 API Gateway 傳送至 Lambda 代理整合之事件的結構。

在此範例中，我們假設 API Gateway 的調用如下：

```
curl 'https://a1b2c3.execute-api.us-east-1.amazonaws.com/my/path?parameter1=value1&parameter2=value1&parameter2=value2&parameter3=value1,value2' -H 'header1: value1' -H 'header2: value1' -H 'header2: value2' -H 'header3: value1,value2'
```

輸出看起來如下：

```
{
  "resource": "/my/path",
  "path": "/my/path",
  "httpMethod": "GET",
  "headers": {
      "header1": "value1",
      "header2": "value2",
      "header3": "value1,value2"
  },
  "multiValueHeaders": {
    "header1": ["value1"],
    "header2": ["value1","value2"],
    "header3": ["value1,value2"]
  },
  "queryStringParameters": {
      "parameter1": "value1",
      "parameter2": "value2",
      "parameter3": "value1,value2"
  },
  "multiValueQueryStringParameters": {
    "parameter1": ["value1"],
    "parameter2": ["value1","value2"],
    "parameter3": ["value1,value2"]
  },
  "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": "IP",
      "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
}
```

**注意**  
在輸入中：  
`headers` 鍵只能包含單一值標頭。
`multiValueHeaders` 鍵可以包含多值標頭以及單一值標頭。
如果您同時指定 `headers` 和 `multiValueHeaders` 的值，API Gateway 會將它們合併成一個清單。如果在兩者指定了相同的鍵值對，則只有 `multiValueHeaders` 中的值會出現在合併清單。

在後端 Lambda 函數的輸入中，`requestContext` 物件是索引鍵/值組的映射。在各對中，鍵是 [\$1context](api-gateway-mapping-template-reference.md#context-variable-reference) 變數屬性的名稱，而值是該屬性的值。API Gateway 可能會將新的金鑰加入至地圖。

根據啟用的功能，`requestContext` 映射可能會因 API 而不同。例如，在上述範例中，未指定任何授權類型，因此沒有 `$context.authorizer.*` 或 `$context.identity.*` 屬性存在。指定授權類型時，這會導致 API Gateway 將授權的使用者資訊傳遞至 `requestContext.identity` 物件中的整合端點，如下所示：
+ 當授權類型為 `AWS_IAM` 時，授權的使用者資訊包含 `$context.identity.*` 屬性。
+ 當授權類型為 `COGNITO_USER_POOLS` (Amazon Cognito 授權方) 時，授權的使用者資訊包含 `$context.identity.cognito*` 和 `$context.authorizer.claims.*` 屬性。
+ 當授權類型為 `CUSTOM` (Lambda 授權方) 時，授權的使用者資訊包含 `$context.authorizer.principalId` 和其他適用的 `$context.authorizer.*` 屬性。

## 代理整合之 Lambda 函數的輸出格式
<a name="api-gateway-simple-proxy-for-lambda-output-format"></a>

在 Lambda 代理整合中，API Gateway 需要後端 Lambda 函數根據下列 JSON 格式傳回輸出：

```
{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
    "body": "..."
}
```

在輸出中：
+ 如果不再傳回額外的回應標頭，則可以不指定 `headers` 和 `multiValueHeaders` 鍵。
+ `headers` 鍵只能包含單一值標頭。
+ `multiValueHeaders` 鍵可以包含多值標頭以及單一值標頭。您可以使用 `multiValueHeaders` 鍵來指定所有額外標頭，包括任何單一值標頭。
+ 如果您同時指定 `headers` 和 `multiValueHeaders` 的值，API Gateway 會將它們合併成一個清單。如果在兩者指定了相同的鍵值對，則只有 `multiValueHeaders` 中的值會出現在合併清單。

若要啟用 CORS 進行 Lambda 代理整合，您必須將 `Access-Control-Allow-Origin:domain-name` 新增至輸出 `headers`。`domain-name` 可以是 `*`，其代表任何網域名稱。輸出 `body` 會封送處理至前端，以做為方法回應承載。如果 `body` 是二進位 Blob，您可以透過將 `isBase64Encoded` 設定為 `true`將其編碼為 Base64 編碼字串，並將 `*/*` 設定為 **Binary Media Type (二進位媒體類型)**。否則，您可以將它設定為 `false`，或保留未指定。

**注意**  
如需啟用二進位支援的詳細資訊，請參閱[使用 API Gateway 主控台啟用二進位支援](api-gateway-payload-encodings-configure-with-console.md)。如需 Lambda 函數的範例，請參閱[在 API Gateway 中從 Lambda 代理整合傳回二進位媒體](lambda-proxy-binary-media.md)。

如果函數輸出的格式不同，則 API Gateway 會傳回 `502 Bad Gateway` 錯誤回應。

若要在 Node.js 的 Lambda 函數中傳回回應，您可以使用以下命令：
+ 若要傳回成功結果，請呼叫 `callback(null, {"statusCode": 200, "body": "results"})`。
+ 若要擲回例外狀況，請呼叫 `callback(new Error('internal server error'))`。
+ 針對用戶端錯誤 (例如，如果遺失必要參數)，您可以呼叫 `callback(null, {"statusCode": 400, "body": "Missing parameters of ..."})` 傳回錯誤，而不擲回例外狀況。

在 Node.js 的 Lambda `async` 函數中，同等語法應為：
+ 若要傳回成功結果，請呼叫 `return {"statusCode": 200, "body": "results"}`。
+ 若要擲回例外狀況，請呼叫 `throw new Error("internal server error")`。
+ 針對用戶端錯誤 (例如，如果遺失必要參數)，您可以呼叫 `return {"statusCode": 400, "body": "Missing parameters of ..."}` 傳回錯誤，而不擲回例外狀況。

# 使用 設定 API Gateway 的 Lambda 代理整合 AWS CLI
<a name="set-up-lambda-proxy-integration-using-cli"></a>

在本節中，我們示範如何使用 AWS CLI設定具有 Lambda 代理整合的 API。如需使用 API Gateway 主控台來設定代理資源與 Lambda 代理整合搭配的詳細指示，請參閱 [教學：建立具 Lambda 代理整合的 REST API](api-gateway-create-api-as-simple-proxy-for-lambda.md)。

例如，我們使用下列範例 Lambda 函數作為 API 的後端：

```
export const handler = async(event, context) => {
    console.log('Received event:', JSON.stringify(event, null, 2));
    var res ={
        "statusCode": 200,
        "headers": {
            "Content-Type": "*/*"
        }
    };
    var greeter = 'World';
    if (event.greeter && event.greeter!=="") {
        greeter =  event.greeter;
    } else if (event.body && event.body !== "") {
        var body = JSON.parse(event.body);
        if (body.greeter && body.greeter !== "") {
            greeter = body.greeter;
        }
    } else if (event.queryStringParameters && event.queryStringParameters.greeter && event.queryStringParameters.greeter !== "") {
        greeter = event.queryStringParameters.greeter;
    } else if (event.multiValueHeaders && event.multiValueHeaders.greeter && event.multiValueHeaders.greeter != "") {
        greeter = event.multiValueHeaders.greeter.join(" and ");
    } else if (event.headers && event.headers.greeter && event.headers.greeter != "") {
        greeter = event.headers.greeter;
    } 
    res.body = "Hello, " + greeter + "!";
    return res
};
```

在 [在 API Gateway 中設定 Lambda 自訂整合](set-up-lambda-custom-integrations.md) 中將此項目與 Lambda 自訂整合設定做比較，可以在請求參數與內文中表達此 Lambda 函數的輸入。您可以有更多的自由，讓用戶端傳遞相同的輸入資料。在這裡，用戶端可以傳入接待員名稱以做為查詢字串參數、標頭或內文屬性。此函數也可以支援 Lambda 自訂整合。API 設定較為簡單。您根本不需要設定方法回應或整合回應。

**使用 設定 Lambda 代理整合 AWS CLI**

1. 使用以下 [create-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-rest-api.html) 命令建立 API：

   ```
   aws apigateway create-rest-api --name 'HelloWorld (AWS CLI)'
   ```

   輸出將如下所示：

   ```
   {
       "name": "HelloWorldProxy (AWS CLI)", 
       "id": "te6si5ach7",
       "rootResourceId" : "krznpq9xpg",
       "createdDate": 1508461860
   }
   ```

   在此範例中，您會使用 API `id` (`te6si5ach7`) 和 `rootResourceId` (`krznpq9xpg`)。

1. 使用以下 [create-resource](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-resource.html) 命令建立 `/greeting` 的 API Gateway [資源](https://docs.aws.amazon.com/apigateway/latest/api/API_Resource.html)：

   ```
   aws apigateway create-resource \
         --rest-api-id te6si5ach7 \
         --parent-id krznpq9xpg \
         --path-part {proxy+}
   ```

   輸出將如下所示：

   ```
   {
       "path": "/{proxy+}", 
       "pathPart": "{proxy+}", 
       "id": "2jf6xt", 
       "parentId": "krznpq9xpg"
   }
   ```

   在下一個步驟中，您會使用 `{proxy+}` 資源的 `id` 值 (`2jf6xt`) 在 `/{proxy+}` 資源上建立方法。

1. 使用以下 [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) 建立 `ANY /{proxy+}` 的方法請求 `ANY`：

   ```
   aws apigateway put-method --rest-api-id te6si5ach7 \
          --resource-id 2jf6xt \
          --http-method ANY \
          --authorization-type "NONE"
   ```

   輸出將如下所示：

   ```
   {
       "apiKeyRequired": false, 
       "httpMethod": "ANY", 
       "authorizationType": "NONE"
   }
   ```

   此 API 方法可讓用戶端從後端的 Lambda 函數接收或傳送問候語。

1. 使用以下 [put-integration](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration.html) 命令來設定 `ANY /{proxy+}` 方法與名為 `HelloWorld` 之 Lambda 函式的整合。如果提供 `"Hello, {name}!"` 參數，則此函數會以 `greeter` 訊息來回應請求，如果未設定查詢字串參數，則會以 `"Hello, World!"` 來回應請求。

   ```
   aws apigateway put-integration \
         --rest-api-id te6si5ach7 \
         --resource-id 2jf6xt \
         --http-method ANY \
         --type AWS_PROXY \
         --integration-http-method POST \
         --uri arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:HelloWorld/invocations \
         --credentials arn:aws:iam::123456789012:role/apigAwsProxyRole
   ```
**重要**  
針對 Lambda 整合，您必須根據[進行函數叫用之 Lambda 服務動作的規格](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)，使用 HTTP 方法 `POST` 進行整合請求。IAM 角色 `apigAwsProxyRole` 的政策必須允許 `apigateway` 服務叫用 Lambda 函數。如需 IAM 許可的相關資訊，請參閱 [用於呼叫 API 的 API Gateway 許可模型](permissions.md#api-gateway-control-access-iam-permissions-model-for-calling-api)。

   輸出將如下所示：

   ```
   {
       "passthroughBehavior": "WHEN_NO_MATCH", 
       "cacheKeyParameters": [], 
       "uri": "arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:1234567890:function:HelloWorld/invocations", 
       "httpMethod": "POST", 
       "cacheNamespace": "vvom7n", 
       "credentials": "arn:aws:iam::1234567890:role/apigAwsProxyRole", 
       "type": "AWS_PROXY"
   }
   ```

   您可以使用 [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) 命令來新增資源型許可，而不提供 `credentials` 的 IAM 角色。這就是 API Gateway 主控台的功能。

1. 使用以下 [create-deployment](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-deployment.html) 命令將 API 部署至 `test` 階段：

   ```
   aws apigateway create-deployment  \
         --rest-api-id te6si5ach7 \
         --stage-name test
   ```

1. 在終端機中使用下列 cURL 命令，以測試 API。

   使用查詢字串參數 `?greeter=jane` 呼叫 API：

   ```
   curl -X GET 'https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/greeting?greeter=jane'
   ```

   使用標頭參數 `greeter:jane` 呼叫 API：

   ```
   curl -X GET https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/hi \
     -H 'content-type: application/json' \
     -H 'greeter: jane'
   ```

   使用內文 `{"greeter":"jane"}` 呼叫 API：

   ```
   curl -X POST https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/hi \
     -H 'content-type: application/json' \
     -d '{ "greeter": "jane" }'
   ```

   在所有情況下，輸出都是具有下列回應內文的 200 回應：

   ```
   Hello, jane!
   ```

# 使用 Lambda 代理整合與 OpenAPI 定義設定代理資源
<a name="api-gateway-set-up-lambda-proxy-integration-on-proxy-resource"></a>

若要以 Lambda 代理整合類型設定代理資源，請以 Greedy 路徑參數建立 API 資源 (例如 `/parent/{proxy+}`)，並將此資源與 `arn:aws:lambda:us-west-2:123456789012:function:SimpleLambda4ProxyResource` 方法上的 Lambda 函數後端 (例如 `ANY`) 整合。Greedy 路徑參數必須位於 API 資源路徑結尾。如同非代理資源，您可以使用 API Gateway 主控台、匯入 OpenAPI 定義檔，或直接呼叫 API Gateway REST API，來設定代理資源。

下列 OpenAPI API 定義檔顯示 API 範例，其中具有與名為 `SimpleLambda4ProxyResource` 的 Lambda 函數整合的代理資源。

------
#### [ OpenAPI 3.0 ]

```
{
   "openapi": "3.0.0",
   "info": {
      "version": "2016-09-12T17:50:37Z",
      "title": "ProxyIntegrationWithLambda"
   },
   "paths": {
      "/{proxy+}": {
         "x-amazon-apigateway-any-method": {
            "parameters": [
               {
                  "name": "proxy",
                  "in": "path",
                  "required": true,
                  "schema": {
                     "type": "string"
                  }
               }
            ],
            "responses": {},
            "x-amazon-apigateway-integration": {
               "responses": {
                  "default": {
                     "statusCode": "200"
                  }
               },
               "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:SimpleLambda4ProxyResource/invocations",
               "passthroughBehavior": "when_no_match",
               "httpMethod": "POST",
               "cacheNamespace": "roq9wj",
               "cacheKeyParameters": [
                  "method.request.path.proxy"
               ],
               "type": "aws_proxy"
            }
         }
      }
   },
   "servers": [
      {
         "url": "https://gy415nuibc.execute-api.us-east-1.amazonaws.com/{basePath}",
         "variables": {
            "basePath": {
              "default": "/testStage"
            }
         }
      }
   ]
}
```

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

```
{
  "swagger": "2.0",
  "info": {
    "version": "2016-09-12T17:50:37Z",
    "title": "ProxyIntegrationWithLambda"
  },
  "host": "gy415nuibc.execute-api.us-east-1.amazonaws.com",
  "basePath": "/testStage",
  "schemes": [
    "https"
  ],
  "paths": {
    "/{proxy+}": {
      "x-amazon-apigateway-any-method": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "proxy",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {},
        "x-amazon-apigateway-integration": {
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:SimpleLambda4ProxyResource/invocations",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST",
          "cacheNamespace": "roq9wj",
          "cacheKeyParameters": [
            "method.request.path.proxy"
          ],
          "type": "aws_proxy"
        }
      }
    }
  }
}
```

------

在 Lambda 代理整合中，API Gateway 會在執行時間將傳入的請求映射到 Lambda 函數的輸入 `event` 參數。輸入包含請求方法、路徑、標頭、任何查詢字串參數、任何承載、相關聯內容和任何已定義的階段變數。「[代理整合之 Lambda 函數的輸入格式](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-input-format)」說明輸入格式。若要讓 API Gateway 成功將 Lambda 輸出映射至 HTTP 回應，Lambda 函數必須以 [代理整合之 Lambda 函數的輸出格式](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-output-format) 中所述的格式輸出結果。

在透過 `ANY` 方法之代理資源的 Lambda 代理整合中，單一後端 Lambda 函數透過代理資源作為所有請求的事件處理常式。例如，若要記錄流量模式，您可以在代理資源的 URL 路徑中使用 `/state/city/street/house` 提交請求，讓行動裝置傳送其州/省、城市、街道和建築物的位置資訊。後端 Lambda 函數接著可以剖析 URL 路徑，並將位置元組插入至 DynamoDB 資料表。

# 在 API Gateway 中設定 Lambda 自訂整合
<a name="set-up-lambda-custom-integrations"></a>

 為了示範如何設定 Lambda 自訂或非代理整合，我們會建立 API Gateway API 來公開 `GET /greeting?greeter={name}` 方法以調用 Lambda 函式。請為您的 API 使用下列其中一個 Lambda 函數範例。

使用下列其中一個 Lambda 函數範例：

------
#### [ Node.js ]

```
'use strict';
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];            
var times = ['morning', 'afternoon', 'evening', 'night', 'day'];

export const handler = async(event) => {
  console.log(event);
  // Parse the input for the name, city, time and day property values
  let name = event.name === null || event.name === undefined || event.name === "" ? 'you' : event.name;
  let city = event.city === undefined ? 'World' : event.city;
  let time = times.indexOf(event.time)<0 ? 'day' : event.time;
  let day = days.indexOf(event.day)<0 ? null : event.day;

  // Generate a greeting
  let greeting = 'Good ' + time + ', ' + name + ' of ' + city + '. ';
  if (day) greeting += 'Happy ' + day + '!';
  
  // Log the greeting to CloudWatch
  console.log('Hello: ', greeting);
  
  // Return a greeting to the caller
  return greeting;
};
```

------
#### [ Python ]

```
import json


def lambda_handler(event, context):
    print(event)
    res = {
        "statusCode": 200,
        "headers": {
            "Content-Type": "*/*"
        }
    }

    if event['greeter'] == "":
        res['body'] = "Hello, World"
    elif (event['greeter']):
        res['body'] = "Hello, " + event['greeter'] + "!"
    else:
        raise Exception('Missing the required greeter parameter.')

    return res
```

------

如果 `"Hello, {name}!"` 參數值是非空白字串，則該函數會以 `greeter` 訊息進行回應。如果 `"Hello, World!"` 值是空白字串，則它會傳回 `greeter` 訊息。如果未在傳入請求中設定 greeter 參數，則該函數會傳回錯誤訊息 `"Missing the required greeter parameter."`。我們將函數命名為 `HelloWorld`。

您可以在 Lambda 主控台中或使用 AWS CLI來建立它。在本節中，我們使用下列 ARN 來參考此函數：

```
arn:aws:lambda:us-east-1:123456789012:function:HelloWorld
```

在後端設定 Lambda 函數，即可繼續設定 API。<a name="set-up-lambda-custom-integration-using-cli"></a>

**使用 設定 Lambda 自訂整合 AWS CLI**

1. 使用以下 [create-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-rest-api.html) 命令建立 API：

   ```
   aws apigateway create-rest-api --name 'HelloWorld (AWS CLI)'
   ```

   輸出將如下所示：

   ```
   {
       "name": "HelloWorld (AWS CLI)", 
       "id": "te6si5ach7",
       "rootResourceId" : "krznpq9xpg",
       "createdDate": 1508461860
   }
   ```

   在此範例中，您會使用 API `id` (`te6si5ach7`) 和 `rootResourceId` (`krznpq9xpg`)。

1. 使用以下 [create-resource](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-resource.html) 命令建立 `/greeting` 的 API Gateway [資源](https://docs.aws.amazon.com/apigateway/latest/api/API_Resource.html)：

   ```
   aws apigateway create-resource \
         --rest-api-id te6si5ach7 \
         --parent-id krznpq9xpg \
         --path-part greeting
   ```

   輸出將如下所示：

   ```
   {
       "path": "/greeting", 
       "pathPart": "greeting", 
       "id": "2jf6xt", 
       "parentId": "krznpq9xpg"
   }
   ```

   在下一個步驟中，您會使用 `greeting` 資源的 `id` 值 (`2jf6xt`) 在 `/greeting` 資源上建立方法。

1. 使用以下 [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) 命令建立 `GET /greeting?greeter={name}` 的 API 方法請求：

   ```
   aws apigateway put-method --rest-api-id te6si5ach7 \
          --resource-id 2jf6xt \
          --http-method GET \
          --authorization-type "NONE" \
          --request-parameters method.request.querystring.greeter=false
   ```

   輸出將如下所示：

   ```
   {
       "apiKeyRequired": false, 
       "httpMethod": "GET", 
       "authorizationType": "NONE", 
       "requestParameters": {
           "method.request.querystring.greeter": false
       }
   }
   ```

   這個 API 方法可讓用戶端從後端的 Lambda 函數接收問候語。`greeter` 是選用參數，因為後端應該處理匿名發起人或自我識別發起人。

1. 使用以下 [put-method-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method-response.html) 命令來設定 `GET /greeting?greeter={name}` 之方法請求的 `200 OK` 回應：

   ```
   aws apigateway put-method-response \
           --rest-api-id te6si5ach7 \ 
           --resource-id 2jf6xt \
           --http-method GET \
           --status-code 200
   ```

   

1. 使用以下 [put-integration](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration.html) 命令來設定 `GET /greeting?greeter={name}` 方法與名為 `HelloWorld` 之 Lambda 函式的整合。如果提供 `"Hello, {name}!"` 參數，則此函數會以 `greeter` 訊息來回應請求，如果未設定查詢字串參數，則會以 `"Hello, World!"` 來回應請求。

   ```
   aws apigateway put-integration \
           --rest-api-id te6si5ach7 \
           --resource-id 2jf6xt \
           --http-method GET \
           --type AWS \
           --integration-http-method POST \
           --uri arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:HelloWorld/invocations \
           --request-templates '{"application/json":"{\"greeter\":\"$input.params('greeter')\"}"}' \
           --credentials arn:aws:iam::123456789012:role/apigAwsProxyRole
   ```

   這裡提供的對應範本會將 `greeter` 查詢字串參數翻譯為 JSON 承載的 `greeter` 屬性。這是必要的，因為 Lambda 函數的輸入必須在內文中表示。
**重要**  
針對 Lambda 整合，您必須根據[進行函數調用之 Lambda 服務動作的規格](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)，使用 HTTP 方法 `POST` 進行整合請求。`uri` 參數是函數呼叫動作的 ARN。  
輸出將如下所示：

   ```
   {
       "passthroughBehavior": "WHEN_NO_MATCH", 
       "cacheKeyParameters": [], 
       "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:HelloWorld/invocations", 
       "httpMethod": "POST", 
       "requestTemplates": {
           "application/json": "{\"greeter\":\"$input.params('greeter')\"}"
       }, 
       "cacheNamespace": "krznpq9xpg", 
       "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole", 
       "type": "AWS"
   }
   ```

   IAM 角色 `apigAwsProxyRole` 的政策必須允許 `apigateway` 服務叫用 Lambda 函數。您可以呼叫 [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) 命令來新增資源型許可，而不提供 `credentials` 的 IAM 角色。這是 API Gateway 主控台新增這些許可的方式。

1. 使用以下 [put-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration-response.html) 命令來設定整合回應，以將 Lambda 函式輸出傳遞至用戶端作為 `200 OK` 方法回應：

   ```
    aws apigateway put-integration-response \
           --rest-api-id te6si5ach7 \
           --resource-id 2jf6xt \
           --http-method GET \
           --status-code 200 \
           --selection-pattern ""
   ```

   透過將選取模式設定為空白字串，`200 OK` 回應是預設值。

   輸出將如下所示：

   ```
    {
       "selectionPattern": "", 
       "statusCode": "200"
   }
   ```

1. 使用以下 [create-deployment](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-deployment.html) 命令將 API 部署至 `test` 階段：

   ```
   aws apigateway create-deployment \
           --rest-api-id te6si5ach7 \
           --stage-name test
   ```

1.  在終端機中使用下列 cURL 命令，以測試 API：

   ```
   curl -X GET 'https://te6si5ach7.execute-api.us-west-2.amazonaws.com/test/greeting?greeter=me' \
     -H 'authorization: AWS4-HMAC-SHA256 Credential={access_key}/20171020/us-west-2/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=f327...5751'
   ```

# 設定後端 Lambda 函數的非同步叫用
<a name="set-up-lambda-integration-async"></a>

在 Lambda 非代理 (自訂) 整合中，系統依預設會同步叫用後端 Lambda 函數。這是大部分 REST API 操作所需的行為。不過，有些應用程式要求系統以非同步方式 (以批次操作方式或長時間延遲操作方式) 來執行工作，通常會由個別後端元件執行。在此情況下，系統會非同步叫用後端 Lambda 函數，且前端 REST API 方法不會傳回結果。

您可以將 Lambda 非代理整合的 Lambda 函數設定為以非同步方式叫用，方法是將 `'Event'` 指定為 [Lambda 叫用類型](https://docs.aws.amazon.com/lambda/latest/dg/lambda-invocation.html)。此作法如下所示：

## 在 API Gateway 主控台中設定 Lambda 非同步叫用
<a name="asynchronous-invocation-console-examples"></a>

對於所有呼叫都是非同步的：
+ 在**整合請求**中，新增具有 `'Event'` 靜態值的 `X-Amz-Invocation-Type` 標頭。

讓客戶決定呼叫是非同步或同步：

1. 在**方法請求**中，新增 `InvocationType` 標頭。

1. 在**整合請求**中，新增包含 `method.request.header.InvocationType` 對應表達式的 `X-Amz-Invocation-Type` 標頭。

1. 用戶端可以在 API 請求中包含 `InvocationType: Event` 標頭以進行非同步呼叫，或包含 `InvocationType: RequestResponse` 以進行同步呼叫。

## 使用 OpenAPI 設定 Lambda 非同步調用
<a name="asynchronous-invocation-OpenAPI-examples"></a>

對於所有呼叫都是非同步的：
+  將 `X-Amz-Invocation-Type` 標頭加到 **x-amazon-apigateway-integration** 區段。

  ```
  "x-amazon-apigateway-integration" : {
            "type" : "aws",
            "httpMethod" : "POST",
            "uri" : "arn:aws:apigateway:us-east-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-2:123456789012:function:my-function/invocations",
            "responses" : {
              "default" : {
                "statusCode" : "200"
              }
            },
            "requestParameters" : {
              "integration.request.header.X-Amz-Invocation-Type" : "'Event'"
            },
            "passthroughBehavior" : "when_no_match",
            "contentHandling" : "CONVERT_TO_TEXT"
          }
  ```

讓客戶決定呼叫是非同步或同步：

1.  在任何 [OpenAPI 路徑項目物件](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#pathItemObject)上新增下列標頭。

   ```
   "parameters" : [ {
   "name" : "InvocationType",
   "in" : "header",
   "schema" : {
     "type" : "string"
   }
   } ]
   ```

1.  將 `X-Amz-Invocation-Type` 標頭加到 **x-amazon-apigateway-integration** 區段。

   ```
   "x-amazon-apigateway-integration" : {
             "type" : "aws",
             "httpMethod" : "POST",
             "uri" : "arn:aws:apigateway:us-east-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-2:123456789012:function:my-function/invocations",
             "responses" : {
               "default" : {
                 "statusCode" : "200"
               }
             },
             "requestParameters" : {
               "integration.request.header.X-Amz-Invocation-Type" : "method.request.header.InvocationType"
             },
             "passthroughBehavior" : "when_no_match",
             "contentHandling" : "CONVERT_TO_TEXT"
           }
   ```

1.  用戶端可以在 API 請求中包含 `InvocationType: Event` 標頭以進行非同步呼叫，或包含 `InvocationType: RequestResponse` 以進行同步呼叫。

## 使用 設定 Lambda 非同步調用 CloudFormation
<a name="asynchronous-invocation-cfn-examples"></a>

下列 CloudFormation 範本示範如何`AWS::ApiGateway::Method`為非同步調用設定 。

對於所有呼叫都是非同步的：

```
AsyncMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref AsyncResource
      HttpMethod: GET
      ApiKeyRequired: false
      AuthorizationType: NONE
      Integration:
        Type: AWS
        RequestParameters:
          integration.request.header.X-Amz-Invocation-Type: "'Event'"
        IntegrationResponses:
            - StatusCode: '200'
        IntegrationHttpMethod: POST
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${myfunction.Arn}$/invocations
      MethodResponses:
        - StatusCode: '200'
```

讓客戶決定呼叫是非同步或同步：

```
AsyncMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref AsyncResource
      HttpMethod: GET
      ApiKeyRequired: false
      AuthorizationType: NONE
      RequestParameters:
        method.request.header.InvocationType: false
      Integration:
        Type: AWS
        RequestParameters:
          integration.request.header.X-Amz-Invocation-Type: method.request.header.InvocationType
        IntegrationResponses:
            - StatusCode: '200'
        IntegrationHttpMethod: POST
        Uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${myfunction.Arn}$/invocations
      MethodResponses:
        - StatusCode: '200'
```

 用戶端可以在 API 請求中包含 `InvocationType: Event` 標頭以進行非同步呼叫，或包含 `InvocationType: RequestResponse` 以進行同步呼叫。

# 處理 API Gateway 中的 Lambda 錯誤
<a name="handle-errors-in-lambda-integration"></a>

 對於 Lambda 自訂整合，您必須將整合回應中 Lambda 傳回的錯誤，映射到您用戶端的標準 HTTP 錯誤回應。否則，預設 Lambda 錯誤會傳回 `200 OK` 回應，此結果對您的 API 使用者不是直覺式。

 Lambda 會傳回兩種錯誤：標準錯誤和自訂錯誤。在您的 API 中，您必須以不同的方式處理它們。

 使用 Lambda 代理整合，Lambda 必須傳回格式如下的輸出：

```
{
  "isBase64Encoded" : "boolean",
  "statusCode": "number",
  "headers": { ... },
  "body": "JSON string"
}
```

在這個輸出中，`statusCode` 的用戶端錯誤通常是 `4XX`，伺服器錯誤通常是 `5XX`。API Gateway 處理這些錯誤的方法是，根據指定的 `statusCode`，將 Lambda 錯誤映射到 HTTP 錯誤回應。如需 API Gateway 將錯誤類型 (例如 `InvalidParameterException`) 當作回應的一部分傳送到用戶端，Lambda 函數必須在 `headers` 屬性中包含標頭 (例如 `"X-Amzn-ErrorType":"InvalidParameterException"`)。

**Topics**
+ [處理 API Gateway 中的標準 Lambda 錯誤](#handle-standard-errors-in-lambda-integration)
+ [處理 API Gateway 中的自訂 Lambda 錯誤](#handle-custom-errors-in-lambda-integration)

## 處理 API Gateway 中的標準 Lambda 錯誤
<a name="handle-standard-errors-in-lambda-integration"></a>

標準 AWS Lambda 錯誤具有下列格式：

```
{
  "errorMessage": "<replaceable>string</replaceable>",
  "errorType": "<replaceable>string</replaceable>",
  "stackTrace": [
    "<replaceable>string</replaceable>",
    ...
  ]
}
```

 這裡的 `errorMessage` 是錯誤的字串表達式。`errorType` 是語言相關錯誤或例外狀況類型。`stackTrace` 是字串表達式清單，顯示造成錯誤出現的堆疊追蹤。

 例如，請考慮下列 JavaScript (Node.js) Lambda 函數。

```
export const handler = function(event, context, callback) {
    callback(new Error("Malformed input ..."));
};
```

此函數會傳回下列標準 Lambda 錯誤，包含 `Malformed input ...` 作為錯誤訊息：

```
{
  "errorMessage": "Malformed input ...",
  "errorType": "Error",
  "stackTrace": [
    "export const handler (/var/task/index.js:3:14)"
  ]
}
```

 同樣地，請考慮下列 Python Lambda 函數，它會引發具有相同 `Malformed input ...` 錯誤訊息的 `Exception`。

```
def lambda_handler(event, context):
    raise Exception('Malformed input ...')
```

 此函數會傳回下列標準 Lambda 錯誤：

```
{
  "stackTrace": [
    [
      "/var/task/lambda_function.py",
      3,
      "lambda_handler",
      "raise Exception('Malformed input ...')"
    ]
  ],
  "errorType": "Exception",
  "errorMessage": "Malformed input ..."
}
```

 請注意，`errorType` 和 `stackTrace` 屬性值為語言相關。標準錯誤也適用於為 `Error` 物件延伸或 `Exception` 類別子類別的任何錯誤物件。

 若要將標準 Lambda 錯誤映射到方法回應，您必須先決定指定 Lambda 錯誤的 HTTP 狀態碼。然後，您要在與指定的 HTTP 狀態碼相關聯之 [IntegrationResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html) 的 `[selectionPattern](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html#selectionPattern)` 屬性上，設定規則表達式模式。在 API Gateway 主控台中，於每個整合回應下的**整合回應**區段中，這個 `selectionPattern` 會表示為 **Lambda 錯誤 Regex**。

**注意**  
API Gateway 使用 Java 模式 regex 進行回應映射。如需詳細資訊，請參閱 Oracle 文件中的[模式](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)一節。

 例如，使用以下 [put-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration-response.html) 來設定新的 `selectionPattern` 表達式：

```
aws apigateway put-integration-response --rest-api-id z0vprf0mdh --resource-id x3o5ih --http-method GET --status-code 400 --selection-pattern "Malformed.*" --region us-west-2
```

 請務必也要在[方法回應](api-gateway-method-settings-method-response.md#setup-method-response-status-code)上設定對應的錯誤碼 (`400`)。否則，API Gateway 在執行時間會擲出無效的組態錯誤回應。

**注意**  
 在執行時間，API Gateway 會根據 `selectionPattern` 屬性規則表達式的模式比對 Lambda 錯誤的 `errorMessage`。若出現相符項目，API Gateway 會傳回 Lambda 錯誤做為對應 HTTP 狀態碼的 HTTP 回應。如果沒有相符項目，API Gateway 會傳回錯誤作為預設回應，或者若未設定預設回應，則擲出無效的組態例外狀況。  
 將指定回應數量的 `selectionPattern` 值設為 `.*`，將這個回應重新設定為預設回應。這是因為這種選取模式會比對所有的錯誤訊息，包括 Null，即任何未指定的錯誤訊息。產生的對應會覆寫預設的對應。如果您使用 `.+` 作為選取模式來篩選回應，請注意，它可能不會比對包含新行 (`\n`) 字元的回應。

 若要使用 更新現有`selectionPattern`值 AWS CLI，請呼叫 [update-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-integration-response.html) 操作，將`/selectionPattern`路徑值取代為`Malformed*`模式的指定 regex 表達式。



若要使用 API Gateway 主控台設定 `selectionPattern` 表達式，當設定或更新指定的 HTTP 狀態碼的整合回應時，請在 **Lambda 錯誤 Regex** 文字方塊中輸入表達式。

## 處理 API Gateway 中的自訂 Lambda 錯誤
<a name="handle-custom-errors-in-lambda-integration"></a>

 AWS Lambda 可讓您以 JSON 字串傳回自訂錯誤物件，而不是上一節所述的標準錯誤。此錯誤可以是任何有效的 JSON 物件。例如，下列 JavaScript (Node.js) Lambda 函數會傳回自訂錯誤：

```
export const handler = (event, context, callback) => {
    ...
    // Error caught here:
    var myErrorObj = {
        errorType : "InternalServerError",
        httpStatus : 500,
        requestId : context.awsRequestId,
        trace : {
            "function": "abc()",
            "line": 123,
            "file": "abc.js"
        }
    }
    callback(JSON.stringify(myErrorObj));
};
```

 您必須先將 `myErrorObj` 物件轉換為 JSON 字串，再呼叫 `callback` 結束函數。否則，`myErrorObj` 會傳回為 `"[object Object]"` 的字串。當您的 API 方法與前述 Lambda 函數整合時，API Gateway 會收到包含下列承載的整合回應：

```
{
    "errorMessage": "{\"errorType\":\"InternalServerError\",\"httpStatus\":500,\"requestId\":\"e5849002-39a0-11e7-a419-5bb5807c9fb2\",\"trace\":{\"function\":\"abc()\",\"line\":123,\"file\":\"abc.js\"}}"
}
```

 就和任何整合回應一樣，您可以將這個錯誤回應依現狀傳遞到方法回應。或者，您可以讓對應範本將承載轉換成不同的格式。例如，`500` 狀態碼的方法回應請考慮下列內文對應範本：

```
{
    errorMessage: $input.path('$.errorMessage');
}
```

此範本會將包含自訂錯誤 JSON 字串的整合回應內文，轉譯成下列方法回應內文。這個方法回應內文包含自訂錯誤 JSON 物件：

```
{
    "errorMessage" : {
        errorType : "InternalServerError",
        httpStatus : 500,
        requestId : context.awsRequestId,
        trace : {
            "function": "abc()",
            "line": 123,
            "file": "abc.js"
        }
    }
};
```

 視您的 API 請求而定，您可能需要將部分或全部自訂錯誤屬性傳送為方法回應標頭參數。您可以將自訂錯誤對應從整合回應內文套用到方法回應標頭，完成此作業。

例如，下列 OpenAPI 延伸分別定義從 `errorMessage.errorType`、`errorMessage.httpStatus`、`errorMessage.trace.function` 和 `errorMessage.trace` 屬性到 `error_type`、`error_status`、`error_trace_function` 和 `error_trace` 標頭的對應。

```
"x-amazon-apigateway-integration": {
    "responses": {
        "default": {
          "statusCode": "200",
          "responseParameters": {
            "method.response.header.error_trace_function": "integration.response.body.errorMessage.trace.function",
            "method.response.header.error_status": "integration.response.body.errorMessage.httpStatus",
            "method.response.header.error_type": "integration.response.body.errorMessage.errorType",
            "method.response.header.error_trace": "integration.response.body.errorMessage.trace"
          },
          ...
        }
    }
}
```

 在執行時間，API Gateway 會在執行標頭映射時還原序列化 `integration.response.body` 參數。不過，此還原序列化僅適用於 Lambda 自訂錯誤回應的內文到標頭映射，不適用於使用 `$input.body` 的內文到內文映射。如果在方法回應中宣告 `error_status`、`error_trace`、`error_trace_function` 和 `error_type` 標頭，使用這些自訂錯誤內文到標頭的對應，用戶端會收到屬於方法回應的下列標頭。

```
"error_status":"500",
"error_trace":"{\"function\":\"abc()\",\"line\":123,\"file\":\"abc.js\"}",
"error_trace_function":"abc()",
"error_type":"InternalServerError"
```

整合回應內文的 `errorMessage.trace` 屬性是複雜屬性。它會對應到 `error_trace` 標頭做為 JSON 字串。

# API Gateway 中 REST API 的 HTTP 整合
<a name="setup-http-integrations"></a>

 您可以使用 HTTP 代理整合或 HTTP 自訂整合，將 API 方法與 HTTP 端點進行整合。

API Gateway 支援以下端點連接埠：80、443 及 1024-65535。

 使用代理整合時，設定非常簡單。如果您不在乎內容編碼或快取，您只需要根據後端需求來設定 HTTP 方法與 HTTP 端點 URI。

 使用自訂整合時，需要進行更多的設定。除了代理整合設定步驟，您還需要指定傳入請求資料如何對應到整合請求，以及產生的整合回應資料如何對應到方法回應。

**Topics**
+ [在 API Gateway 中設定 HTTP 代理整合](#api-gateway-set-up-http-proxy-integration-on-proxy-resource)
+ [在 API Gateway 中設定 HTTP 自訂整合](#set-up-http-custom-integrations)

## 在 API Gateway 中設定 HTTP 代理整合
<a name="api-gateway-set-up-http-proxy-integration-on-proxy-resource"></a>

若要設定代理資源與 HTTP 代理整合類型搭配，請建立 API 資源與 Greedy 路徑參數 (例如 `/parent/{proxy+}`) 搭配，並將此資源與 `https://petstore-demo-endpoint.execute-api.com/petstore/{proxy}` 方法上的 HTTP 後端端點 (例如 `ANY`) 整合。Greedy 路徑參數必須位於資源路徑結尾。

如同非代理資源，您可以使用 API Gateway 主控台、匯入 OpenAPI 定義檔，或直接呼叫 API Gateway REST API，來設定具有 HTTP 代理整合的代理資源。如需使用 API Gateway 主控台來設定代理資源與 HTTP 整合搭配的詳細說明，請參閱[教學：建立具有 HTTP 代理整合的 REST API](api-gateway-create-api-as-simple-proxy-for-http.md)。

下列 OpenAPI 定義檔顯示一個其代理資源與 [PetStore](http://petstore-demo-endpoint.execute-api.com/petstore/pets) 網站整合的 API 範例。

------
#### [ OpenAPI 3.0 ]

```
{
   "openapi": "3.0.0",
   "info": {
      "version": "2016-09-12T23:19:28Z",
      "title": "PetStoreWithProxyResource"
   },
   "paths": {
      "/{proxy+}": {
         "x-amazon-apigateway-any-method": {
            "parameters": [
               {
                  "name": "proxy",
                  "in": "path",
                  "required": true,
                  "schema": {
                     "type": "string"
                  }
               }
            ],
            "responses": {},
            "x-amazon-apigateway-integration": {
               "responses": {
                  "default": {
                     "statusCode": "200"
                  }
               },
               "requestParameters": {
                  "integration.request.path.proxy": "method.request.path.proxy"
               },
               "uri": "http://petstore-demo-endpoint.execute-api.com/petstore/{proxy}",
               "passthroughBehavior": "when_no_match",
               "httpMethod": "ANY",
               "cacheNamespace": "rbftud",
               "cacheKeyParameters": [
                  "method.request.path.proxy"
               ],
               "type": "http_proxy"
            }
         }
      }
   },
   "servers": [
      {
         "url": "https://4z9giyi2c1.execute-api.us-east-1.amazonaws.com/{basePath}",
         "variables": {
            "basePath": {
              "default": "/test"
            }
         }
      }
   ]
}
```

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

```
{
  "swagger": "2.0",
  "info": {
    "version": "2016-09-12T23:19:28Z",
    "title": "PetStoreWithProxyResource"
  },
  "host": "4z9giyi2c1.execute-api.us-east-1.amazonaws.com",
  "basePath": "/test",
  "schemes": [
    "https"
  ],
  "paths": {
    "/{proxy+}": {
      "x-amazon-apigateway-any-method": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "proxy",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {},
        "x-amazon-apigateway-integration": {
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.path.proxy": "method.request.path.proxy"
          },
          "uri": "http://petstore-demo-endpoint.execute-api.com/petstore/{proxy}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "ANY",
          "cacheNamespace": "rbftud",
          "cacheKeyParameters": [
            "method.request.path.proxy"
          ],
          "type": "http_proxy"
        }
      }
    }
  }
}
```

------

在此範例中，快取金鑰是在代理資源的 `method.request.path.proxy` 路徑參數上宣告。當您使用 API Gateway 主控台建立 API 時，這是預設設定。API 的基底路徑 (對應到階段的 `/test`) 會對應到網站的 PetStore 頁面 (`/petstore`)。單一整合請求使用 API 的 Greedy 路徑變數與 catch-all `ANY` 方法來鏡射整個 PetStore 網站。下列範例說明此鏡射。
+ **將 `ANY` 設定為 `GET`，將 `{proxy+}` 設定為 `pets`**

  從前端啟動的方法請求：

  ```
  GET https://4z9giyi2c1.execute-api.us-west-2.amazonaws.com/test/pets HTTP/1.1
  ```

  傳送到後端的整合請求：

  ```
  GET http://petstore-demo-endpoint.execute-api.com/petstore/pets HTTP/1.1
  ```

  `ANY` 方法與代理資源的執行時間執行個體皆有效。呼叫會傳回 `200 OK` 回應與含有從後端傳回之第一批寵物的承載。
+ **將 `ANY` 設定為 `GET`，將 `{proxy+}` 設定為 `pets?type=dog`**

  ```
  GET https://4z9giyi2c1.execute-api.us-west-2.amazonaws.com/test/pets?type=dog HTTP/1.1
  ```

  傳送到後端的整合請求：

  ```
  GET http://petstore-demo-endpoint.execute-api.com/petstore/pets?type=dog HTTP/1.1
  ```

  `ANY` 方法與代理資源的執行時間執行個體皆有效。呼叫會傳回 `200 OK` 回應與含有從後端傳回之第一批指定狗類的承載。
+ **將 `ANY` 設定為 `GET`，將 `{proxy+}` 設定為 `pets/{petId}`**

  從前端啟動的方法請求：

  ```
  GET https://4z9giyi2c1.execute-api.us-west-2.amazonaws.com/test/pets/1 HTTP/1.1
  ```

  傳送到後端的整合請求：

  ```
  GET http://petstore-demo-endpoint.execute-api.com/petstore/pets/1 HTTP/1.1
  ```

  `ANY` 方法與代理資源的執行時間執行個體皆有效。呼叫會傳回 `200 OK` 回應與含有從後端傳回之指定寵物的承載。
+ **將 `ANY` 設定為 `POST`，將 `{proxy+}` 設定為 `pets`**

  從前端啟動的方法請求：

  ```
  POST https://4z9giyi2c1.execute-api.us-west-2.amazonaws.com/test/pets HTTP/1.1
  Content-Type: application/json
  Content-Length: ...
  
  {
    "type" : "dog",
    "price" : 1001.00
  }
  ```

  傳送到後端的整合請求：

  ```
  POST http://petstore-demo-endpoint.execute-api.com/petstore/pets HTTP/1.1
  Content-Type: application/json
  Content-Length: ...
  
  {
    "type" : "dog",
    "price" : 1001.00
  }
  ```

  `ANY` 方法與代理資源的執行時間執行個體皆有效。呼叫會傳回 `200 OK` 回應與含有從後端傳回之新建立寵物的承載。
+ **將 `ANY` 設定為 `GET`，將 `{proxy+}` 設定為 `pets/cat`**

  從前端啟動的方法請求：

  ```
  GET https://4z9giyi2c1.execute-api.us-west-2.amazonaws.com/test/pets/cat
  ```

  傳送到後端的整合請求：

  ```
  GET http://petstore-demo-endpoint.execute-api.com/petstore/pets/cat
  ```

  代理資源路徑的執行時間執行個體未對應到後端端點，且產生的請求無效。因此會傳回 `400 Bad Request` 回應與下列錯誤訊息。

  ```
  {
    "errors": [
      {
        "key": "Pet2.type",
        "message": "Missing required field"
      },
      {
        "key": "Pet2.price",
        "message": "Missing required field"
      }
    ]
  }
  ```
+ **將 `ANY` 設定為 `GET`，將 `{proxy+}` 設定為 `null`**

  從前端啟動的方法請求：

  ```
  GET https://4z9giyi2c1.execute-api.us-west-2.amazonaws.com/test
  ```

  傳送到後端的整合請求：

  ```
  GET http://petstore-demo-endpoint.execute-api.com/petstore/pets
  ```

  目標資源是代理資源的父系，但未在該資源的 API 中定義 `ANY` 方法的執行時間執行個體。因此，這個 `GET` 請求會傳回 `403 Forbidden` 回應與 API Gateway 所傳回的 `Missing Authentication Token` 錯誤訊息。如果 API 在父資源 (`ANY`) 上公開 `GET` 或 `/` 方法，呼叫會傳回 `404 Not Found` 回應與後端所傳回的 `Cannot GET /petstore` 訊息。

針對任何用戶端請求，如果目標端點 URL 無效，或 HTTP 動詞有效但不受支援，則後端會傳回 `404 Not Found` 回應。針對不支援的 HTTP 方法，則會傳回 `403 Forbidden` 回應。

## 在 API Gateway 中設定 HTTP 自訂整合
<a name="set-up-http-custom-integrations"></a>

 若使用 HTTP 自訂整合 (也稱為非代理整合)，您就能更精細地控制要在 API 方法與 API 整合之間傳遞哪些資料，以及如何傳遞這些資料。您會透過資料對應來執行此作業。

在方法請求設定過程中，您可以在 [Method](https://docs.aws.amazon.com/apigateway/latest/api/API_Method.html) 資源上設定 [responseParameters](https://docs.aws.amazon.com/apigateway/latest/api/API_Method.html#requestParameters) 屬性。這會宣告哪些從用戶端佈建的方法請求參數，是要對應到整合請求參數或適用的內文屬性，再發送到後端。然後，在整合請求設定過程中，您可以在映射的 [Integration](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html) 資源上設定 [requestParameters](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html#requestParameters) 屬性，來指定參數對參數的映射。您也可以設定 [requestTemplates](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html#requestTemplates) 屬性，針對每個支援的內容類型各指定一個映射範本。對應範本會將方法請求參數或內文對應到整合請求內文。

 同樣地，在方法回應設定過程中，您可以在 [Method Response](https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html) 資源上設定 [responseParameters](https://docs.aws.amazon.com/apigateway/latest/api/API_MethodResponse.html#responseParameters) 屬性。這會宣告哪些要發送到用戶端的方法回應參數，是要從後端傳回之整合回應參數或特定適用的內文屬性對應而來。接著您可以設定 [selectionPattern](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html#selectionPattern)，以根據後端的回應選擇整合回應。對於非代理 HTTP 整合，這是規則表達式。例如，若要將所有 2xx HTTP 回應狀態碼從 HTTP 端點對應至此輸出對應，請使用 `2\d{2}`。

**注意**  
API Gateway 使用 Java 模式 regex 進行回應映射。如需詳細資訊，請參閱 Oracle 文件中的[模式](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html)一節。

然後，在整合回應設定過程中，您可以在映射的 [IntegrationResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html) 資源上設定 [responseParameters](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html#responseParameters) 屬性，來指定參數對參數的映射。您也可以設定 [responseTemplates](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html#responseTemplates) 映射，針對每個支援的內容類型各指定一個映射範本。對應範本會將整合回應參數或整合回應內文屬性對應到方法回應內文。

 如需設定映射範本的詳細資訊，請參閱[API Gateway 中用於 REST API 的資料轉換](rest-api-data-transformations.md)。

# 在 API Gateway 中串流代理整合的整合回應
<a name="response-transfer-mode"></a>

您可以設定代理整合，以控制 API Gateway 傳回整合回應的方式。根據預設，API Gateway 會在開始傳輸之前，等待收到完整回應。不過，如果您將整合的回應傳輸模式設定為 `STREAM`，API Gateway 不會等待完全計算回應，再將其傳送至用戶端。回應串流適用於所有 REST API 端點類型。

針對下列使用案例使用回應串流：
+ 降低聊天機器人等生成式 AI 應用程式time-to-first-byte (TTFB)。
+ 不使用 S3 預先簽章的 URL 來串流大型影像、影片或音樂檔案。
+ 執行長時間執行的操作，同時報告增量進度，例如伺服器傳送事件 (SSE)。
+ 超過 API Gateway 的 10 MB 回應承載限制。
+ 超過 API Gateway 的 29 秒逾時限制，而不要求增加整合逾時限制。
+ 接收二進位承載而不設定二進位媒體類型。

## 回應承載串流的考量
<a name="response-transfer-mode-considerations"></a>

下列考量可能會影響您對回應承載串流的使用：
+ 您只能對 `HTTP_PROXY`或 `AWS_PROXY`整合類型使用回應承載串流。這包括 Lambda 代理整合和使用整合的私有`HTTP_PROXY`整合。
+ 預設傳輸模式設定為 `BUFFERED`。若要使用回應串流，您必須將回應傳輸模式變更為 `STREAM`。
+ 回應串流僅支援 REST APIs。
+ 不支援請求串流。
+ 您最多可以串流回應 15 分鐘。
+ 您的串流會受到閒置逾時的影響。對於區域或私有端點，逾時為 5 分鐘。對於邊緣最佳化端點，逾時為 30 秒。
+ 如果您使用區域 REST API 的回應串流搭配您自己的 CloudFront 分佈，您可以透過增加 CloudFront 分佈的回應逾時，達到超過 30 秒的閒置逾時。如需詳細資訊，請參閱[回應逾時](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DownloadDistValuesOrigin.html#DownloadDistValuesOriginResponseTimeout)。
+ 當回應傳輸模式設定為 時`STREAM`，API Gateway 不支援需要緩衝整個整合回應的功能。因此，回應串流不支援下列功能：
  + 端點快取
  + 內容編碼。如果您想要壓縮整合回應，請在整合中執行此操作。
  + 使用 VTL 進行回應轉換
+ 在每個串流回應中，前 10MB 的回應承載不受任何頻寬限制。超過 10MB 的回應承載資料限制為 2MB/s。
+ 當用戶端和 API Gateway 之間的連線，或 API Gateway 和 Lambda 之間的連線因逾時而關閉時，Lambda 函數可能會繼續執行。如需詳細資訊，請參閱[設定 Lambda 函數逾時](https://docs.aws.amazon.com/lambda/latest/dg/configuration-timeout.html)。
+ 回應串流會產生成本。如需詳細資訊，請參閱 [API Gateway 定價](https://aws.amazon.com/api-gateway/pricing/)。

# 在 API Gateway 中設定 HTTP 代理整合與承載回應串流
<a name="response-streaming-http"></a>

當您設定回應承載串流時，您可以在 方法的整合請求中指定回應傳輸模式。您可以在整合請求中設定這些設定，以控制 API Gateway 在整合回應之前和期間的行為。使用回應串流時，您可以設定整合逾時最多 15 分鐘。

當您搭配 `HTTP_PROXY`整合使用承載回應串流時，API Gateway 不會傳送 HTTP 回應狀態碼或任何 HTTP 回應標頭，直到它完全收到所有標頭為止。

## 建立 HTTP 代理與承載回應串流的整合
<a name="response-streaming-http-create"></a>

下列程序說明如何匯入將 `responseTransferMode` 設為 的新 API`STREAM`。如果您有現有的整合 API 並想要修改 `responseTransferMode`，請參閱 [更新 HTTP 代理整合的回應傳輸模式](#response-streaming-http-update)。

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

**建立與承載回應串流的 HTTP 代理整合**

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

1. 選擇 REST API。

1. 選擇**建立資源**。

1. 針對**資源名稱**，輸入 **streaming**。

1. 選擇**建立資源**。

1. 選取 **/streaming** 資源後，選擇**建立方法**。

1. 針對**方法類型**，選擇**任何**。

1. 對於**整合類型**，選擇 **HTTP**。

1. 選擇 **HTTP 代理整合**。

1. 針對**回應傳輸模式**，選擇**串流**。

1. 針對 **HTTP 方法**，選擇方法。

1. 針對**端點 URL**，輸入整合端點。請確定您選擇的端點會產生要串流回給您的大型承載。

1. 選擇**建立方法**。

建立方法後，請部署您的 API。

**部署 API**

1. 選擇**部署 API**。

1. 針對**階段**，選取**新階段**。

1. 針對**階段名稱**，輸入 **prod**。

1. 在**描述**，請輸入描述。

1. 選擇**部署**。

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

**使用承載回應串流建立新的 API**

1. 複製下列 Open API 檔案，然後將其儲存為 `ResponseStreamDemoSwagger.yaml`。在此檔案中， `responseTransferMode` 設定為 `STREAM`。整合端點設定為 `https://example.com`，但建議您將其修改為可產生大型承載的端點，以串流回給您。

   ```
   openapi: "3.0.1"
   info:
     title: "ResponseStreamingDemo"
     version: "2025-04-28T17:28:25Z"
   servers:
   - url: "{basePath}"
     variables:
       basePath:
         default: "prod"
   paths:
     /streaming:
       get:
         x-amazon-apigateway-integration:
           httpMethod: "GET"
           uri: "https://example.com"
           type: "http_proxy"
           timeoutInMillis: 900000
           responseTransferMode: "STREAM"
   ```

1. 使用下列`import-rest-api`命令匯入您的 OpenAPI 定義：

   ```
   aws apigateway import-rest-api \
     --body 'fileb://~/ResponseStreamDemoSwagger.yaml' \
     --parameters endpointConfigurationTypes=REGIONAL \
     --region us-west-1
   ```

1. 使用下列`create-deployment`命令將您的新 API 部署到階段：

   ```
   aws apigateway create-deployment \
     --rest-api-id a1b2c3 \
     --stage-name prod \
     --region us-west-1
   ```

------

## 更新 HTTP 代理整合的回應傳輸模式
<a name="response-streaming-http-update"></a>

下列程序說明如何更新 HTTP 代理整合的回應傳輸模式。

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

**更新 HTTP 代理整合的回應傳輸模式**

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

1. 選擇 REST API。

1. 選擇一個方法。

1. 在**整合請求**索引標籤上，於**整合請求設定**下，選擇**編輯**。

1. 針對**回應傳輸模式**，選擇**串流**。

1. 選擇**儲存**。

更新方法後，請部署您的 API。

**部署 API**

1. 選擇**部署 API**。

1. 針對**階段**，選取**新階段**。

1. 針對**階段名稱**，輸入 **prod**。

1. 在**描述**，請輸入描述。

1. 選擇**部署**。

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

下列`update-integration`命令會將 整合的傳輸模式從 更新`BUFFERED`為 `STREAM`。對於任何現有的 APIs，所有整合的回應傳輸模式都會設定為 `BUFFERED`。

```
aws apigateway update-integration \
 --rest-api-id a1b2c3 \
 --resource-id aaa111 \
 --http-method GET \
 --patch-operations "op='replace',path='/responseTransferMode',value=STREAM" \
 --region us-west-1
```

您需要重新部署 API，變更才會生效。如果您自訂整合逾時，此逾時值會移除，因為 API Gateway 會串流您的回應長達 5 分鐘。

下列`update-integration`命令會將 整合的傳輸模式從 更新`STREAM`為 `BUFFERED`：

```
aws apigateway update-integration \
 --rest-api-id a1b2c3 \
 --resource-id aaa111 \
 --http-method GET \
 --patch-operations "op='replace',path='/responseTransferMode',value=BUFFERED" \
 --region us-west-1
```

您需要重新部署 API，變更才會生效。

------

# 在 API Gateway 中設定 Lambda 代理整合與承載回應串流
<a name="response-transfer-mode-lambda"></a>

您可以串流 Lambda 函數的回應，以改善達到第一個位元組的時間 (TTFB) 效能，並在用戶端可用時將部分回應傳回給用戶端。API Gateway 要求您使用 [InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html) Lambda API 來叫用 Lambda 函數。API Gateway 會將事件物件傳遞至 Lambda 函數。後端 Lambda 函數會剖析傳入請求資料，以判斷其所傳回的回應。為了讓 API Gateway 串流 Lambda 輸出，Lambda 函數必須輸出 API Gateway 所需的[格式](#response-transfer-mode-lambda-format)。

## 串流和緩衝回應傳輸模式之間 Lambda 代理整合的差異
<a name="response-transfer-mode-lambda-comparison"></a>

下列清單說明 Lambda 代理整合與回應串流的 Lambda 代理整合之間的差異：
+ API Gateway 使用 [InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html) API 來叫用 Lambda 代理整合以進行回應串流。這會產生不同的 URI，如下所示：

  ```
  arn:aws:apigateway:us-west-1:lambda:path/2021-11-15/functions/arn:aws:lambda:us-west-1:111122223333:function:my-function-name/response-streaming-invocations
  ```

  相較於 Lambda 代理整合，此 ARN 使用不同的 API 版本日期和服務動作。

  如果您使用 API Gateway 主控台進行回應串流，主控台會為您使用正確的 URI。
+ 在 Lambda 代理整合中，API Gateway 只會在收到 Lambda 的完整回應後將回應傳送至用戶端。在回應串流的 Lambda 代理整合中，API Gateway 會在從 Lambda 收到有效的中繼資料和分隔符號後開始承載串流。
+ 回應串流的 Lambda 代理整合使用與代理整合相同的輸入格式，但需要不同的輸出格式。

## 用於回應串流的 Lambda 代理整合格式
<a name="response-transfer-mode-lambda-format"></a>

當 API Gateway 使用回應串流叫用 Lambda 函數時，輸入格式與 Lambda 函數的輸入格式相同，以進行代理整合。如需詳細資訊，請參閱[代理整合之 Lambda 函數的輸入格式](set-up-lambda-proxy-integrations.md#api-gateway-simple-proxy-for-lambda-input-format)。

當 Lambda 將回應串流至 API Gateway 時，回應必須遵循下列格式。此格式使用分隔符號來分隔中繼資料 JSON 和原始承載。在此情況下，承載資料會在串流 Lambda 函數傳輸時串流：

```
{
  "headers": {"headerName": "headerValue", ...},
  "multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
  "cookies" : ["cookie1", "cookie2"],
  "statusCode": httpStatusCode
}<DELIMITER>PAYLOAD1 | PAYLOAD2 | PAYLOAD3
```

在輸出中：
+ 如果沒有傳回額外的回應標頭`headers``multiValueHeaders`，則無法指定 、`cookies`、 和 `statusCode`金鑰。
+ `headers` 鍵只能包含單一值標頭。
+ 輸出預期標頭包含 `Transfer-Encoding: chunked`或 `Content-length: number`。如果您的函數未傳回其中一個標頭，API Gateway 會附加`Transfer-Encoding: chunked`到回應標頭。
+ `multiValueHeaders` 鍵可以包含多值標頭以及單一值標頭。您可以使用 `multiValueHeaders` 鍵來指定所有額外標頭，包括任何單一值標頭。
+ 如果您同時指定 `headers` 和 `multiValueHeaders` 的值，API Gateway 會將它們合併成一個清單。如果在兩者指定了相同的鍵值對，則只有 `multiValueHeaders` 中的值會出現在合併清單。
+ 中繼資料必須是有效的 JSON。僅支援 `headers`、 `multiValueHeaders``cookies`和 `statusCode`金鑰。
+ 您必須在中繼資料 JSON 之後提供分隔符號。分隔符號必須是 8 個 null 位元組，且必須出現在串流資料的前 16KB 內。
+ API Gateway 不需要方法回應承載的特定格式。

如果您使用函數 URL 串流 Lambda 函數，則必須修改 Lambda 函數的輸入和輸出，以滿足這些要求。

如果您的 Lambda 函數輸出不符合此格式的要求，API Gateway 可能仍會叫用您的 Lambda 函數。下表顯示 API Gateway 支援的 API 整合請求設定和 Lambda 函數程式碼的組合。這包括緩衝的回應傳輸模式支援的組合。


| 回應傳輸模式 | 函數程式碼遵循所需的格式 | Lambda 叫用 API | API Gateway 支援 | 
| --- | --- | --- | --- | 
|  串流  |  是  |   [InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html)  |  是。API Gateway 會串流您的回應。  | 
|  串流  |  否  |   [InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html)  |  否。API Gateway 會叫用您的 Lambda 函數並傳回 500 錯誤回應。  | 
|  串流  |  是  |   [Invoke](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)  |  否。API Gateway 不支援此整合組態。  | 
|  串流  |  否  |   [Invoke](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)  |  否。API Gateway 不支援此整合組態。  | 
|  緩衝  |  是  |   [InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html)  |  否。API Gateway 不支援此整合組態。  | 
|  緩衝  |  否  |   [InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html)  |  否。API Gateway 不支援此整合組態。  | 
|  緩衝  |  是  |   [Invoke](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)  |  API Gateway 會傳回 HTTP 標頭和狀態碼，但不會傳回回應內文。  | 
|  緩衝  |  否  |   [Invoke](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)  |  是。這是 Lambda 代理整合。如需詳細資訊，請參閱 [Lambda 代理整合](set-up-lambda-proxy-integrations.md)。  | 

# 在 API Gateway 中設定 Lambda 代理整合與承載回應串流
<a name="response-streaming-lambda-configure"></a>

當您設定回應承載串流時，您可以在資源的整合請求中指定傳輸模式。您可以在整合請求中設定這些設定，以控制 API Gateway 在整合回應之前和期間的行為。

## 回應串流的 Lambda 函數範例
<a name="response-streaming-lambda-example"></a>

您的 Lambda 函數必須遵循 [用於回應串流的 Lambda 代理整合格式](response-transfer-mode-lambda.md#response-transfer-mode-lambda-format)。我們建議您使用三個範例 Lambda 函數之一來測試回應串流。當您建立 Lambda 函數時，請務必執行下列動作：
+ 為您的函數提供足夠的逾時。我們建議您設定至少 1 分鐘的逾時，以了解回應串流。當您建立生產資源時，請確定 Lambda 函數逾時涵蓋完整的請求週期。如需詳細資訊，請參閱[設定 Lambda 函數逾時](https://docs.aws.amazon.com/lambda/latest/dg/configuration-timeout.html)。
+ 使用最新的 Node.js 執行時間。
+ 使用可使用 Lambda 回應串流的區域。

------
#### [ Using HttpResponseStream.from ]

下列程式碼範例使用 `awslambda.HttpResponseStream()`方法將 JSON 中繼資料物件和承載串流回用戶端，而不使用管道方法。您不需要建立分隔符號。如需詳細資訊，請參閱[撰寫啟用回應串流功能的 Lambda 函數](https://docs.aws.amazon.com/lambda/latest/dg/config-rs-write-functions.html)。

```
export const handler = awslambda.streamifyResponse(
  async (event, responseStream, context) => {
    const httpResponseMetadata = {
      "statusCode": 200,
      "headers": {
        "x-foo": "bar"
      },
      "multiValueHeaders": {
        "x-mv1": ["hello", "world"],
        "Set-Cookie": ["c1=blue", "c2=red"]
      }
    };

    responseStream = awslambda.HttpResponseStream.from(responseStream, httpResponseMetadata);
    await new Promise(r => setTimeout(r, 1000)); // synthetic delay

    responseStream.write("First payload ");
    await new Promise(r => setTimeout(r, 1000)); // synthetic delay

    responseStream.write("Final payload");
    responseStream.end();
});
```

------
#### [ Using the pipeline method ]

Lambda 建議您在撰寫啟用回應串流的函數時，使用原生 Node.js 執行時間提供的`awslambda.streamifyResponse()`裝飾項目，以及 `pipeline()`方法。當您使用管道方法時，您不需要建立分隔符號，Lambda 會為您執行此操作。如需詳細資訊，請參閱[撰寫啟用回應串流功能的 Lambda 函數](https://docs.aws.amazon.com/lambda/latest/dg/config-rs-write-functions.html)。

下列程式碼範例會將 JSON 中繼資料物件和三個承載串流回用戶端。

```
import { pipeline } from 'node:stream/promises';
import { Readable } from 'node:stream';

export const handler = awslambda.streamifyResponse(
  async (event, responseStream, context) => {
    const httpResponseMetadata = {
      statusCode: 200,
      headers: {
        "Content-Type": "text/plain",
        "X-Custom-Header": "Example-Custom-Header"
      }
    };

    responseStream = awslambda.HttpResponseStream.from(responseStream, httpResponseMetadata);

    const dataStream = Readable.from(async function* () {
      yield "FIRST payload\n";
      await new Promise(r => setTimeout(r, 1000));
      yield "SECOND payload\n";
      await new Promise(r => setTimeout(r, 1000));
      yield "THIRD payload\n";
      await new Promise(r => setTimeout(r, 1000));
    }());

    await pipeline(dataStream, responseStream);
  }
);
```

------
#### [ Without using the pipeline method ]

下列程式碼範例會將 JSON 中繼資料物件和三個承載串流回用戶端，而無需使用 `awslambda.HttpResponseStream()`方法。如果沒有 `awslambda.HttpResponseStream()`方法，您必須在中繼資料和承載之間包含 8 個 null 位元組的分隔符號。

```
export const handler = awslambda.streamifyResponse(async (event, response, ctx) => {
  response.write('{"statusCode": 200, "headers": {"hdr-x": "val-x"}}');
  response.write("\x00".repeat(8)); // DELIMITER
  await new Promise(r => setTimeout(r, 1000));

  response.write("FIRST payload");
  await new Promise(r => setTimeout(r, 1000));

  response.write("SECOND payload");
  await new Promise(r => setTimeout(r, 1000));

  response.write("FINAL payload");
  response.end();
});
```

------

## 建立與承載回應串流的 Lambda 代理整合
<a name="response-streaming-lambda-create"></a>

下列程序說明如何建立與承載回應串流的 Lambda 代理整合。使用範例 Lambda 函數或建立您自己的函數。

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

**建立與承載回應串流的 Lambda 代理整合**

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

1. 選擇 REST API。

1. 選擇**建立資源**。

1. 針對**資源名稱**，輸入 **streaming**。

1. 選擇**建立資源**。

1. 選取 **/streaming** 資源後，選擇**建立方法**。

1. 針對**方法類型**，選擇**任何**。

1. 對於 **整合類型**，選擇 **Lambda**。

1. 選擇 **Lambda 代理整合**。

1. 針對**回應傳輸模式**，選擇**串流**。

1. 針對 **Lambda 函數**，選擇 Lambda 函數的名稱。

   API Gateway 主控台會自動使用 [InvokeWithResponseStream](https://docs.aws.amazon.com/lambda/latest/api/API_InvokeWithResponseStream.html) API 來叫用 Lambda 函數。您負責撰寫啟用回應串流功能的 Lambda 函數。如需範例，請參閱 [回應串流的 Lambda 函數範例](#response-streaming-lambda-example)。

1. 選擇**建立方法**。

建立方法之後，請部署您的 API。

**部署 API**

1. 選擇**部署 API**。

1. 針對**階段**，選取**新階段**。

1. 針對**階段名稱**，輸入 **prod**。

1. 在**描述**，請輸入描述。

1. 選擇**部署**。

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

下列程序說明如何匯入將 `responseTransferMode` 設為 的新 API`STREAM`。如果您有現有的整合 API 並想要修改 `responseTransferMode`，請參閱 [更新 Lambda 代理整合的回應傳輸模式](#response-streaming-lambda-update)。

**使用承載回應串流建立新的 API**

1. 複製下列 Open API 檔案，然後將其儲存為 `ResponseStreamDemoSwagger.yaml`。在此檔案中， `responseTransferMode` 設定為 `STREAM`，而整合 URI 設定為 `arn:aws:apigateway:us-west-1:lambda:path/2021-11-15/functions/arn:aws:lambda:us-west-1:111122223333:function:my-function-name/response-streaming-invocations`。

   將 中的函數名稱取代`my-function`為啟用串流的函數，並將登入資料取代為具有允許`apigateway`服務呼叫 Lambda 函數之政策的 IAM 角色。

   ```
   openapi: "3.0.1"
   info:
     title: "ResponseStreamingDemo"
     version: "2025-04-28T17:28:25Z"
   servers:
   - url: "{basePath}"
     variables:
       basePath:
         default: "prod"
   paths:
     /lambda:
       get:
         x-amazon-apigateway-integration:
           httpMethod: "POST"
           uri: "arn:aws:apigateway:us-west-1:lambda:path/2021-11-15/functions/arn:aws:lambda:us-west-1:111122223333:function:my-function-name/response-streaming-invocations"
           type: "aws_proxy"
           timeoutInMillis: 90000
           responseTransferMode: "STREAM"
           credentials: "arn:aws:iam::111122223333:role/apigateway-lambda-role"
   ```

   您可以使用 Lambda 的 `add-permission`命令來新增以資源為基礎的許可，而不是為登入資料提供 IAM 角色。

1. 使用下列`import-rest-api`命令匯入您的 OpenAPI 定義：

   ```
   aws apigateway import-rest-api \
     --body 'fileb://~/ResponseStreamDemoSwagger.yaml' \
     --parameters endpointConfigurationTypes=REGIONAL \
     --region us-west-1
   ```

1. 使用下列`create-deployment`命令將您的新 API 部署到階段：

   ```
   aws apigateway create-deployment \
     --rest-api-id a1b2c2 \
     --stage-name prod \
     --region us-west-1
   ```

------

### 更新 Lambda 代理整合的回應傳輸模式
<a name="response-streaming-lambda-update"></a>

下列程序說明如何更新 Lambda 代理整合的回應傳輸模式。當您將回應傳輸模式變更為串流時，請更新您的 Lambda 函數，使其遵守回應串流的要求。使用範例 Lambda 函數或建立您自己的函數。

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

**更新 Lambda 代理整合的回應傳輸模式**

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

1. 選擇 REST API。

1. 選擇一個方法。

1. 在**整合請求**索引標籤上，於**整合請求設定**下，選擇**編輯**。

1. 針對**回應傳輸模式**，選擇**串流**。

1. 針對 **Lambda 函數**，選擇 Lambda 函數的名稱。

1. 選擇**儲存**。

更新方法後，請部署您的 API。

**部署 API**

1. 選擇**部署 API**。

1. 針對**階段**，選取**新階段**。

1. 針對**階段名稱**，輸入 **prod**。

1. 在**描述**，請輸入描述。

1. 選擇**部署**。

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

1. 更新您的 Lambda 函數以啟用串流。

1. 使用下列 AWS CLI 命令來更新整合的整合 URI 和回應傳輸模式：

   ```
   aws apigateway update-integration \
    --rest-api-id a1b2c3 \
    --resource-id aaa111 \
    --http-method ANY \
    --patch-operations "[{\"op\":\"replace\",\"path\":\"/uri\",\"value\":\"arn:aws:apigateway:us-west-1:lambda:path/2021-11-15/functions/arn:aws:lambda:us-west-1:111122223333:function:my-function-name/response-streaming-invocations\"}, {\"op\":\"replace\",\"path\":\"/responseTransferMode\",\"value\":\"STREAM\"}]" \
    --region us-west-1
   ```

1. 重新部署 API 以使變更生效。

------

# 針對 API Gateway 中的回應串流問題進行故障診斷
<a name="response-streaming-troubleshoot"></a>

下列疑難排解指引可能有助於解決使用回應串流APIs 的問題。

## 一般性問題的故障診斷
<a name="response-streaming-general-troubleshooting"></a>

您可以使用 [TestInvokeMethod](https://docs.aws.amazon.com/apigateway/latest/api/API_TestInvokeMethod.html) 或主控台的測試索引標籤來測試串流回應。下列考量事項可能會影響您使用測試叫用進行回應串流：
+ 當您測試方法時，API Gateway 會緩衝串流的回應承載。一旦符合下列任一條件，API Gateway 便會傳回包含緩衝承載的一次性回應：
  + 請求已完成
  + 已經過 35 秒
  + 已緩衝超過 1 MB 的回應承載
+ 如果超過 35 秒才傳回 HTTP 回應狀態和所有標頭，則 TestInvokeMethod 中傳回的回應狀態為 0。
+ API Gateway 不會產生任何執行日誌。

部署 API 之後，您可以使用 curl 命令來測試串流回應。建議您使用 `-i`選項，在輸出中包含通訊協定回應標頭。若要查看到達時的回應資料，請使用 curl 選項 `--no-buffer`

## 針對 cURL 錯誤進行故障診斷
<a name="response-streaming-troubleshoot-curl-error"></a>

如果您正在測試整合並收到錯誤 `curl: (18) transfer closed with outstanding read data remaining`，請確定整合的逾時時間夠長。如果您使用的是 Lambda 函數，則需要更新 Lambda 函數的回應逾時。如需詳細資訊，請參閱[設定 Lambda 函數逾時](https://docs.aws.amazon.com/lambda/latest/dg/configuration-timeout.html)。

## 使用存取記錄進行故障診斷
<a name="response-streaming-troubleshoot-access-logging"></a>

您可以使用 REST API 階段的存取日誌來記錄回應串流並進行疑難排解。除了現有的變數之外，您還可以使用下列存取日誌變數：

`$context.integration.responseTransferMode`  
整合的回應傳輸模式。可以是 `BUFFERED` 或 `STREAMED`。

`$context.integration.timeToAllHeaders`  
從用戶端接收所有整合回應標頭時，API Gateway 與 建立整合連線之間的時間。

`$context.integration.timeToFirstContent`  
API Gateway 在收到第一個內容位元組時建立與 的整合連線之間的時間。

`$context.integration.latency` 或 `$context.integrationLatency`  
當整合回應串流完成時，API Gateway 與 建立整合連線的時間。

下圖顯示這些存取日誌變數如何代表回應串流的不同元件。

![\[在 API Gateway 中存取回應串流的日誌變數\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/response-streaming-figure.png)


如需存取日誌的詳細資訊，請參閱[在 API Gateway 中設定 REST API 的 CloudWatch 記錄功能](set-up-logging.md)。您也可以使用 X-Ray 來監控回應串流。如需詳細資訊，請參閱[在 API Gateway 中使用 X-Ray 追蹤使用者對 REST API 的請求](apigateway-xray.md)。

# API Gateway 中 REST API 的私有整合
<a name="private-integration"></a>

使用私有整合公開 Amazon VPC 內的 HTTP/HTTPS 資源，供 VPC 外部的用戶端存取。這會將對私有 VPC 資源的存取延伸到 VPC 邊界之外。您可以使用 API Gateway 支援的任何[授權方法](apigateway-control-access-to-api.md)來控制對您的 API 的存取。

若要建立私有整合，您必須先建立 VPC 連結。API Gateway 支援適用於 REST APIs VPC 連結 V2。VPC 連結 V2 可讓您建立私有整合，將 REST API 連線至 Application Load Balancer，而無需使用 Network Load Balancer。使用 Application Load Balancer 可讓您連線至 Amazon ECSs容器型應用程式和許多其他後端。VPC 連結 V1 被視為舊版整合類型。雖然 API Gateway 支援這些連結，但建議您不要建立新的 VPC 連結 V1。

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

下列考量事項可能會影響您使用私有整合：
+ 所有資源都必須由相同的 擁有 AWS 帳戶。這包括負載平衡器、VPC 連結和 REST API。
+ 依預設，私有整合流量會使用 HTTP 通訊協定。若要使用 HTTPS，請指定包含安全伺服器名稱[https://docs.aws.amazon.com/apigateway/latest/api/API_PutIntegration.html#apigw-PutIntegration-request-uri](https://docs.aws.amazon.com/apigateway/latest/api/API_PutIntegration.html#apigw-PutIntegration-request-uri)的 ，例如 `https://example.com:443/test`。
+ 在私有整合中，API Gateway 會在對後端資源的請求中包含 API 端點的[階段](set-up-stages.md)部分。例如，如果您請求 API 的`test`階段，API Gateway 會在私有整合的請求`test/path`中包含 。若要從對後端資源的請求移除階段名稱，請使用[參數映射](rest-api-parameter-mapping.md)來建立`$context.requestOverride.path`變數的覆寫。
+  AWS Cloud Map 不支援與 的私有整合。

**Topics**
+ [考量事項](#private-integrations-considerations)
+ [在 API Gateway 中設定 VPC 連結 V2](apigateway-vpc-links-v2.md)
+ [設定私有整合](set-up-private-integration.md)
+ [使用 VPC 連結 V1 的私有整合 （舊版）](vpc-links-v1.md)

# 在 API Gateway 中設定 VPC 連結 V2
<a name="apigateway-vpc-links-v2"></a>

VPC 連結可讓您建立私有整合，將 API 路由連線至 VPC 中的私有資源，例如 Application Load Balancer 或 Amazon ECS 容器型應用程式。私有整合使用 VPC 連結 V2 封裝 API Gateway 與目標 VPC 資源之間的連線。您可以重複使用不同資源和 APIs VPC 連結。

當您建立 VPC 連結時，API Gateway 會建立和管理您帳戶中 VPC 連結 V2 的[彈性網路介面](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html)。此程序需要幾分鐘的時間。當 VPC 連結 V2 可供使用時，其狀態會從 轉換為 `PENDING` `AVAILABLE`。

**注意**  
如果 60 天內沒有透過 VPC 連結傳送流量，則會變成 `INACTIVE`。當 VPC 連結處於 `INACTIVE` 狀態時，API Gateway 會刪除所有 VPC 連結的網路介面。這會導致依賴 VPC 連結的 API 請求失敗。如果 API 請求繼續，API Gateway 會重新佈建網路介面。建立網路介面並重新啟用 VPC 連結可能需要幾分鐘的時間。您可以使用 VPC 連結狀態來監控 VPC 連結的狀態。

## 使用 建立 VPC 連結 V2 AWS CLI
<a name="apigateway-vpc-links-v2-create"></a>

若要建立 VPC 連結 V2，所有涉及的資源都必須由相同的 AWS 帳戶擁有。以下 [create-vpc-link](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-vpc-link.html) 命令會建立 VPC 連結：

```
aws apigatewayv2 create-vpc-link --name MyVpcLink \
    --subnet-ids subnet-aaaa subnet-bbbb \
    --security-group-ids sg1234 sg5678
```

**注意**  
VPC 連結 V2 是不可變的。建立 VPC 連結 V2 之後，您無法變更其子網路或安全群組。

## 使用 刪除 VPC 連結 V2 AWS CLI
<a name="apigateway-vpc-links-v2-delete"></a>

以下 [delete-vpc-link](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/delete-vpc-link.html) 命令會刪除 VPC 連結。

```
aws apigatewayv2 delete-vpc-link --vpc-link-id abcd123
```

## 各個區域的供應情形
<a name="apigateway-vpc-links-v2-availability"></a>

下列區域和可用區域支援 VPC 連結 V2：

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/apigateway-vpc-links-v2.html)

# 設定私有整合
<a name="set-up-private-integration"></a>

若要建立與 Application Load Balancer 或 Network Load Balancer 的私有整合，您可以建立 HTTP 代理整合、指定要使用的 [VPC 連結 V2](apigateway-vpc-links-v2.md)，並提供 Network Load Balancer 或 Application Load Balancer 的 ARN。依預設，私有整合流量會使用 HTTP 通訊協定。若要使用 HTTPS，請指定包含安全伺服器名稱[https://docs.aws.amazon.com/apigateway/latest/api/API_PutIntegration.html#apigw-PutIntegration-request-uri](https://docs.aws.amazon.com/apigateway/latest/api/API_PutIntegration.html#apigw-PutIntegration-request-uri)的 ，例如 `https://example.com:443/test`。如需如何使用私有整合建立 REST API 的完整教學課程，請參閱 [教學：建立具私有整合的 REST API](getting-started-with-private-integration.md)。

## 建立私有整合
<a name="set-up-private-integration-create"></a>

下列程序說明如何使用 VPC 連結 V2 建立連線至負載平衡器的私有整合。

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

如需如何建立私有整合的教學課程，請參閱 [教學：建立具私有整合的 REST API](getting-started-with-private-integration.md)。

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

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

```
aws apigateway put-integration \
    --rest-api-id abcdef123 \
    --resource-id aaa000 \
    --integration-target 'arn:aws:elasticloadbalancing:us-east-2:111122223333:loadbalancer/app/myLoadBalancerName/1234567891011' \
    --uri 'https://example.com:443/path' \
    --http-method GET \
    --type HTTP_PROXY \
    --integration-http-method GET \
    --connection-type VPC_LINK \
    --connection-id bbb111
```

您可以改用階段變數，而不是直接提供連線 ID。當您將 API 部署到階段時，您可以設定 VPC 連結 V2 ID。下列 [put-integration](https://docs.aws.amazon.com/cli/latest/reference/latest/api/API_PutIntegration.html) 命令會使用 VPC 連結 V2 ID 的階段變數建立私有整合：

```
aws apigateway put-integration \
    --rest-api-id abcdef123 \
    --resource-id aaa000 \
    --integration-target 'arn:aws:elasticloadbalancing:us-east-2:111122223333:loadbalancer/app/myLoadBalancerName/1234567891011' \
    --uri 'https://example.com:443/path' \
    --http-method GET \
    --type HTTP_PROXY \
    --integration-http-method GET \
    --connection-type VPC_LINK \
    --connection-id "\${stageVariables.vpcLinkV2Id}"
```

請務必對階段變數表達式 (\$1\$1stageVariables.vpcLinkV2Id\$1) 進行雙引號，並逸出 \$1 字元。

------
#### [ OpenAPI ]

您可以匯入 API OpenAPI 檔案來設定具有私有整合的 API。這些設定類似具有 HTTP 整合之 API 的 OpenAPI 定義，但例外如下：
+ 您必須將 `connectionType` 明確地設定為 `VPC_LINK`。
+ 您必須將 `connectionId` 明確地設定為 `VpcLinkV2` 的 ID 或參考 `VpcLinkV2` ID 的階段變數。
+ 私有整合中的 `uri` 參數指向 VPC 中的 HTTP/HTTPS 端點，但改為用來設定整合請求的 `Host` 標頭。
+ 具有 VPC 中 HTTPS 端點之私有整合中的 `uri` 參數用來針對 VPC 端點上所安裝憑證中的網域名稱來驗證所指出的網域名稱。

 您可以使用階段變數來參考 `VpcLinkV2` ID。或者，您可以將 ID 值直接指派給 `connectionId`。

下列 JSON 格式化 OpenAPI 檔案會顯示 API 的範例，具有階段變數 (`${stageVariables.vpcLinkIdV2}`) 所參考的 VPC 連結：

```
{
  "swagger": "2.0",
  "info": {
    "version": "2017-11-17T04:40:23Z",
    "title": "MyApiWithVpcLinkV2"
  },
  "host": "abcdef123.execute-api.us-west-2.amazonaws.com",
  "basePath": "/test",
  "schemes": [
    "https"
  ],
  "paths": {
    "/": {
      "get": {
        "produces": [
          "application/json"
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "uri": "https://example.com:443/path",
          "passthroughBehavior": "when_no_match",
          "connectionType": "VPC_LINK",
          "connectionId": "${stageVariables.vpcLinkV2Id}",
          "integration-target": "arn:aws:elasticloadbalancing:us-east-2:111122223333:loadbalancer/app/myLoadBalancerName/1234567891011",
          "httpMethod": "GET",
          "type": "http_proxy"
        }
      }
    }
  },
  "definitions": {
    "Empty": {
      "type": "object",
      "title": "Empty Schema"
    }
  }
}
```

------

## 更新私有整合
<a name="set-up-private-integration-update"></a>

下列範例會更新私有整合的 VPC 連結 V2。

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

**更新私有整合**

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

1. 選擇具有私有整合的 REST API。

1. 選擇使用私有整合的資源和方法。

1. 在**整合請求**標籤上，於**整合請求設定**下，選擇**編輯**。

1. 您可以編輯私有整合的設定。如果您目前正在使用 VPC 連結 V1，您可以將 VPC 連結變更為 VPC 連結 V2。

1. 選擇**儲存**。

1. 重新部署 API 以使變更生效。

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

下列 [update-integration](https://docs.aws.amazon.com/cli/latest/reference/latest/api/API_PutIntegration.html) 命令會更新私有整合，以使用 VPC 連結 V2：

```
aws apigateway update-integration \
    --rest-api-id a1b2c3d4e5 \
    --resource-id a1b2c3 \
    --http-method GET \
    --patch-operations "[{\"op\":\"replace\",\"path\":\"/connectionId\",\"value\":\"pk0000\"}, {\"op\":\"replace\",\"path\":\"/uri\",\"value\":\"http://example.com\"}, {\"op\":\"replace\",\"path\":\"/integrationTarget\",\"value\":\"arn:aws:elasticloadbalancing:us-east-2:111122223333:loadbalancer/app/myLoadBalancerName/1234567891011\"}]"
```

------

# 使用 VPC 連結 V1 的私有整合 （舊版）
<a name="vpc-links-v1"></a>

**注意**  
下列私有整合實作會使用 VPC 連結 V1。VPC 連結 V1 是舊版資源。建議您將 [VPC 連結 V2 用於 REST APIs](apigateway-vpc-links-v2.md)。

若要建立私有整合，您必須先建立 Network Load Balancer。您的 Network Load Balancer 必須有一個[接聽程式](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-listeners.html)，將請求路由至 VPC 中的資源。為了改善 API 可用性，請確定您的 Network Load Balancer 可將流量路由至 AWS 區域中一個以上可用區域內的資源。然後，您會建立用來連線 API 和 Network Load Balancer 的 VPC 連結。建立 VPC 連結後，您可以建立私有整合，以透過 VPC 連結和 Network Load Balancer 將流量從 API 路由到 VPC 中的資源。Network Load Balancer 和 API 必須擁有相同的 AWS 帳戶。

**Topics**
+ [設定 API Gateway 私有整合的 Network Load Balancer （舊版）](set-up-nlb-for-vpclink-using-console.md)
+ [授予 API Gateway 建立 VPC 連結的許可 （舊版）](grant-permissions-to-create-vpclink.md)
+ [使用 AWS CLI （舊版） 設定具有私有整合的 API Gateway API](set-up-api-with-vpclink-cli.md)
+ [用於私有整合的 API Gateway 帳戶 （舊版）](set-up-api-with-vpclink-accounts.md)

# 設定 API Gateway 私有整合的 Network Load Balancer （舊版）
<a name="set-up-nlb-for-vpclink-using-console"></a>

**注意**  
下列私有整合實作會使用 VPC 連結 V1。VPC 連結 V1 是舊版資源。建議您將 [VPC 連結 V2 用於 REST APIs](apigateway-vpc-links-v2.md)。

 下列程序概述使用 Amazon EC2 主控台設定 API Gateway 私有整合之 Network Load Balancer (NLB) 的步驟，並提供每個步驟之詳細說明的參考。

對於每個 VPC 中的資源，您只需要設定一個 NLB 和一個 VPCLink。每個 NLB 皆支援多個[接聽程式](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-listeners.html)和[目標群組](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html)。您可以設定每個服務為 NLB 上特定的接聽程式，使用單一 VPCLink 連接到 NLB。當您在 API Gateway 中建立私有整合時，將使用指定到每個服務的特定連接埠定義每個服務。如需詳細資訊，請參閱[教學：建立具私有整合的 REST API](getting-started-with-private-integration.md)。Network Load Balancer 和 API 必須擁有相同的 AWS 帳戶。

**使用 API Gateway 主控台建立私有整合的 Network Load Balancer**

1. 登入 AWS 管理主控台 ，並在 [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)：// 開啟 Amazon EC2 主控台。

1. 在 Amazon EC2 執行個體上設定 Web 伺服器。如需範例設定，請參閱[在 Amazon Linux 2 上安裝 LAMP Web Server](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-lamp-amazon-linux-2.html)。

1. 建立 Network Load Balancer、註冊具有目標群組的 EC2 執行個體，並將目標群組新增至 Network Load Balancer 接聽程式。如需詳細資訊，請參閱 [Network Load Balancer 入門](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancer-getting-started.html)中的指示。

1. 建立 Network Load Balancer 之後，執行下列操作：

   1.  記下 Network Load Balancer 的 ARN。您需要它才能在 API Gateway 中建立 VPC 連結，以整合 API 與受 Network Load Balancer 保護的 VPC 資源。

   1.  針對 PrivateLink 關閉安全群組評估。
      + 若要使用主控台關閉 PrivateLink 流量的安全群組評估，您可以選擇**安全**標籤，然後選擇**編輯**。在**安全設定**中，清除**在 PrivateLink 流量強制執行輸入規則**。
      + 使用以下 [set-security-groups](https://docs.aws.amazon.com/cli/latest/reference/elbv2/set-security-groups.html) 命令關閉 PrivateLink 流量的安全群組評估：

        ```
        aws elbv2 set-security-groups --load-balancer-arn arn:aws:elasticloadbalancing:us-east-2:111122223333:loadbalancer/net/my-loadbalancer/abc12345 \
          --security-groups sg-123345a --enforce-security-group-inbound-rules-on-private-link-traffic off
        ```

**注意**  
請勿將任何相依性新增至 API Gateway CIDR，因為這些相依性必然會在未通知的情況下變更。

# 授予 API Gateway 建立 VPC 連結的許可 （舊版）
<a name="grant-permissions-to-create-vpclink"></a>

**注意**  
下列私有整合實作會使用 VPC 連結 V1。VPC 連結 V1 是舊版資源。我們建議您將 [VPC 連結 V2 用於 REST APIs](apigateway-vpc-links-v2.md)。

若要讓您或您帳戶中的使用者建立和維護 VPC 連結，您或使用者必須有權建立、刪除和檢視 VPC 端點服務組態、變更 VPC 端點服務許可，以及檢查負載平衡器。若要授予這類許可，請使用下列步驟。

**授予建立、更新和刪除 VPC 連結的許可**

1. 建立與下列類似的 IAM 政策：

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "apigateway:POST",
                   "apigateway:GET",
                   "apigateway:PATCH",
                   "apigateway:DELETE"
               ],
               "Resource": [
                   "arn:aws:apigateway:us-east-1::/vpclinks",
                   "arn:aws:apigateway:us-east-1::/vpclinks/*"
               ]
           },
           {
               "Effect": "Allow",
               "Action": [
                   "elasticloadbalancing:DescribeLoadBalancers"
               ],
               "Resource": "*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "ec2:CreateVpcEndpointServiceConfiguration",
                   "ec2:DeleteVpcEndpointServiceConfigurations",
                   "ec2:DescribeVpcEndpointServiceConfigurations",
                   "ec2:ModifyVpcEndpointServicePermissions"
               ],
               "Resource": "*"
           }
       ]
   }
   ```

------

   如果您想要啟用 VPC 連結的標記，請務必允許標記操作。如需詳細資訊，請參閱[允許標記操作](apigateway-tagging-iam-policy.md#allow-tagging)。

1. 建立或選擇 IAM 角色，並將先前的政策連接至角色。

1. 將 IAM 角色指派給您或您帳戶中建立 VPC 連結的使用者。

# 使用 AWS CLI （舊版） 設定具有私有整合的 API Gateway API
<a name="set-up-api-with-vpclink-cli"></a>

**注意**  
下列私有整合實作會使用 VPC 連結 V1。VPC 連結 V1 是舊版資源。建議您將 [VPC 連結 V2 用於 REST APIs](apigateway-vpc-links-v2.md)。

下列教學課程說明如何使用 AWS CLI 來建立 VPC 連結和私有整合。需要下列先決條件：
+ 您需要使用 VPC 來源來建立並設定 Network Load Balancer，並將其當成目標。如需詳細資訊，請參閱[設定 API Gateway 私有整合的 Network Load Balancer （舊版）](set-up-nlb-for-vpclink-using-console.md)。這必須與 API AWS 帳戶 位於相同的 中。您需要 Network Load Balancer ARN 才能建立 VPC 連結。
+ 若要建立和管理 `VpcLink`，您需要可在 API 中建立 `VpcLink` 的許可權。使用 `VpcLink` 不需要許可權。如需詳細資訊，請參閱[授予 API Gateway 建立 VPC 連結的許可 （舊版）](grant-permissions-to-create-vpclink.md)。

**使用 設定具有私有整合的 API AWS CLI**

1. 使用以下 [create-vpc-link](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-vpc-link.html) 命令會建立以指定的 Network Load Balancer 為目標的 `VpcLink`：

   ```
   aws apigateway create-vpc-link \
       --name my-test-vpc-link \
       --target-arns arn:aws:elasticloadbalancing:us-east-2:123456789012:loadbalancer/net/my-vpclink-test-nlb/1234567890abcdef
   ```

   此命令的輸出會確認收到請求，並顯示建立中 `VpcLink` 的 `PENDING` 狀態。

   ```
   {
       "status": "PENDING", 
       "targetArns": [
           "arn:aws:elasticloadbalancing:us-east-2:123456789012:loadbalancer/net/my-vpclink-test-nlb/1234567890abcdef"
       ], 
       "id": "gim7c3", 
       "name": "my-test-vpc-link"
   }
   ```

   API Gateway 需要 2-4 分鐘才能完成建立 `VpcLink`。操作順利完成時，`status` 是 `AVAILABLE`。您可以使用下列 [get-vpc-link](https://docs.aws.amazon.com/cli/latest/reference/apigateway/get-vpc-link.html) 命令進行驗證：

   ```
   aws apigateway get-vpc-link --vpc-link-id gim7c3
   ```

   如果操作失敗，您會取得 `FAILED` 狀態，以及包含錯誤訊息的 `statusMessage`。例如，如果您嘗試建立具有已與 VPC 端點建立關聯之 Network Load Balancer 的 `VpcLink`，則會在 `statusMessage` 屬性上收到下列訊息：

   ```
   "NLB is already associated with another VPC Endpoint Service"
   ```

   順利建立 `VpcLink` 之後，您可以建立 API 並透過 `VpcLink` 將其與 VPC 資源整合。

   記下新建立之 `VpcLink` 的 `id` 值。在此範例輸出中為 `gim7c3`。您需要它才能設定私有整合。

1. 使用以下 [create-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-rest-api.html) 命令建立 API Gateway [https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html](https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html) 資源：

   ```
   aws apigateway create-rest-api --name 'My VPC Link Test'
   ```

   請記下所傳回結果中 `RestApi` 的 `id` 值，和 `RestApi` 的 `rootResourceId` 值。您需要此值才能對 API 執行進一步操作。

   接著在根資源 (`/`) 上建立只有 `GET` 方法的 API，並整合此方法與 `VpcLink`。

1. 使用以下 [put-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-method.html) 命令建立 `GET /` 方法：

   ```
   aws apigateway put-method \
          --rest-api-id  abcdef123 \
          --resource-id skpp60rab7 \
          --http-method GET \
          --authorization-type "NONE"
   ```

   如果您未搭配 `VpcLink` 使用代理整合，至少也必須設定 `200` 狀態碼的方法回應。在這裡使用代理整合。

1. 建立 `GET /` 方法後，您可以設定整合。對於私有整合，您可以使用 `connection-id` 參數來提供 `VpcLink` ID。您可以使用階段變數或直接輸入 `VpcLink` ID。`uri` 參數不是用於將請求路由至端點，但用於設定 `Host` 標頭以及進行憑證驗證。

------
#### [ Use the VPC link ID ]

   使用以下 [put-integration](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration.html) 命令，以直接在整合中使用 `VpcLink` ID：

   ```
   aws apigateway put-integration \
       --rest-api-id abcdef123 \
       --resource-id skpp60rab7 \
       --uri 'http://my-vpclink-test-nlb-1234567890abcdef.us-east-2.amazonaws.com' \
       --http-method GET \
       --type HTTP_PROXY \
       --integration-http-method GET \
       --connection-type VPC_LINK \
       --connection-id gim7c3
   ```

------
#### [ Use a stage variable ]

   使用以下 [put-integration](https://docs.aws.amazon.com/cli/latest/reference/apigateway/put-integration.html) 命令，以使用階段變數來參考 VPC 連結 ID。當您將 API 部署到階段時，可以設定 VPC 連結 ID。

   ```
   aws apigateway put-integration \
       --rest-api-id abcdef123 \
       --resource-id skpp60rab7 \
       --uri 'http://my-vpclink-test-nlb-1234567890abcdef.us-east-2.amazonaws.com' \
       --http-method GET \
       --type HTTP_PROXY \
       --integration-http-method GET \
       --connection-type VPC_LINK \
       --connection-id "\${stageVariables.vpcLinkId}"
   ```

   請務必使用雙引號括住階段變數表達式 (`${stageVariables.vpcLinkId}`) 並逸出 `$` 字元。

------

   您也可以隨時更新整合，以變更 `connection-id`。使用以下 [update-integration](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-integration.html) 命令來更新整合：

   ```
    aws apigateway update-integration \
       --rest-api-id abcdef123 \
       --resource-id skpp60rab7 \
       --http-method GET \
       --patch-operations '[{"op":"replace","path":"/connectionId","value":"${stageVariables.vpcLinkId}"}]'
   ```

   請務必使用字串化 JSON 清單做為 `patch-operations` 參數值。

   因為您使用了私有代理整合，所以 API 現在已準備好進行部署和執行測試。

1. 如果使用階段變數來定義 `connection-id`，您需要部署 API 來進行測試。使用以下 [create-deployment](https://docs.aws.amazon.com/cli/latest/reference/apigateway/create-deployment.html) 命令，以部署有階段變數的 API：

   ```
   aws apigateway create-deployment \
       --rest-api-id abcdef123 \
       --stage-name test \
       --variables vpcLinkId=gim7c3
   ```

   若要以不同的 `VpcLink` ID 更新階段變數 (例如 `asf9d7`)，請使用 [update-stage](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-stage.html) 命令：

   ```
   aws apigateway update-stage \
       --rest-api-id abcdef123 \
       --stage-name test \
       --patch-operations op=replace,path='/variables/vpcLinkId',value='asf9d7'
   ```

   當使用 `VpcLink` ID 常值硬式編碼 `connection-id` 屬性時，您不需要部署 API 來進行測試。使用 [test-invoke-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/test-invoke-method.html) 命令，在部署之前先測試您的 API。

1. 使用下列命令叫用 API：

   ```
   curl -X GET https://abcdef123.execute-api.us-east-2.amazonaws.com/test
   ```

   或者，您可以在 Web 瀏覽器中輸入 API 的調用 URL 來檢視結果。

# 用於私有整合的 API Gateway 帳戶 （舊版）
<a name="set-up-api-with-vpclink-accounts"></a>

當您建立 `VpcLink` 時，下列特定區域 API Gateway 帳戶 ID 也會作為 `AllowedPrincipals` 自動新增至 VPC 端點服務。


| **區域** | **帳戶 ID** | 
| --- | --- | 
| us-east-1 | 392220576650 | 
| us-east-2 | 718770453195 | 
| us-west-1 | 968246515281 | 
| us-west-2 | 109351309407 | 
| ca-central-1 | 796887884028 | 
| eu-west-1 | 631144002099 | 
| eu-west-2 | 544388816663 | 
| eu-west-3 | 061510835048 | 
| eu-central-1 | 474240146802 | 
| eu-central-2 | 166639821150 | 
| eu-north-1 | 394634713161 | 
| eu-south-1 | 753362059629 | 
| eu-south-2 | 359345898052 | 
| ap-northeast-1 | 969236854626 | 
| ap-northeast-2 | 020402002396 | 
| ap-northeast-3 | 360671645888 | 
| ap-southeast-1 | 195145609632 | 
| ap-southeast-2 | 798376113853 | 
| ap-southeast-3 | 652364314486 | 
| ap-southeast-4 | 849137399833 | 
| ap-south-1 | 507069717855 | 
| ap-south-2 | 644042651268 | 
| ap-east-1 | 174803364771 | 
| sa-east-1 | 287228555773 | 
| me-south-1 | 855739686837 | 
| me-central-1 | 614065512851 | 

# API Gateway 中 REST API 的模擬整合
<a name="how-to-mock-integration"></a>

Amazon API Gateway 支援 API 方法的模擬整合。此功能可讓 API 開發人員直接從 API Gateway 產生 API 回應，而不需要整合後端。您是 API 開發人員，在專案開發完成之前，可以使用此功能來解鎖需要使用 API 的相依團隊。您也可以使用此功能來佈建您 API 的登錄頁面，以提供 API 的概觀，並導覽至 API。如需這類登錄頁面的範例，請參閱[教學課程：匯入範例來建立 REST API](api-gateway-create-api-from-example.md) 中所討論的範例 API 之根資源上的 GET 方法整合請求和回應。

作為 API 開發人員，您可決定 API Gateway 回應如何模擬整合請求。因此，您設定方法的整合請求和整合回應，以將回應與特定狀態碼建立關聯。若要讓具有模擬整合的方法傳回 `200` 回應，請設定整合請求內文映射範本來傳回下列內容。

```
{"statusCode": 200}
```

設定 `200` 整合回應，以具有下列內文映射範本，例如：

```
{
    "statusCode": 200,
    "message": "Go ahead without me."
}
```

 例如，同樣地，若要讓方法傳回 `500` 錯誤回應，請設定整合請求內文映射範本來傳回下列內容。

```
{"statusCode": 500}
```

例如，設定具有下列映射範本的 `500` 整合回應：

```
{
    "statusCode": 500,
    "message": "The invoked method is not supported on the API resource."
}
```

或者，您可以讓模擬整合方法傳回預設整合回應，而不需要定義整合請求映射範本。預設整合回應具有未定義的 **HTTP status regex (HTTP 狀態 regex)**。請確定已設定適當的傳遞行為。

**注意**  
模擬整合並不支援大型回應範本。如果您的使用案例需要這類範本，應考慮改用 Lambda 整合。

您可使用整合請求映射範本來插入應用程式邏輯，以根據特定條件決定要傳回的模擬整合回應。例如，您可以在傳入請求上使用 `scope` 查詢參數，決定是要傳回成功回應還是錯誤回應：

```
{
  #if( $input.params('scope') == "internal" )
    "statusCode": 200
  #else
    "statusCode": 500
  #end
}
```

因此，模擬整合方法可讓內部呼叫通過，同時拒絕具有錯誤回應之其他類型的呼叫。



在本節中，我們將說明如何使用 API Gateway 主控台來啟用 API 方法的模擬整合。

**Topics**
+ [使用 API Gateway 主控台啟用模擬整合](how-to-mock-integration-console.md)

# 使用 API Gateway 主控台啟用模擬整合
<a name="how-to-mock-integration-console"></a>

您必須在 API Gateway 中有可用的方法。請遵循中的說明進行[教學：建立具有 HTTP 非代理整合的 REST API](api-gateway-create-api-step-by-step.md)

1. 選擇 API 資源，並選擇**建立方法**。

   若要建立方法，請執行下列動作：

   1. 針對**方法類型**，選取某個方法。

   1. 針對**整合類型**，選取**模擬**。

   1. 選擇**建立方法**。

   1. 在**方法請求**索引標籤上，針對**方法請求設定**，選擇**編輯**。

   1. 選擇 **URL 查詢字串參數**。選擇**新增查詢字串**，然後針對**名稱**輸入 **scope**。這個查詢參數會判斷發起人是否為內部。

   1. 選擇**儲存**。

1. 在**方法回應**索引標籤上，選擇**建立回應**，然後執行下列動作：

   1. 針對 **HTTP 狀態**，輸入 **500**。

   1. 選擇**儲存**。

1. 在**整合請求**索引標籤上，針對**整合請求設定**，選擇**編輯**。

1. 選擇**對應範本**，然後執行下列動作：

   1. 選擇**新增映射範本**。

   1. 針對**內容類型**，輸入 **application/json**。

   1. 針對**範本內文**，輸入下列內容：

      ```
      {
        #if( $input.params('scope') == "internal" )
          "statusCode": 200
        #else
          "statusCode": 500
        #end
      }
      ```

   1. 選擇**儲存**。

1. 在**整合回應**索引標籤上，針對**預設 - 回應**選擇**編輯**。

1. 選擇**對應範本**，然後執行下列動作：

   1. 針對**內容類型**，輸入 **application/json**。

   1. 針對**範本內文**，輸入下列內容：

      ```
      {
          "statusCode": 200,
          "message": "Go ahead without me"
      }
      ```

   1. 選擇**儲存**。

1. 選擇**建立回應**。

   若要建立 500 回應，請執行下列動作：

   1. 對於 **HTTP 狀態 regex**，輸入 **5\$1d\$12\$1**。

   1. 針對**方法回應狀態**，選取 **500**。

   1. 選擇**儲存**。

   1. 針對 **5\$1d\$12\$1 - 回應**，選擇**編輯**。

   1. 選擇**對應範本**，然後選擇**新增對應範本**。

   1. 針對**內容類型**，輸入 **application/json**。

   1. 針對**範本內文**，輸入下列內容：

      ```
      {
          "statusCode": 500,
          "message": "The invoked method is not supported on the API resource."
      }
      ```

   1. 選擇**儲存**。

1.  選擇**測試**標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。若要測試模擬整合，請執行下列動作：

   1. 在**查詢字串**下，輸入 `scope=internal`。選擇 **Test (測試)**。測試結果顯示：

      ```
      Request: /?scope=internal
      Status: 200
      Latency: 26 ms
      Response Body
      
      {
        "statusCode": 200,
        "message": "Go ahead without me"
      }
      
      Response Headers
      
      {"Content-Type":"application/json"}
      ```

   1. 在 `Query strings` 下輸入 `scope=public`，或將其空白。選擇 **Test (測試)**。測試結果顯示：

      ```
      Request: /
      Status: 500
      Latency: 16 ms
      Response Body
      
      {
        "statusCode": 500,
        "message": "The invoked method is not supported on the API resource."
      }
      
      Response Headers
      
      {"Content-Type":"application/json"}
      ```

您也可以在模擬整合回應中傳回標頭，方法是先將標頭新增至方法回應，然後在整合回應中設定標頭映射。事實上，這就是 API Gateway 主控台透過傳回 CORS 必要標頭來啟用 CORS 支援的作法。

# API Gateway 中的 REST API 的請求驗證
<a name="api-gateway-method-request-validation"></a>

 您可以先設定 API Gateway 執行 API 請求的基本驗證，再繼續進行整合請求。驗證失敗時，API Gateway 會立即讓請求失敗、將 400 錯誤回應傳回給發起人，並在 CloudWatch Logs 中發布驗證結果。這樣可減少不必要的後端呼叫。更重要的是，它可讓您專注於應用程式特定的驗證努力。您可以驗證請求內文，方法為驗證必要的請求參數是否有效且為非 null 值，或指定模型結構描述進行更複雜的資料驗證。

**Topics**
+ [API Gateway 中的基本請求驗證概觀](#api-gateway-request-validation-basic-definitions)
+ [REST API 的資料模型](models-mappings-models.md)
+ [在 API Gateway 中設定基本請求驗證](api-gateway-request-validation-set-up.md)
+ [AWS CloudFormation 具有基本請求驗證的範例 API 範本](api-gateway-request-validation-sample-cloudformation.md)

## API Gateway 中的基本請求驗證概觀
<a name="api-gateway-request-validation-basic-definitions"></a>

 API Gateway 可以執行基本請求驗證，以便您可以專注於後端的應用程式特定驗證。針對驗證，API Gateway 會驗證下列任一或兩個條件：
+ 是否包含 URI 中的必要請求參數、查詢字串以及傳入請求的標頭，而且不是空白。API Gateway 只會檢查參數是否存在，而不會檢查類型或格式。
+  適用的請求承載會遵守方法中，針對所指內容類型設定的 [JSON 結構描述](https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04)請求。如果找不到相符的內容類型，則不會執行請求驗證。若無論內容類型為何都要使用相同的模型，請將資料模型的內容類型設定為 `$default`。

若要開啟驗證，您必須在[請求驗證程式](https://docs.aws.amazon.com/apigateway/latest/api/API_RequestValidator.html)中指定驗證規則、將驗證程式新增至 API 的[請求驗證程式對應](https://docs.aws.amazon.com/apigateway/latest/api/API_RequestValidator.html)，並將驗證程式指派給個別 API 方法。

**注意**  
請求內文驗證和 [API Gateway 中 REST API 沒有映射範本時，承載的方法請求行為](integration-passthrough-behaviors.md) 是兩個獨立的主題。當請求承載沒有相符的模型結構描述時，您可以選擇傳遞或封鎖原始承載。如需詳細資訊，請參閱[API Gateway 中 REST API 沒有映射範本時，承載的方法請求行為](integration-passthrough-behaviors.md)。

# REST API 的資料模型
<a name="models-mappings-models"></a>

在 API Gateway 中，模型會定義承載的資料結構。在 API Gateway 中，模型以 [JSON 結構描述草稿第 4 版](https://tools.ietf.org/html/draft-zyp-json-schema-04)定義。下列 JSON 物件是 Pet Store 範例中的範例資料。

```
{
    "id": 1,
    "type": "dog",
    "price": 249.99
}
```

資料包含寵物的 `id`、`type` 和 `price`。此資料的模型可讓您：
+ 使用基本請求驗證。
+ 建立對應範本進行資料轉換。
+ 產生 SDK 時，建立使用者定義的資料類型 (UDT)。

![\[PetStore API 的範例 JSON 資料模型。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/how-to-validate-requests.png)


在這個模型中：

1. `$schema` 物件代表有效的 JSON 結構描述版本識別符。此結構描述為 JSON 結構描述草稿第 4 版。

1. `title` 物件是人類看得懂的模型識別符。這個標題是 `PetStoreModel`。

1.  `required` 驗證關鍵字需要 `type` 和 `price`，才能進行基本請求驗證。

1. 模型的 `properties` 是 `id`、`type` 和 `price`。每個物件都有模型中描述的屬性。

1. 物件 `type` 只能具有值 `dog`、`cat` 或 `fish`。

1. 物件 `price` 是一個數字，且受到 `minimum` 為 25 且 `maximum` 為 500 的限制。

## PetStore 模型
<a name="PetStore-model-text"></a>

```
1 {
2 "$schema": "http://json-schema.org/draft-04/schema#",
3  "title": "PetStoreModel",
4  "type" : "object",
5  "required" : [ "price", "type" ],
6  "properties" : {
7    "id" : {
8      "type" : "integer"
9    },
10    "type" : {
11      "type" : "string",
12      "enum" : [ "dog", "cat", "fish" ]
13    },
14    "price" : {
15      "type" : "number",
16      "minimum" : 25.0,
17      "maximum" : 500.0
18    }
19  }
20 }
```

在這個模型中：

1. 在第 2 行，`$schema` 物件代表有效的 JSON 結構描述版本識別符。此結構描述為 JSON 結構描述草稿第 4 版。

1. 在第 3 行，`title` 物件是人類看得懂的模型識別符。這個標題是 `PetStoreModel`。

1.  在第 5 行，`required` 驗證關鍵字需要 `type` 和 `price`，才能進行基本請求驗證。

1.  在第 6 至 17 行，模型的 `properties` 是 `id`、`type` 和 `price`。每個物件都有模型中描述的屬性。

1. 在第 12 行，物件 `type` 只能具有值 `dog`、`cat` 或 `fish`。

1. 在第 14 至 17 行，物件 `price` 是一個數字，且受到 `minimum` 為 25 且 `maximum` 為 500 的限制。

## 建立更複雜的模型
<a name="api-gateway-request-validation-model-more-complex"></a>

 您可以使用 `$ref` 基本值，為較長的模型建立可重複使用的定義。例如，您可以在描述 `price` 物件的 `definitions` 區段中建立稱為 `Price` 的定義。`$ref` 的值是 `Price` 定義。

```
{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "title" : "PetStoreModelReUsableRef",
  "required" : ["price", "type" ],
  "type" : "object",
  "properties" : {
    "id" : {
      "type" : "integer"
    },
    "type" : {
      "type" : "string",
      "enum" : [ "dog", "cat", "fish" ]
    },
    "price" : {
        "$ref": "#/definitions/Price"
    }
  },
  "definitions" : {
      "Price": {
        "type" : "number",
        "minimum" : 25.0,
        "maximum" : 500.0
            }
      }
}
```

您也可以參考外部模型檔案中定義的另一個模型結構描述。將 `$ref` 屬性的值設定為模型的位置。在下列範例中，`Price` 模型是在 API `a1234` 的 `PetStorePrice` 模型中定義的。

```
{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "title" : "PetStorePrice",
  "type": "number",
  "minimum": 25,
  "maximum": 500
}
```

較長的模型可以參考 `PetStorePrice` 模型。

```
{
  "$schema" : "http://json-schema.org/draft-04/schema#",
  "title" : "PetStoreModelReusableRefAPI",
  "required" : [ "price", "type" ],
  "type" : "object",
  "properties" : {
    "id" : {
      "type" : "integer"
    },
    "type" : {
      "type" : "string",
      "enum" : [ "dog", "cat", "fish" ]
    },
    "price" : {
        "$ref": "https://apigateway.amazonaws.com/restapis/a1234/models/PetStorePrice"
    }
  }
}
```

## 使用輸出資料模型
<a name="api-gateway-request-validation-output-model"></a>

如果轉換您的資料，您可以在整合回應中定義承載模型。產生 SDK 時，可以使用承載模型。針對強型別語言 (例如 Java、Objective-C 或 Swift)，物件會對應到使用者定義的資料類型 (UDT)。如果您在產生 SDK 時透過資料模型提供 UDT，則 API Gateway 會建立該 UDT。如需資料轉型的詳細資訊，請參閱 [API Gateway 中 REST API 的映射範本轉換](models-mappings.md)。

下列範例是整合回應的輸出資料。

```
{
[
  {
    "description" : "Item 1 is a dog.",
    "askingPrice" : 249.99
  },
  {
    "description" : "Item 2 is a cat.",
    "askingPrice" : 124.99
  },
  {
    "description" : "Item 3 is a fish.",
    "askingPrice" : 0.99
  }
]
}
```

下列範例是描述輸出資料的承載模型。

```
{
"$schema": "http://json-schema.org/draft-04/schema#",
  "title": "PetStoreOutputModel",
  "type" : "object",
  "required" : [ "description", "askingPrice" ],
  "properties" : {
    "description" : {
      "type" : "string"
    },
    "askingPrice" : {
      "type" : "number",
      "minimum" : 25.0,
      "maximum" : 500.0
    }
  }
}
```

有了此模型，您可以呼叫 SDK，透過讀取 `PetStoreOutputModel[i].description` 和 `PetStoreOutputModel[i].askingPrice` 屬性，來擷取 `description` 和 `askingPrice` 屬性值。如果未提供模型，API Gateway 會使用空白模型來建立預設 UDT。

## 後續步驟
<a name="api-gateway-request-validation-model-next-steps"></a>
+ 本節提供的資源可讓您深入了解本主題中呈現的概念。

  您可以遵循請求驗證教學課程：
  + [使用 API Gateway 主控台設定請求驗證](api-gateway-request-validation-set-up.md#api-gateway-request-validation-setup-in-console)
  +  [使用 設定基本請求驗證 AWS CLI](api-gateway-request-validation-set-up.md#api-gateway-request-validation-setup-cli)
  +  [使用 OpenAPI 定義來設定基本請求驗證](api-gateway-request-validation-set-up.md#api-gateway-request-validation-setup-importing-swagger)
+  如需資料轉換和映射範本的詳細資訊，請參閱 [API Gateway 中 REST API 的映射範本轉換](models-mappings.md)。

# 在 API Gateway 中設定基本請求驗證
<a name="api-gateway-request-validation-set-up"></a>

 本節說明如何使用 主控台 AWS CLI和 OpenAPI 定義來設定 API Gateway 的請求驗證。

**Topics**
+ [使用 API Gateway 主控台設定請求驗證](#api-gateway-request-validation-setup-in-console)
+ [使用 設定基本請求驗證 AWS CLI](#api-gateway-request-validation-setup-cli)
+ [使用 OpenAPI 定義來設定基本請求驗證](#api-gateway-request-validation-setup-importing-swagger)

## 使用 API Gateway 主控台設定請求驗證
<a name="api-gateway-request-validation-setup-in-console"></a>

 您可以使用 API Gateway 主控台來驗證請求，方法是為 API 請求選取三個驗證程式之一：
+ **驗證內文**。
+ **驗證查詢字串參數和標頭**。
+ **驗證內文、查詢字串參數和標頭**。

 當您在 API 方法上套用其中一個驗證程式時，API Gateway 主控台會將驗證程式新增至 API 的 [RequestValidators](https://docs.aws.amazon.com/apigateway/latest/api/API_RequestValidator.html) 對應。

若要遵循本教學課程，您將使用 CloudFormation 範本來建立不完整的 API Gateway API。此 API 具有 `/validator` 資源，其中含有 `GET` 和 `POST` 方法。這兩種方法會與 `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP 端點整合。您將設定兩種請求驗證：
+ 在 `GET` 方法中，您將設定 URL 查詢字串參數的請求驗證。
+ 在 `POST` 方法中，您將設定請求內文的請求驗證。

 這將只允許某些 API 呼叫傳遞至 API。

下載並解壓縮 [的應用程式建立範本 CloudFormation](samples/request-validation-tutorial-console.zip)。您將使用此範本建立不完整的 API。您將完成 API Gateway 主控台中的其餘步驟。

**建立 CloudFormation 堆疊**

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

1. 選擇 **Create stack (建立堆疊)**，然後選擇 **With new resources (standard) (使用新資源 (標準))**。

1. 對於 **Specify template (指定範本)**，選擇 **Upload a template file (上傳範本檔案)**。

1. 選取您下載的範本。

1. 選擇 **Next** (下一步)。

1. 針對 **Stack name (堆疊名稱)**，輸入 **request-validation-tutorial-console**，然後選擇 **Next (下一步)**。

1. 針對 **Configure stack options (設定堆疊選項)**，選擇 **Next (下一步)**。

1. 針對 **功能**，確認 CloudFormation 可以在您的帳戶中建立 IAM 資源。

1. 選擇**下一步**，然後選擇**提交**。

CloudFormation 會佈建範本中指定的資源。完成資源佈建可能需要幾分鐘的時間。當您的 CloudFormation 堆疊狀態為 **CREATE\$1COMPLETE** 時，您就可以繼續進行下一個步驟。

**選取新建立的 API**

1. 選取新建立的 **request-validation-tutorial-console** 堆疊。

1. 選擇**資源**。

1. 在**實體 ID** 下，選擇您的 API。此連結會將您導向至 API Gateway 主控台。

在修改 `GET` 和 `POST` 方法之前，您必須建立模型。

**建立裝置**

1. 需有模型才能在傳入請求的內文上使用請求驗證。若要建立模型，請在主導覽窗格中選擇**模型**。

1. 選擇**建立模型**。

1. 對於**名稱**，輸入 **PetStoreModel**。

1. 針對**內容類型**，輸入 **application/json**。如果找不到相符的內容類型，則不會執行請求驗證。若要使用相同的模型，而不論內容類型為何，請輸入 **\$1default**。

1. 對於**描述**，輸入 **My PetStore Model** 作為模型描述。

1. 對於**模型結構描述**，將下列模型貼入程式碼編輯器中，然後選擇**建立**。

   ```
   {
     "type" : "object",
     "required" : [ "name", "price", "type" ],
     "properties" : {
       "id" : {
         "type" : "integer"
       },
       "type" : {
         "type" : "string",
         "enum" : [ "dog", "cat", "fish" ]
       },
       "name" : {
         "type" : "string"
       },
       "price" : {
         "type" : "number",
         "minimum" : 25.0,
         "maximum" : 500.0
       }
     }
   }
   ```

如需關於模型的詳細資訊，請參閱[REST API 的資料模型](models-mappings-models.md)。

**設定 `GET` 方法的請求驗證**

1. 在主導覽窗格中，選擇**資源**，然後選取 **GET** 方法。

1. 在**方法請求**索引標籤的**方法請求設定**下，選擇**編輯**。

1. 對於**請求驗證程式**，選取**驗證查詢字串參數與標頭**。

1. 在 **URL 查詢字串參數**下，執行下列動作：

   1. 選擇**新增查詢字串**。

   1. 對於**名稱**，輸入 **petType**。

   1. 開啟**必要**。

   1. 讓**快取**保持關閉。

1. 選擇**儲存**。

1. 在**整合請求**索引標籤上，於**整合請求設定**下，選擇**編輯**。

1. 在 **URL 查詢字串參數**下，執行下列動作：

   1. 選擇**新增查詢字串**。

   1. 對於**名稱**，輸入 **petType**。

   1. 對於**映射自**，輸入 **method.request.querystring.petType**。這會將 **petType** 對應到寵物的類型。

      如需資料對應的詳細資訊，請參閱[資料對應教學課程](set-up-data-transformations-in-api-gateway.md#mapping-example-console)。

   1. 讓**快取**保持關閉。

1. 選擇**儲存**。

**測試 `GET` 方法的請求驗證**

1. 選擇**測試**標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

1. 對於**查詢字串**，輸入 **petType=dog**，然後選擇**測試**。

1. 方法測試會傳回 `200 OK` 及狗的清單。

   如需如何轉換此輸出資料的相關資訊，請參閱[資料對應教學課程](set-up-data-transformations-in-api-gateway.md#mapping-example-console)。

1. 移除 **petType=dog** 並選擇**測試**。

1.  方法測試會傳回 `400` 錯誤，並顯示下列錯誤訊息：

   ```
   {
     "message": "Missing required request parameters: [petType]"
   }
   ```

**設定 `POST` 方法的請求驗證**

1. 在主導覽窗格中，選擇**資源**，然後選取 **POST** 方法。

1. 在**方法請求**索引標籤的**方法請求設定**下，選擇**編輯**。

1. 對於**請求驗證程式**，選取**驗證內文**。

1. 在**請求內文**下，選擇**新增模型**。

1. 針對**內容類型**，輸入 **application/json**。如果找不到相符的內容類型，則不會執行請求驗證。若要使用相同的模型，而不論內容類型為何，請輸入 `$default`。

    對於**模型**，選取 **PetStoreModel**。

1. 選擇**儲存**。

**測試 `POST` 方法的請求驗證**

1. 選擇**測試**標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

1. 對於**請求內文**，將下列內容貼入程式碼編輯器中：

   ```
   {
     "id": 2,
     "name": "Bella",
     "type": "dog",
     "price": 400
   }
   ```

    選擇**測試**。

1. 方法測試會傳回 `200 OK` 和成功訊息。

1. 對於**請求內文**，將下列內容貼入程式碼編輯器中：

   ```
   {
     "id": 2,
     "name": "Bella",
     "type": "dog",
     "price": 4000
   }
   ```

    選擇**測試**。

1.  方法測試會傳回 `400` 錯誤，並顯示下列錯誤訊息：

   ```
   {
    "message": "Invalid request body"
   }
   ```

    測試日誌底部會傳回請求內文無效的原因。在此案例中，寵物的價格超出了模型中指定的最高價格。

**刪除 CloudFormation 堆疊**

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

1. 選取您的 CloudFormation 堆疊。

1. 選擇**刪除**，然後確認您的選擇。

### 後續步驟
<a name="next-steps-request-validation-tutorial"></a>
+ 如需如何轉換輸出資料並執行其他資料對應的相關資訊，請參閱[資料對應教學課程](set-up-data-transformations-in-api-gateway.md#mapping-example-console)。
+ 遵循[使用 AWS CLI設定基本請求驗證](#api-gateway-request-validation-setup-cli)教學課程，以使用 AWS CLI執行類似的步驟。

## 使用 設定基本請求驗證 AWS CLI
<a name="api-gateway-request-validation-setup-cli"></a>

您可以使用 AWS CLI建立驗證程式來設定請求驗證。若要遵循本教學課程，您將使用 CloudFormation 範本來建立不完整的 API Gateway API。

**注意**  
這與主控台教學課程的 CloudFormation 範本不同。

 使用預先公開的 `/validator` 資源，您將建立 `GET` 和 `POST` 方法。這兩種方法會與 `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP 端點整合。您將設定下列兩個請求驗證：
+ 在 `GET` 方法上，您將建立 `params-only` 驗證程式來驗證 URL 查詢字串參數。
+ 在 `POST` 方法上，您將建立 `body-only` 驗證程式來驗證請求內文。

 這將只允許某些 API 呼叫傳遞至 API。

**建立 CloudFormation 堆疊**

下載並解壓縮 [的應用程式建立範本 CloudFormation](samples/request-validation-tutorial-cli.zip)。

若要完成下列教學課程，您需要 [AWS Command Line Interface (AWS CLI) 第 2 版](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

對於長命令，逸出字元 (`\`) 用於將命令分割為多行。
**注意**  
在 Windows 中，作業系統的內建終端機不支援您常用的某些 Bash CLI 命令 (例如 `zip`)。若要取得 Ubuntu 和 Bash 的 Windows 整合版本，請[安裝適用於 Linux 的 Windows 子系統](https://learn.microsoft.com/en-us/windows/wsl/install)。本指南中的 CLI 命令範例使用 Linux 格式。如果您使用的是 Windows CLI，必須重新格式化包含內嵌 JSON 文件的命令。

1.  使用下列命令來建立 CloudFormation 堆疊。

   ```
   aws cloudformation create-stack --stack-name request-validation-tutorial-cli --template-body file://request-validation-tutorial-cli.zip --capabilities CAPABILITY_NAMED_IAM 
   ```

1. CloudFormation 會佈建範本中指定的資源。完成資源佈建可能需要幾分鐘的時間。使用下列命令來查看 CloudFormation 堆疊的狀態。

   ```
   aws cloudformation describe-stacks --stack-name request-validation-tutorial-cli
   ```

1. 當您的 CloudFormation 堆疊狀態為 時`StackStatus: "CREATE_COMPLETE"`，請使用下列命令來擷取未來步驟的相關輸出值。

   ```
    aws cloudformation describe-stacks --stack-name request-validation-tutorial-cli --query "Stacks[*].Outputs[*].{OutputKey: OutputKey, OutputValue: OutputValue, Description: Description}"
   ```

   輸出值如下：
   + ApiId，這是 API 的 ID。對於本教學課程，API ID 為 `abc123`。
   + ResourceId，這是 `GET` 和 `POST` 方法公開所在驗證程式資源的 ID。對於本教學課程，資源 ID 為 `efg456`

**建立請求驗證程式並匯入模型**

1. 需有驗證程式才能搭配 AWS CLI使用請求驗證。使用下列命令建立僅驗證請求參數的驗證程式。

   ```
   aws apigateway create-request-validator --rest-api-id abc123 \
         --no-validate-request-body \
         --validate-request-parameters \
         --name params-only
   ```

   請記下 `params-only` 驗證程式的 ID。

1.  使用下列命令建立僅驗證請求內文的驗證程式。

   ```
   aws apigateway create-request-validator --rest-api-id abc123 \
         --validate-request-body \
         --no-validate-request-parameters \
         --name body-only
   ```

   請記下 `body-only` 驗證程式的 ID。

1.  需有模型才能在傳入請求的內文上使用請求驗證。使用下列命令匯入模型。

   ```
   aws apigateway create-model --rest-api-id abc123 --name PetStoreModel --description 'My PetStore Model' --content-type 'application/json' --schema '{"type": "object", "required" : [ "name", "price", "type" ], "properties" : { "id" : {"type" : "integer"},"type" : {"type" : "string", "enum" : [ "dog", "cat", "fish" ]},"name" : { "type" : "string"},"price" : {"type" : "number","minimum" : 25.0, "maximum" : 500.0}}}}' 
   ```

   如果找不到相符的內容類型，則不會執行請求驗證。若要使用相同的模型，而不論內容類型為何，請指定 `$default` 為索引鍵。

**建立 `GET` 和 `POST` 方法**

1. 使用下列命令，在 `/validate` 資源上新增 `GET` HTTP 方法。此命令會建立 `GET` 方法、新增 `params-only` 驗證程式，並視需要設定查詢字串 `petType`。

   ```
   aws apigateway put-method --rest-api-id abc123 \
          --resource-id efg456 \
          --http-method GET \
          --authorization-type "NONE" \
          --request-validator-id aaa111 \
          --request-parameters "method.request.querystring.petType=true"
   ```

   使用下列命令，在 `/validate` 資源上新增 `POST` HTTP 方法。此命令會建立 `POST` 方法、新增 `body-only` 驗證程式，並將模型附加至僅內文驗證程式。

   ```
   aws apigateway put-method --rest-api-id abc123 \
          --resource-id efg456 \
          --http-method POST \
          --authorization-type "NONE" \
          --request-validator-id bbb222 \
          --request-models 'application/json'=PetStoreModel
   ```

1.  使用下列命令設定 `GET /validate` 方法的 `200 OK` 回應。

   ```
   aws apigateway put-method-response --rest-api-id abc123  \
               --resource-id efg456 \
               --http-method GET \
               --status-code 200
   ```

    使用下列命令設定 `POST /validate` 方法的 `200 OK` 回應。

   ```
   aws apigateway put-method-response --rest-api-id abc123  \
               --resource-id efg456 \
               --http-method POST \
               --status-code 200
   ```

1.  使用下列命令，為 `GET /validation` 方法設定具有所指定 HTTP 端點的 `Integration`。

   ```
   aws apigateway put-integration --rest-api-id abc123  \
               --resource-id efg456 \
               --http-method GET \
               --type HTTP \
               --integration-http-method GET \
               --request-parameters '{"integration.request.querystring.type" : "method.request.querystring.petType"}' \
               --uri 'http://petstore-demo-endpoint.execute-api.com/petstore/pets'
   ```

    使用下列命令，為 `POST /validation` 方法設定具有所指定 HTTP 端點的 `Integration`。

   ```
   aws apigateway put-integration --rest-api-id abc123  \
                 --resource-id efg456 \
                 --http-method POST \
                 --type HTTP \
                 --integration-http-method GET \
                 --uri 'http://petstore-demo-endpoint.execute-api.com/petstore/pets'
   ```

1.  使用下列命令設定 `GET /validation` 方法的整合回應。

   ```
   aws apigateway put-integration-response --rest-api-id abc123 \
                 --resource-id efg456\
                 --http-method GET \
                 --status-code 200 \
                 --selection-pattern ""
   ```

    使用下列命令設定 `POST /validation` 方法的整合回應。

   ```
   aws apigateway put-integration-response --rest-api-id abc123 \
               --resource-id efg456 \
               --http-method POST \
               --status-code 200 \
               --selection-pattern ""
   ```

**若要測試 API**

1. 若要測試將為查詢字串執行請求驗證的 `GET` 方法，請使用下列命令：

   ```
   aws apigateway test-invoke-method --rest-api-id abc123 \
               --resource-id efg456 \
               --http-method GET \
               --path-with-query-string '/validate?petType=dog'
   ```

   結果將傳回 `200 OK` 和狗清單。

1. 在不包括查詢字串 `petType` 的情況下，使用下列命令進行測試，

   ```
   aws apigateway test-invoke-method --rest-api-id abc123 \
               --resource-id efg456 \
               --http-method GET
   ```

   結果將傳回 `400` 錯誤。

1. 若要測試將為請求內文執行請求驗證的 `POST` 方法，請使用下列命令：

   ```
    aws apigateway test-invoke-method --rest-api-id abc123 \
               --resource-id efg456 \
               --http-method POST \
               --body '{"id": 1, "name": "bella", "type": "dog", "price" : 400 }'
   ```

   結果將傳回 `200 OK` 和成功訊息。

1. 使用下列命令，以利用無效內文進行測試。

   ```
    aws apigateway test-invoke-method --rest-api-id abc123 \
                 --resource-id efg456 \
                 --http-method POST \
                 --body '{"id": 1, "name": "bella", "type": "dog", "price" : 1000 }'
   ```

   結果將傳回 `400` 錯誤，因為狗的價格超過了模型定義的最高價格。

**刪除 CloudFormation 堆疊**
+ 使用下列命令來刪除您的 CloudFormation 資源。

  ```
  aws cloudformation delete-stack  --stack-name request-validation-tutorial-cli
  ```

## 使用 OpenAPI 定義來設定基本請求驗證
<a name="api-gateway-request-validation-setup-importing-swagger"></a>

 您可以在 API 層級宣告請求驗證程式，方法是在 [x-amazon-apigateway-request-validators 物件](api-gateway-swagger-extensions-request-validators.md) 對應中指定一組 [x-amazon-apigateway-request-validators.requestValidator 物件](api-gateway-swagger-extensions-request-validators.requestValidator.md) 物件，以選取要驗證請求的哪一部分。在範例 OpenAPI 定義中，有兩個驗證程式：
+ `all` 驗證程式，其會同時驗證內文 (使用 `RequestBodyModel` 資料模型) 和參數。

  此 `RequestBodyModel` 資料模型要求輸入 JSON 物件包含 `name`、`type` 和 `price` 屬性。`name` 屬性可以是任意字串、`type` 必須是其中一個指定的列舉欄位 (`["dog", "cat", "fish"]`)，而 `price` 的範圍必須是 25 到 500。`id` 不是必要參數。
+ `param-only`，其僅會驗證參數。

 若要在 API 的所有方法上開啟請求驗證程式，請在 OpenAPI 定義的 API 層級指定 [x-amazon-apigateway-request-validator 屬性](api-gateway-swagger-extensions-request-validator.md) 屬性。在範例 OpenAPI 定義中，除非特別覆寫，否則會在所有 API 方法上使用 `all` 驗證程式。使用模型驗證主體時，如果找不到相符的內容類型，則不會執行請求驗證。若要使用相同的模型，而不論內容類型為何，請指定 `$default` 為索引鍵。

若要在個別方法上開啟請求驗證程式，請在方法層級指定 `x-amazon-apigateway-request-validator` 屬性。在範例 (OpenAPI 定義) 中，`param-only` 驗證程式會覆寫 `GET` 方法上的 `all` 驗證程式。



若要將 OpenAPI 範例匯入至 API Gateway，請參閱下列指示，[將區域 API 匯入至 API Gateway](import-export-api-endpoints.md) 或 [將邊緣最佳化 API 匯入至 API Gateway](import-edge-optimized-api.md)。

------
#### [ OpenAPI 3.0 ]

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "ReqValidators Sample",
    "version" : "1.0.0"
  },
  "servers" : [ {
    "url" : "/{basePath}",
    "variables" : {
      "basePath" : {
        "default" : "/v1"
      }
    }
  } ],
  "paths" : {
    "/validation" : {
      "get" : {
        "parameters" : [ {
          "name" : "q1",
          "in" : "query",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response",
            "headers" : {
              "test-method-response-header" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/ArrayOfError"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator" : "params-only",
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "400",
              "responseParameters" : {
                "method.response.header.test-method-response-header" : "'static value'"
              },
              "responseTemplates" : {
                "application/xml" : "xml 400 response template",
                "application/json" : "json 400 response template"
              }
            },
            "2\\d{2}" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.querystring.type" : "method.request.querystring.q1"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      },
      "post" : {
        "parameters" : [ {
          "name" : "h1",
          "in" : "header",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/RequestBodyModel"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "200 response",
            "headers" : {
              "test-method-response-header" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/ArrayOfError"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator" : "all",
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "POST",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "400",
              "responseParameters" : {
                "method.response.header.test-method-response-header" : "'static value'"
              },
              "responseTemplates" : {
                "application/xml" : "xml 400 response template",
                "application/json" : "json 400 response template"
              }
            },
            "2\\d{2}" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.header.custom_h1" : "method.request.header.h1"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  },
  "components" : {
    "schemas" : {
      "RequestBodyModel" : {
        "required" : [ "name", "price", "type" ],
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "integer"
          },
          "type" : {
            "type" : "string",
            "enum" : [ "dog", "cat", "fish" ]
          },
          "name" : {
            "type" : "string"
          },
          "price" : {
            "maximum" : 500.0,
            "minimum" : 25.0,
            "type" : "number"
          }
        }
      },
      "ArrayOfError" : {
        "type" : "array",
        "items" : {
          "$ref" : "#/components/schemas/Error"
        }
      },
      "Error" : {
        "type" : "object"
      }
    }
  },
  "x-amazon-apigateway-request-validators" : {
    "all" : {
      "validateRequestParameters" : true,
      "validateRequestBody" : true
    },
    "params-only" : {
      "validateRequestParameters" : true,
      "validateRequestBody" : false
    }
  }
}
```

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

```
{
  "swagger" : "2.0",
  "info" : {
    "version" : "1.0.0",
    "title" : "ReqValidators Sample"
  },
  "basePath" : "/v1",
  "schemes" : [ "https" ],
  "paths" : {
    "/validation" : {
      "get" : {
        "produces" : [ "application/json", "application/xml" ],
        "parameters" : [ {
          "name" : "q1",
          "in" : "query",
          "required" : true,
          "type" : "string"
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response",
            "schema" : {
              "$ref" : "#/definitions/ArrayOfError"
            },
            "headers" : {
              "test-method-response-header" : {
                "type" : "string"
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator" : "params-only",
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "400",
              "responseParameters" : {
                "method.response.header.test-method-response-header" : "'static value'"
              },
              "responseTemplates" : {
                "application/xml" : "xml 400 response template",
                "application/json" : "json 400 response template"
              }
            },
            "2\\d{2}" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.querystring.type" : "method.request.querystring.q1"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      },
      "post" : {
        "consumes" : [ "application/json" ],
        "produces" : [ "application/json", "application/xml" ],
        "parameters" : [ {
          "name" : "h1",
          "in" : "header",
          "required" : true,
          "type" : "string"
        }, {
          "in" : "body",
          "name" : "RequestBodyModel",
          "required" : true,
          "schema" : {
            "$ref" : "#/definitions/RequestBodyModel"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response",
            "schema" : {
              "$ref" : "#/definitions/ArrayOfError"
            },
            "headers" : {
              "test-method-response-header" : {
                "type" : "string"
              }
            }
          }
        },
        "x-amazon-apigateway-request-validator" : "all",
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "POST",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "400",
              "responseParameters" : {
                "method.response.header.test-method-response-header" : "'static value'"
              },
              "responseTemplates" : {
                "application/xml" : "xml 400 response template",
                "application/json" : "json 400 response template"
              }
            },
            "2\\d{2}" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.header.custom_h1" : "method.request.header.h1"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  },
  "definitions" : {
    "RequestBodyModel" : {
      "type" : "object",
      "required" : [ "name", "price", "type" ],
      "properties" : {
        "id" : {
          "type" : "integer"
        },
        "type" : {
          "type" : "string",
          "enum" : [ "dog", "cat", "fish" ]
        },
        "name" : {
          "type" : "string"
        },
        "price" : {
          "type" : "number",
          "minimum" : 25.0,
          "maximum" : 500.0
        }
      }
    },
    "ArrayOfError" : {
      "type" : "array",
      "items" : {
        "$ref" : "#/definitions/Error"
      }
    },
    "Error" : {
      "type" : "object"
    }
  },
  "x-amazon-apigateway-request-validators" : {
    "all" : {
      "validateRequestParameters" : true,
      "validateRequestBody" : true
    },
    "params-only" : {
      "validateRequestParameters" : true,
      "validateRequestBody" : false
    }
  }
}
```

------

# AWS CloudFormation 具有基本請求驗證的範例 API 範本
<a name="api-gateway-request-validation-sample-cloudformation"></a>

 下列 CloudFormation 範例範本定義會定義已啟用請求驗證的範例 API。API 是 [PetStore API](http://petstore-demo-endpoint.execute-api.com/petstore/pets) 的子集。它會公開 `POST` 方法以將寵物新增至 `pets` 集合，並公開 `GET` 方法以依指定的類型來查詢寵物。

 這裡會宣告兩種請求驗證程式：

**`GETValidator`**  
此驗證程式會在 `GET` 方法上啟用。它可讓 API Gateway 驗證傳入請求中已包含不是空白的必要查詢參數 (`q1`)。

**`POSTValidator`**  
此驗證程式會在 `POST` 方法上啟用。它可讓 API Gateway 驗證，當內容類型為 `application/json` 時，承載請求格式是否遵循指定的 `RequestBodyModel`，如果找不到相符的內容類型，則不會執行請求驗證。若無論內容類型為何都要使用相同的模型，可指定 `$default`。`RequestBodyModel` 包含一個額外的模型 `RequestBodyModelId`，用於定義寵物 ID。

```
AWSTemplateFormatVersion: 2010-09-09
Parameters:
  StageName:
    Type: String
    Default: v1
    Description: Name of API stage.
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: ReqValidatorsSample
  RequestBodyModelId:
    Type: 'AWS::ApiGateway::Model'
    Properties:
      RestApiId: !Ref Api
      ContentType: application/json
      Description: Request body model for Pet ID.
      Schema:
        $schema: 'http://json-schema.org/draft-04/schema#'
        title: RequestBodyModelId
        properties:
            id:
              type: integer
  RequestBodyModel: 
    Type: 'AWS::ApiGateway::Model'
    Properties:
      RestApiId: !Ref Api
      ContentType: application/json
      Description: Request body model for Pet type, name, price, and ID.
      Schema:
        $schema: 'http://json-schema.org/draft-04/schema#'
        title: RequestBodyModel
        required:
          - price
          - name
          - type
        type: object
        properties:
            id:
              "$ref": !Sub 
                - 'https://apigateway.amazonaws.com/restapis/${Api}/models/${RequestBodyModelId}'
                - Api: !Ref Api
                  RequestBodyModelId: !Ref RequestBodyModelId
            price: 
              type: number
              minimum: 25
              maximum: 500
            name:
              type: string
            type:
              type: string
              enum:
                - "dog"
                - "cat"
                - "fish"
  GETValidator:
    Type: AWS::ApiGateway::RequestValidator
    Properties:
      Name: params-only
      RestApiId: !Ref Api
      ValidateRequestBody: False
      ValidateRequestParameters: True 
  POSTValidator:
    Type: AWS::ApiGateway::RequestValidator
    Properties:
      Name: body-only
      RestApiId: !Ref Api
      ValidateRequestBody: True
      ValidateRequestParameters: False
  ValidationResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref Api
      ParentId: !GetAtt Api.RootResourceId
      PathPart: 'validation'
  ValidationMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref ValidationResource
      HttpMethod: GET
      AuthorizationType: NONE
      RequestValidatorId: !Ref GETValidator
      RequestParameters:
        method.request.querystring.q1: true
      Integration:
        Type: HTTP_PROXY
        IntegrationHttpMethod: GET
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets/
  ValidationMethodPost:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref ValidationResource
      HttpMethod: POST
      AuthorizationType: NONE
      RequestValidatorId: !Ref POSTValidator
      RequestModels:
        application/json : !Ref RequestBodyModel 
      Integration:
        Type: HTTP_PROXY
        IntegrationHttpMethod: POST
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets/
  ApiDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn:
      - ValidationMethodGet
      - RequestBodyModel 
    Properties:
      RestApiId: !Ref Api
      StageName: !Sub '${StageName}'
Outputs:
  ApiRootUrl:
    Description: Root Url of the API
    Value: !Sub 'https://${Api}.execute-api.${AWS::Region}.amazonaws.com/${StageName}'
```

# API Gateway 中用於 REST API 的資料轉換
<a name="rest-api-data-transformations"></a>

**注意**  
本節說明可搭配非代理整合使用的功能。不過，我們建議您盡可能針對 REST API 使用代理整合。代理整合採用簡化的整合設定，並且可隨著後端演進，而不必縮減現有的設定。如需詳細資訊，請參閱[選擇 API Gateway API 整合類型](api-gateway-api-integration-types.md)。

如果您使用非代理整合，您可以使用 API Gateway 的兩項功能來轉換方法請求和整合回應。如果方法請求採用與整合請求承載不同的承載格式，則您可以轉換方法請求。如果整合回應傳回的承載格式與方法回應中需要傳回的格式不同，則您可以轉換整合回應。如需有關請求生命週期的詳細資訊，請參閱 [REST API 的範例資源](rest-api-develop.md#rest-api-develop-example)。

下列範例說明資料轉換，其中標頭 `"x-version:beta"` 的 `x-version` 標頭參數會轉換成 `app-version` 標頭參數。整合請求中會進行 `x-version` 到 `app-version` 的資料轉換。如此一來，整合端點就會收到轉換後的標頭參數值。當整合端點傳回狀態碼時，狀態碼會在方法回應之前，從 `200` 轉換為 `204`。

![\[API Gateway 資料轉換圖\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/develop-non-proxy.png)


若要建立資料轉換，您可以使用下列功能：

**參數映射**  
在參數映射中，您可以修改整合請求 URL 路徑參數、URL 查詢字串參數或 HTTP 標頭值，但無法修改整合請求承載。您也可以修改 HTTP 回應標頭值。使用參數映射建立跨來源資源分享 (CORS) 的靜態標頭值。  
您可以在代理和非代理整合的整合請求中使用參數映射，但若要將參數映射用於整合回應，則需要非代理整合。參數映射不需要使用 [ Velocity 範本語言 (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) 編寫任何指令碼。如需詳細資訊，請參閱[API Gateway 中 REST API 的參數映射](rest-api-parameter-mapping.md)。

**映射範本轉換**  
在映射範本轉換中，您可以使用映射範本來對應 URL 路徑參數、URL 查詢字串參數、HTTP 標頭，以及整合請求或整合回應內文。*映射範本*是以 [Velocity 範本語言 (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) 表達的指令碼，會使用 [JSONPath 表達式](https://goessner.net/articles/JsonPath/)並根據 `Content-type` 標頭套用至承載。  
您可以使用映射範本執行下列操作：  
+ 選取要使用整合傳送的資料 AWS 服務，例如 Amazon DynamoDB 或 Lambda 函數或 HTTP 端點。如需詳細資訊，請參閱[教學課程：修改 AWS 服務整合的整合請求和回應](set-up-data-transformations-in-api-gateway.md)。
+ 有條件地覆寫 API 的整合請求和整合回應參數、建立新的標頭值，以及覆寫狀態碼。如需詳細資訊，請參閱[覆寫 API Gateway 中 REST API 的 API 請求和回應參數及狀態碼](apigateway-override-request-response-parameters.md)。
若整合請求內文的 `Content-type` 標頭沒有相符的映射範本，您也可以指定 API 的行為。這稱為整合傳遞行為。如需詳細資訊，請參閱[API Gateway 中 REST API 沒有映射範本時，承載的方法請求行為](integration-passthrough-behaviors.md)。

## 選擇參數映射或映射範本轉換
<a name="rest-api-data-transformations-choose"></a>

我們建議您盡可能使用參數映射來轉換資料。如果您的 API 要求您變更內文，或要求您根據傳入的整合請求或整合回應執行條件式覆寫和修改，而且您無法使用代理整合，則使用映射範本轉換。

# API Gateway 中 REST API 的參數映射
<a name="rest-api-parameter-mapping"></a>

**注意**  
如果您使用的是 HTTP API，請參閱 [在 API Gateway 中轉換 HTTP API 的 API 請求和回應](http-api-parameter-mapping.md)。

在參數映射中，您可以對應請求或回應參數。您可以使用參數映射表達式或靜態值來對應參數。如需映射表達式的清單，請參閱 [API Gateway 中 REST API 的參數映射來源參考](rest-api-parameter-mapping-sources.md)。您可以在代理和非代理整合的整合請求中使用參數映射，但若要將參數映射用於整合回應，則需要非代理整合。

例如，您可以將方法請求標頭參數 `puppies` 對應到整合請求標頭參數 `DogsAge0`。之後如果用戶端將標頭 `puppies:true` 傳送至您的 API，則整合請求會將請求標頭 `DogsAge0:true` 傳送至整合端點。下圖顯示此範例的請求生命週期。

![\[請求的 API Gateway 參數映射範例圖\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/parameter-mapping-example1.png)


若要使用 API Gateway 建立此範例，請參閱 [範例 1：將方法請求參數對應至整合請求參數](request-response-data-mappings.md#request-response-data-mappings-example-1)。

 另一個範例是，您也可以將整合回應標頭參數 `kittens` 對應至方法回應標頭參數 `CatsAge0`。之後如果整合端點傳回 `kittens:false`，則用戶端會收到標頭 `CatsAge0:false`。下圖顯示此範例的請求生命週期。

![\[回應的 API Gateway 參數映射範例圖\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/parameter-mapping-example2.png)


**Topics**
+ [API Gateway 中 REST API 的參數映射範例](request-response-data-mappings.md)
+ [API Gateway 中 REST API 的參數映射來源參考](rest-api-parameter-mapping-sources.md)

# API Gateway 中 REST API 的參數映射範例
<a name="request-response-data-mappings"></a>

下列範例示範如何使用 API Gateway 主控台、OpenAPI 和 CloudFormation 範本建立參數映射表達式。如需如何使用參數映射來建立所需 CORS 標頭的範例，請參閱 [API Gateway 中 REST API 的 CORS](how-to-cors.md)。

## 範例 1：將方法請求參數對應至整合請求參數
<a name="request-response-data-mappings-example-1"></a>

下列範例會將方法請求標頭參數 `puppies` 對應至整合請求標頭參數 `DogsAge0`。

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

**對應方法請求參數**

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

1. 選擇 REST API。

1. 選擇一個方法。

   您的方法必須有非代理整合。

1. 針對**方法請求設定**，選擇**編輯**。

1. 選擇 **HTTP 請求標頭**。

1. 選擇**新增標頭**。

1. 對於**名稱**，輸入 **puppies**。

1. 選擇**儲存**。

1. 選擇**整合請求**索引標籤，然後針對**整合請求設定**，選擇**編輯**。

    AWS 管理主控台 會自動`puppies`為您從 新增參數映射`method.request.header.puppies `至 ，但您需要變更**名稱**以符合整合端點預期的請求標頭參數。

1. 對於**名稱**，輸入 **DogsAge0**。

1. 選擇**儲存**。

1. 重新部署 API 以使變更生效。

下列步驟說明如何驗證參數映射是否成功。

**(選用) 測試參數映射**

1. 選擇**測試**標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

1. 針對標頭，輸入 **puppies:true**。

1. 選擇**測試**。

1. 在**日誌**中，結果應如下所示：

   ```
   Tue Feb 04 00:28:36 UTC 2025 : Method request headers: {puppies=true}
   Tue Feb 04 00:28:36 UTC 2025 : Method request body before transformations: 
   Tue Feb 04 00:28:36 UTC 2025 : Endpoint request URI: http://petstore-demo-endpoint.execute-api.com/petstore/pets
   Tue Feb 04 00:28:36 UTC 2025 : Endpoint request headers: {DogsAge0=true, x-amzn-apigateway-api-id=abcd1234, Accept=application/json, User-Agent=AmazonAPIGateway_aaaaaaa, X-Amzn-Trace-Id=Root=1-abcd-12344}
   ```

   請求標頭參數已從 `puppies` 變更為 `DogsAge0`。

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

 在此範例中，您使用 [body](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) 屬性將 OpenAPI 定義檔案匯入 API Gateway 中。

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Body:
        openapi: 3.0.1
        info:
          title: ParameterMappingExample
          version: "2025-02-04T00:30:41Z"
        paths:
          /pets:
            get:
              parameters:
                - name: puppies
                  in: header
                  schema:
                    type: string
              responses:
                "200":
                  description: 200 response
              x-amazon-apigateway-integration:
                httpMethod: GET
                uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets
                responses:
                  default:
                    statusCode: "200"
                requestParameters:
                  integration.request.header.DogsAge0: method.request.header.puppies
                passthroughBehavior: when_no_match
                type: http
  ApiGatewayDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  ApiGatewayDeployment20250219:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  Stage:
    Type: 'AWS::ApiGateway::Stage'
    Properties:
       DeploymentId: !Ref ApiGatewayDeployment20250219
       RestApiId: !Ref Api
       StageName: prod
```

------
#### [ OpenAPI ]

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "ParameterMappingExample",
    "version" : "2025-02-04T00:30:41Z"
  },
  "paths" : {
    "/pets" : {
      "get" : {
        "parameters" : [ {
          "name" : "puppies",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response"
          }
        },
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.header.DogsAge0" : "method.request.header.puppies"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  }
}
```

------

## 範例 2：將多個方法請求參數對應至不同的整合請求參數
<a name="request-response-data-mappings-example-2"></a>

下列範例會將多值方法請求查詢字串參數 `methodRequestQueryParam` 對應至整合請求查詢字串參數 `integrationQueryParam`，並將方法請求標頭參數 `methodRequestHeaderParam` 對應至整合請求路徑參數 `integrationPathParam`。

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

**對應方法請求參數**

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

1. 選擇 REST API。

1. 選擇一個方法。

   您的方法必須有非代理整合。

1. 針對**方法請求設定**，選擇**編輯**。

1. 選擇 **URL 查詢字串參數**。

1. 選擇**新增查詢字串**。

1. 對於**名稱**，輸入 **methodRequestQueryParam**。

1. 選擇 **HTTP 請求標頭**。

1. 選擇**新增標頭**。

1. 對於**名稱**，輸入 **methodRequestHeaderParam**。

1. 選擇**儲存**。

1. 選擇**整合請求**索引標籤，然後針對**整合請求設定**，選擇**編輯**。

1. 選擇 **URL 路徑參數**。

1. 選擇**新增路徑參數**。

1. 對於**名稱**，輸入 **integrationPathParam**。

1. 對於**映射自**，輸入 **method.request.header.methodRequestHeaderParam**。

   這樣做會將您在方法請求中指定的方法請求標頭，對應至新的整合請求路徑參數。

1. 選擇 **URL 查詢字串參數**。

1. 選擇**新增查詢字串**。

1. 對於**名稱**，輸入 **integrationQueryParam**。

1. 對於**映射自**，輸入 **method.request.multivaluequerystring.methodRequestQueryParam**。

   這樣做會將多值查詢字串參數對應至新的單一值整合請求查詢字串參數。

1. 選擇**儲存**。

1. 重新部署 API 以使變更生效。

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

 在此範例中，您使用 [body](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) 屬性將 OpenAPI 定義檔案匯入 API Gateway 中。

以下 OpenAPI 定義會針對 HTTP 整合建立下列參數映射：
+ 將名為 `methodRequestHeaderParam` 的方法請求標頭對應到名為 `integrationPathParam` 的整合請求路徑參數
+ 將名為 `methodRequestQueryParam` 的多值方法請求查詢字串對應到名為 `integrationQueryParam` 的整合請求查詢字串

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Body: 
        openapi: 3.0.1
        info:
          title: Parameter mapping example 2
          version: "2025-01-15T19:12:31Z"
        paths:
          /:
            post:
              parameters:
                - name: methodRequestQueryParam
                  in: query
                  schema:
                    type: string
                - name: methodRequestHeaderParam
                  in: header
                  schema:
                    type: string
              responses:
                "200":
                  description: 200 response
              x-amazon-apigateway-integration:
                httpMethod: GET
                uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets
                responses:
                  default:
                    statusCode: "200"
                requestParameters:
                  integration.request.querystring.integrationQueryParam: method.request.multivaluequerystring.methodRequestQueryParam
                  integration.request.path.integrationPathParam: method.request.header.methodRequestHeaderParam
                requestTemplates:
                  application/json: '{"statusCode": 200}'
                passthroughBehavior: when_no_templates
                timeoutInMillis: 29000
                type: http
  ApiGatewayDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  ApiGatewayDeployment20250219:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  Stage:
    Type: 'AWS::ApiGateway::Stage'
    Properties:
       DeploymentId: !Ref ApiGatewayDeployment20250219
       RestApiId: !Ref Api
       StageName: prod
```

------
#### [ OpenAPI ]

以下 OpenAPI 定義會針對 HTTP 整合建立下列參數映射：
+ 將名為 `methodRequestHeaderParam` 的方法請求標頭對應到名為 `integrationPathParam` 的整合請求路徑參數
+ 將名為 `methodRequestQueryParam` 的多值方法請求查詢字串對應到名為 `integrationQueryParam` 的整合請求查詢字串

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "Parameter mapping example 2",
    "version" : "2025-01-15T19:12:31Z"
  },
  "paths" : {
    "/" : {
      "post" : {
        "parameters" : [ {
          "name" : "methodRequestQueryParam",
          "in" : "query",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "methodRequestHeaderParam",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response"
          }
        },
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.querystring.integrationQueryParam" : "method.request.multivaluequerystring.methodRequestQueryParam",
            "integration.request.path.integrationPathParam" : "method.request.header.methodRequestHeaderParam"
          },
          "requestTemplates" : {
            "application/json" : "{\"statusCode\": 200}"
          },
          "passthroughBehavior" : "when_no_templates",
          "timeoutInMillis" : 29000,
          "type" : "http"
        }
      }
    }
  }
}
```

------

## 範例 3：將欄位從 JSON 請求內文對應至整合請求參數
<a name="request-response-data-mappings-example-3"></a>

您也可以使用 [JSONPath 表達式](http://goessner.net/articles/JsonPath/index.html#e2)，從 JSON 請求內文中的欄位對應整合請求參數。下列範例會將方法請求內文對應至名為 `body-header` 的整合請求標頭，並將部分請求內文 (如 JSON 表達式所示) 對應至名為 `pet-price` 的整合請求標頭。

若要測試此範例，請提供包含價格類別的輸入，如下所示：

```
[ 
  { 
    "id": 1, 
    "type": "dog", 
    "price": 249.99 
  }
]
```

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

**對應方法請求參數**

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

1. 選擇 REST API。

1. 選擇 `POST`、`PUT`、`PATCH` 或 `ANY` 方法。

   您的方法必須有非代理整合。

1. 針對**整合請求設定**，選擇**編輯**。

1. 選擇 **URL 請求標頭參數**。

1. 選擇**新增請求標頭參數**。

1. 對於**名稱**，輸入 **body-header**。

1. 對於**映射自**，輸入 **method.request.body**。

   這樣做會將方法請求內文對應至新的整合請求標頭參數。

1. 選擇**新增請求標頭參數**。

1. 對於**名稱**，輸入 **pet-price**。

1. 對於**映射自**，輸入 ** method.request.body[0].price**。

   這樣做會將部分方法請求內文對應至新的整合請求標頭參數。

1. 選擇**儲存**。

1. 重新部署 API 以使變更生效。

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

 在此範例中，您使用 [body](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) 屬性將 OpenAPI 定義檔案匯入 API Gateway 中。

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Body: 
        openapi: 3.0.1
        info:
          title: Parameter mapping example 3
          version: "2025-01-15T19:19:14Z"
        paths:
          /:
            post:
              responses:
                "200":
                  description: 200 response
              x-amazon-apigateway-integration:
                httpMethod: GET
                uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets
                responses:
                  default:
                    statusCode: "200"
                requestParameters:
                  integration.request.header.pet-price: method.request.body[0].price
                  integration.request.header.body-header: method.request.body
                requestTemplates:
                  application/json: '{"statusCode": 200}'
                passthroughBehavior: when_no_templates
                timeoutInMillis: 29000
                type: http
  ApiGatewayDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  ApiGatewayDeployment20250219:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  Stage:
    Type: 'AWS::ApiGateway::Stage'
    Properties:
       DeploymentId: !Ref ApiGatewayDeployment20250219
       RestApiId: !Ref Api
       StageName: prod
```

------
#### [ OpenAPI ]

以下 OpenAPI 定義會從 JSON 請求內文中的欄位對應整合請求參數。

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "Parameter mapping example 3",
    "version" : "2025-01-15T19:19:14Z"
  },
  "paths" : {
    "/" : {
      "post" : {
        "responses" : {
          "200" : {
            "description" : "200 response"
          }
        },
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.header.pet-price" : "method.request.body[0].price",
            "integration.request.header.body-header" : "method.request.body"
          },
          "requestTemplates" : {
            "application/json" : "{\"statusCode\": 200}"
          },
          "passthroughBehavior" : "when_no_templates",
          "timeoutInMillis" : 29000,
          "type" : "http"
        }
      }
    }
  }
}
```

------

## 範例 4：將整合回應對應至方法回應
<a name="request-response-data-mappings-example-4"></a>

您也可以將整合回應對應至方法回應。下列範例會將整合回應內文對應至名為 `location` 的方法回應標頭、將整合回應標頭 `x-app-id` 對應至方法回應標頭 `id`，並將多值整合回應標頭 `item` 對應至方法回應標頭 `items`。

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

**對應整合回應**

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

1. 選擇 REST API。

1. 選擇一個方法。

   您的方法必須有非代理整合。

1. 選擇**方法回應**索引標籤，然後針對**回應 200** 選擇**編輯**。

1. 針對**標頭名稱**，選擇**新增標頭**。

1. 建立三個分別名為 **id**、**item** 和 **location** 的標頭。

1. 選擇**儲存**。

1. 選擇**整合回應**索引標籤，然後針對**預設 - 回應**選擇**編輯**。

1. 在**標頭映射**下，輸入以下內容。

   1. 針對 **id**，輸入 **integration.response.header.x-app-id**

   1. 針對 **item**，輸入 **integration.response.multivalueheader.item**

   1. 針對 **location**，輸入 **integration.response.body.redirect.url**

1. 選擇**儲存**。

1. 重新部署 API 以使變更生效。

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

 在此範例中，您使用 [body](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) 屬性將 OpenAPI 定義檔案匯入 API Gateway 中。

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Body:
        openapi: 3.0.1
        info:
          title: Parameter mapping example
          version: "2025-01-15T19:21:35Z"
        paths:
          /:
            post:
              responses:
                "200":
                  description: 200 response
                  headers:
                    item:
                      schema:
                        type: string
                    location:
                      schema:
                        type: string
                    id:
                      schema:
                        type: string
              x-amazon-apigateway-integration:
                type: http
                httpMethod: GET
                uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets
                responses:
                  default:
                    statusCode: "200"
                    responseParameters:
                      method.response.header.id: integration.response.header.x-app-id
                      method.response.header.location: integration.response.body.redirect.url
                      method.response.header.item: integration.response.multivalueheader.item
                requestTemplates:
                  application/json: '{"statusCode": 200}'
                passthroughBehavior: when_no_templates
                timeoutInMillis: 29000
  ApiGatewayDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  ApiGatewayDeployment20250219:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  Stage:
    Type: 'AWS::ApiGateway::Stage'
    Properties:
       DeploymentId: !Ref ApiGatewayDeployment20250219
       RestApiId: !Ref Api
       StageName: prod
```

------
#### [ OpenAPI ]

以下 OpenAPI 定義會將整合回應對應至方法回應。

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "Parameter mapping example",
    "version" : "2025-01-15T19:21:35Z"
  },
  "paths" : {
    "/" : {
      "post" : {
        "responses" : {
          "200" : {
            "description" : "200 response",
            "headers" : {
              "item" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "location" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "id" : {
                "schema" : {
                  "type" : "string"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "type" : "http",
          "httpMethod" : "GET",
          "uri" : "http://petstore-demo-endpoint.execute-api.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.id" : "integration.response.header.x-app-id",
                "method.response.header.location" : "integration.response.body.redirect.url",
                "method.response.header.item" : "integration.response.multivalueheader.item"
              }
            }
          },
          "requestTemplates" : {
            "application/json" : "{\"statusCode\": 200}"
          },
          "passthroughBehavior" : "when_no_templates",
          "timeoutInMillis" : 29000
        }
      }
    }
  }
}
```

------

# API Gateway 中 REST API 的參數映射來源參考
<a name="rest-api-parameter-mapping-sources"></a>

當您建立參數映射時，請指定要修改的方法請求或整合回應參數，並指定如何修改這些參數。

下表顯示您可以對應的方法請求參數，以及建立映射的表達式。在這些表達式中，*name* 是方法請求參數的名稱。例如，若要對應請求標頭參數 `puppies`，則使用表達式 `method.request.header.puppies`。您的表達式必須符合規則表達式 `'^[a-zA-Z0-9._$-]+$]'`。您可以在代理和非代理整合的整合請求中使用參數映射。


| **映射的資料來源** | **映射表達式** | 
| --- | --- | 
| 方法請求路徑 | method.request.path.name | 
| 方法請求查詢字串 | method.request.querystring.name | 
| 多值方法請求查詢字串 | method.request.multivaluequerystring.name | 
| 方法請求標頭 | method.request.header.name | 
| 多值方法請求標頭 | method.request.multivalueheader.name | 
| 方法請求內文 | method.request.body | 
| 方法請求內文 (JsonPath) | `method.request.body.JSONPath_EXPRESSION`. *JSONPath\$1EXPRESSION* 是請求的內文中，JSON 欄位的 JSONPath 表達式。如需詳細資訊，請參閱 [JSONPath 表達式](http://goessner.net/articles/JsonPath/index.html#e2)。  | 
| 階段變數 | stageVariables.name | 
| 環境變數 |  `context.name` name 必須是[支援的環境變數](api-gateway-mapping-template-reference.md#context-variable-reference)之一。 | 
| 靜態值 | `'static_value'`. *static\$1value* 是字串常值，而且前後必須加上單引號。例如 `'https://www.example.com'`。 | 

下表顯示您可以對應的整合回應參數，以及建立映射的表達式。在這些表達式中，*name* 是整合回應參數的名稱。您可以從任何整合回應標頭或整合回應內文、\$1context 變數或靜態值，對應方法回應標頭。若要針對整合回應使用參數映射，則您需要非代理整合。


| 映射的資料來源 | 對應表達式 | 
| --- | --- | 
| 整合回應標頭 | integration.response.header.name | 
| 整合回應標頭 | integration.response.multivalueheader.name | 
| 整合回應內文 | integration.response.body | 
| 整合回應內文 (JsonPath) | `integration.response.body.JSONPath_EXPRESSION` *JSONPath\$1EXPRESSION* 是回應的內文中，JSON 欄位的 JSONPath 表達式。如需詳細資訊，請參閱 [JSONPath 表達式](http://goessner.net/articles/JsonPath/index.html#e2)。 | 
| 階段變數 | stageVariables.name | 
| 環境變數 |  `context.name` name 必須是[支援的環境變數](api-gateway-mapping-template-reference.md#context-variable-reference)之一。 | 
| 靜態值 | ` 'static_value'` *static\$1value* 是字串常值，而且前後必須加上單引號。例如 `'https://www.example.com'`。 | 

# API Gateway 中 REST API 的映射範本轉換
<a name="models-mappings"></a>

映射範本轉換會使用映射範本來修改您的整合請求或整合回應。*映射範本*是以 [Velocity 範本語言 (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) 表達的指令碼，會使用 [JSONPath](https://goessner.net/articles/JsonPath/) 並根據 `Content-type` 標頭套用至承載。您會使用映射範本來進行映射範本轉換。本節說明與映射範本相關的概念性資訊。

下圖顯示與 PetStore 整合端點整合之 `POST /pets` 資源的請求生命週期。在此 API 中，使用者會傳送有關寵物的資料，而整合端點會傳回與寵物相關聯的認養費。在此請求生命週期中，映射範本轉換會篩選傳送至整合端點的請求內文，以及篩選來自整合端點的回應內文。

![\[請求生命週期範例\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/mapping-template-transforms.png)


以下各節說明請求和回應生命週期。

## 方法請求和整合請求
<a name="models-mappings-request"></a>

在上述範例中，如果這是傳送至方法請求的請求內文：

```
POST /pets
    HTTP/1.1
    Host:abcd1234.us-west-2.amazonaws.com
    Content-type: application/json
    
  {
    "id": 1,
    "type": "dog",
    "Age": 11,
  }
```

此請求內文的格式不正確，無法供整合端點使用，因此 API Gateway 會執行映射範本轉換。API Gateway 只會執行映射範本轉換，因為有針對 Content-Type `application/json` 定義的映射範本。如果您未針對 Content-Type 定義映射範本，則根據預設，API Gateway 會透過整合請求將內文傳遞至整合端點。若要修改此行為，請參閱 [API Gateway 中 REST API 沒有映射範本時，承載的方法請求行為](integration-passthrough-behaviors.md)。

下列映射範本會先轉換整合請求中的方法請求資料，再將其傳送至整合端點：

```
#set($inputRoot = $input.path('$'))
  {
    "dogId" : "dog_"$elem.id,
    "Age": $inputRoot.Age
  }
```

1. `$inputRoot` 變數代表上一節中原始 JSON 資料的根物件。指令以 `#` 符號開始。

1. `dog` 是使用者的 `id` 和字串值的串連。

1. `Age` 來自方法請求內文。

然後，下列輸出會轉送至整合端點：

```
{
    "dogId" : "dog_1",
    "Age": 11
  }
```

## 整合回應和方法回應
<a name="models-mappings-response"></a>

成功對整合端點發出請求後，端點會將回應傳送至 API Gateway 的整合回應。以下是來自整合端點的輸出資料範例：

```
{
    "dogId" : "dog_1",
    "adoptionFee": 19.95,
}
```

方法回應預期的承載與整合回應傳回的承載不同。API Gateway 會執行映射範本轉換。API Gateway 只會執行映射範本轉換，因為有針對 Content-Type `application/json` 定義的映射範本。如果您未針對 Content-Type 定義映射範本，則根據預設，API Gateway 會透過整合回應將內文傳遞至方法回應。若要修改此行為，請參閱 [API Gateway 中 REST API 沒有映射範本時，承載的方法請求行為](integration-passthrough-behaviors.md)。

```
#set($inputRoot = $input.path('$'))
  {
    "adoptionFee" : $inputRoot.adoptionFee,
  }
```

下列輸出會傳送至方法回應：

```
{"adoptionFee": 19.95}
```

映射範本轉換範例至此完成。我們建議您盡可能使用代理整合來轉換資料，而不要使用映射範本轉換。如需詳細資訊，請參閱[選擇 API Gateway API 整合類型](api-gateway-api-integration-types.md)。

# API Gateway 中 REST API 沒有映射範本時，承載的方法請求行為
<a name="integration-passthrough-behaviors"></a>

如果您的方法請求具有承載，而您未針對 `Content-Type` 標頭定義映射範本，則您可以選擇透過整合請求將用戶端提供的請求承載傳遞至後端，而不進行轉換。這個過程稱為整合傳遞。

 傳入請求的實際傳遞行為是由此設定決定。共有三個選項：

**當沒有範本符合請求 Content-Type 標頭時**  
當方法請求內容類型不符合與對應範本相關聯的任何內容類型時，如果您想要讓方法請求內文透過整合請求傳遞到後端而不進行轉換，請選擇此選項。  
呼叫 API Gateway API 時，您可以透過在[整合](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html)上將 `WHEN_NO_MATCH` 設定為 `passthroughBehavior` 屬性值來選擇此選項。

**未定義範本時 (建議)**  
當整合請求中未定義任何對應範本時，如果您想要讓方法請求內文透過整合請求傳遞到後端而不進行轉換，請選擇此選項。如果選取此選項時已定義範本，則具有承載但內容類型不符合任何已定義映射範本的方法請求將會遭拒，並顯示 HTTP 415 Unsupported Media Type (不支援的媒體類型) 回應。  
呼叫 API Gateway API 時，您可以透過在[整合](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html)上將 `WHEN_NO_TEMPLATES` 設定為 `passthroughBehavior` 屬性值來選擇此選項。

**從不**  
當整合請求中未定義任何對應範本時，如果您不想要讓方法請求內文透過整合請求傳遞到後端而不進行轉換，請選擇此選項。如果選取此選項時已定義範本，未映射內容類型的方法請求會遭到拒絕，並顯示 HTTP 415 Unsupported Media Type (不支援的媒體類型) 回應。  
呼叫 API Gateway API 時，您可以透過在[整合](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html)上將 `NEVER` 設定為 `passthroughBehavior` 屬性值來選擇此選項。

 下列範例說明可能的傳遞行為。

範例 1：針對 `application/json` 內容類型在整合請求中定義的一個對應範本。


| Content-type | 傳遞選項 | Behavior (行為) | 
| --- | --- | --- | 
| 無 API Gateway 預設為 `application/json` | WHEN\$1NO\$1MATCH | 使用此範本轉換請求承載。 | 
| 無 API Gateway 預設為 `application/json` | WHEN\$1NO\$1TEMPLATES | 使用此範本轉換請求承載。 | 
| 無 API Gateway 預設為 `application/json` | NEVER | 使用此範本轉換請求承載。 | 
| application/json | WHEN\$1NO\$1MATCH | 使用此範本轉換請求承載。 | 
| application/json | WHEN\$1NO\$1TEMPLATES | 使用此範本轉換請求承載。 | 
| application/json | NEVER | 使用此範本轉換請求承載。 | 
| application/xml | WHEN\$1NO\$1MATCH | 請求承載未轉換，而且會依現狀傳送到後端。 | 
| application/xml | WHEN\$1NO\$1TEMPLATES | 請求遭到拒絕，回應為 HTTP 415 Unsupported Media Type。 | 
| application/xml | NEVER | 請求遭到拒絕，回應為 HTTP 415 Unsupported Media Type。 | 

範例 2：針對 `application/xml` 內容類型在整合請求中定義的一個對應範本。


| Content-type | 傳遞選項 | Behavior (行為) | 
| --- | --- | --- | 
| 無 API Gateway 預設為 `application/json` | WHEN\$1NO\$1MATCH | 請求承載未轉換，而且會依現狀傳送到後端。 | 
| 無 API Gateway 預設為 `application/json` | WHEN\$1NO\$1TEMPLATES | 請求遭到拒絕，回應為 HTTP 415 Unsupported Media Type。 | 
| 無 API Gateway 預設為 `application/json` | NEVER | 請求遭到拒絕，回應為 HTTP 415 Unsupported Media Type。 | 
| application/json | WHEN\$1NO\$1MATCH | 請求承載未轉換，而且會依現狀傳送到後端。 | 
| application/json | WHEN\$1NO\$1TEMPLATES | 請求遭到拒絕，回應為 HTTP 415 Unsupported Media Type。 | 
| application/json | NEVER | 請求遭到拒絕，回應為 HTTP 415 Unsupported Media Type。 | 
| application/xml | WHEN\$1NO\$1MATCH | 使用此範本轉換請求承載。 | 
| application/xml | WHEN\$1NO\$1TEMPLATES | 使用此範本轉換請求承載。 | 
| application/xml | NEVER | 使用此範本轉換請求承載。 | 

範例 3：整合請求中未定義任何映射範本。


| Content-type | 傳遞選項 | Behavior (行為) | 
| --- | --- | --- | 
| 無 API Gateway 預設為 `application/json` | WHEN\$1NO\$1MATCH | 請求承載未轉換，而且會依現狀傳送到後端。 | 
| 無 API Gateway 預設為 `application/json` | WHEN\$1NO\$1TEMPLATES | 請求承載未轉換，而且會依現狀傳送到後端。 | 
| 無 API Gateway 預設為 `application/json` | NEVER | 請求遭到拒絕，回應為 HTTP 415 Unsupported Media Type。 | 
| application/json | WHEN\$1NO\$1MATCH | 請求承載未轉換，而且會依現狀傳送到後端。 | 
| application/json | WHEN\$1NO\$1TEMPLATES | 請求承載未轉換，而且會依現狀傳送到後端。 | 
| application/json | NEVER | 請求遭到拒絕，回應為 HTTP 415 Unsupported Media Type。 | 
| application/xml | WHEN\$1NO\$1MATCH | 請求承載未轉換，而且會依現狀傳送到後端。 | 
| application/xml | WHEN\$1NO\$1TEMPLATES | 請求承載未轉換，而且會依現狀傳送到後端。 | 
| application/xml | NEVER | 請求遭到拒絕，回應為 HTTP 415 Unsupported Media Type。 | 

# API Gateway 中 REST API 的其他映射範本範例
<a name="example-photos"></a>

下列範例顯示 API Gateway 中的相簿 API，其使用映射範本來轉換整合請求和整合回應資料。此 API 也會使用資料模型來定義方法請求和整合回應承載。如需更多有關資料模型的詳細資訊，請參閱 [REST API 的資料模型](models-mappings-models.md)。

## 方法請求和整合請求
<a name="example-photos-request"></a>

以下是定義方法請求內文的模型。此輸入模型會要求發起人上傳一張相片，並要求每頁至少 10 張相片。您可以使用此輸入模型來產生 SDK，或針對您的 API 使用請求驗證。使用請求驗證時，如果方法請求內文未遵循模型的資料結構，則 API Gateway 會讓請求失敗。

```
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "PhotosInputModel",
  "type": "object",
  "properties": {
    "photos": {
      "type": "object",
      "required" : [
      "photo"
      ],
      "properties": {
        "page": { "type": "integer" },
        "pages": { "type": "string" },
        "perpage": { "type": "integer", "minimum" : 10 },
        "total": { "type": "string" },
        "photo": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": { "type": "string" },
              "owner": { "type": "string" },
              "photographer_first_name" : {"type" : "string"},
              "photographer_last_name" : {"type" : "string"},
              "secret": { "type": "string" },
              "server": { "type": "string" },
              "farm": { "type": "integer" },
              "title": { "type": "string" },
              "ispublic": { "type": "boolean" },
              "isfriend": { "type": "boolean" },
              "isfamily": { "type": "boolean" }
            }
          }
        }
      }
    }
  }
}
```

以下是遵循上述資料模型之資料結構的方法請求內文範例。

```
{
  "photos": {
    "page": 1,
    "pages": "1234",
    "perpage": 100,
    "total": "123398",
    "photo": [
      {
        "id": "12345678901",
        "owner": "23456789@A12",
        "photographer_first_name" : "Saanvi",
        "photographer_last_name" : "Sarkar",
        "secret": "abc123d456",
        "server": "1234",
        "farm": 1,
        "title": "Sample photo 1",
        "ispublic": true,
        "isfriend": false,
        "isfamily": false
      },
      {
        "id": "23456789012",
        "owner": "34567890@B23",
        "photographer_first_name" : "Richard",
        "photographer_last_name" : "Roe",
        "secret": "bcd234e567",
        "server": "2345",
        "farm": 2,
        "title": "Sample photo 2",
        "ispublic": true,
        "isfriend": false,
        "isfamily": false
      }
    ]
  }
}
```

在此範例中，如果用戶端提交了上述方法請求內文，則此映射範本會轉換承載，使其符合整合端點要求的格式。

```
#set($inputRoot = $input.path('$'))
{
  "photos": [
#foreach($elem in $inputRoot.photos.photo)
    {
      "id": "$elem.id",
      "photographedBy": "$elem.photographer_first_name $elem.photographer_last_name",
      "title": "$elem.title",
      "ispublic": $elem.ispublic,
      "isfriend": $elem.isfriend,
      "isfamily": $elem.isfamily
    }#if($foreach.hasNext),#end
		
#end
  ]
}
```

下列範例是轉換的輸出資料：

```
{
  "photos": [
    {
      "id": "12345678901",
      "photographedBy": "Saanvi Sarkar",
      "title": "Sample photo 1",
      "ispublic": true,
      "isfriend": false,
      "isfamily": false
    },		
    {
      "id": "23456789012",
      "photographedBy": "Richard Roe",
      "title": "Sample photo 2",
      "ispublic": true,
      "isfriend": false,
      "isfamily": false
    }		
  ]
}
```

此資料會傳送到整合請求，然後再傳送到整合端點。

## 整合回應和方法回應
<a name="photos-example-response"></a>

以下是整合端點中相片資料的範例輸出模型。您可以使用此模型作為方法回應模型，當您為 API 產生強型別 SDK 時，需要這樣做。這會導致輸出在 Java 或 Objective-C 中轉換成適當的類別。

```
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "PhotosOutputModel",
  "type": "object",
  "properties": {
    "photos": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "photographedBy": { "type": "string" },
          "title": { "type": "string" },
          "ispublic": { "type": "boolean" },
          "isfriend": { "type": "boolean" },
          "isfamily": { "type": "boolean" }
        }
      }
    }
  }
}
```

整合端點的回應可能無法使用遵循此模型的資料結構。例如，整合回應可能如下所示：

```
  "photos": [
    {
      "id": "12345678901",
      "photographedBy": "Saanvi Sarkar",
      "title": "Sample photo 1",
      "description": "My sample photo 1",
      "public": true,
      "friend": false,
      "family": false
    },		
    {
      "id": "23456789012",
      "photographedBy": "Richard Roe",
      "title": "Sample photo 2",
      "description": "My sample photo 1",
      "public": true,
      "friend": false,
      "family": false
    }		
  ]
}
```

下列範例映射範本會將整合回應資料轉換為方法回應預期的格式：

```
#set($inputRoot = $input.path('$'))
{
  "photos": [
#foreach($elem in $inputRoot.photos.photo)
    {
      "id": "$elem.id",
      "photographedBy": "$elem.photographer_first_name $elem.photographer_last_name",
      "title": "$elem.title",
      "ispublic": $elem.public,
      "isfriend": $elem.friend,
      "isfamily": $elem.family
    }#if($foreach.hasNext),#end
		
#end
  ]
}
```

下列範例是轉換的輸出資料：

```
{
  "photos": [
    {
      "id": "12345678901",
      "photographedBy": "Saanvi Sarkar",
      "title": "Sample photo 1",
      "ispublic": true,
      "isfriend": false,
      "isfamily": false
    },		
    {
      "id": "23456789012",
      "photographedBy": "Richard Roe",
      "title": "Sample photo 2",
      "ispublic": true,
      "isfriend": false,
      "isfamily": false
    }		
  ]
}
```

此資料會傳送到方法回應，然後再傳回用戶端。

# 覆寫 API Gateway 中 REST API 的 API 請求和回應參數及狀態碼
<a name="apigateway-override-request-response-parameters"></a>

您可以使用映射範本轉換來覆寫任何類型的請求參數、回應標頭或回應狀態碼。使用映射範本執行下列操作：
+ 執行多對一參數映射
+ 在套用標準 API Gateway 映射之後覆寫參數
+ 根據內文內容或其他參數值，有條件地映射參數
+ 以程式設計方式建立新參數
+ 覆寫由您的整合端點所傳回的狀態碼

覆寫是最終。覆寫只能套用到每個參數一次。如果您嘗試覆寫相同的參數多次，API Gateway 會傳回 `5XX` 回應。如果您必須多次在整個範本中覆寫相同的參數，我們建議您建立變數與在範本結尾套用覆寫。只會在整個範本剖析後才套用範本。

## 範例 1：根據整合內文覆寫狀態碼
<a name="apigateway-override-request-response-examples"></a>

下列範例使用[範例 API](api-gateway-create-api-from-example.md)，根據整合回應內文覆寫狀態碼。

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

**根據整合回應內文覆寫狀態碼**

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

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

1. 針對 **REST API**，選擇**組建**。

1. 針對 **API 詳細資訊**，選擇**範例 API**。

1. 選擇**建立 API**。

   API Gateway 會建立範例寵物商店 API。若要擷取有關寵物的資訊，您可以使用 API 方法請求 `GET /pets/{petId}`，其中 `{petId}` 是對應寵物 ID 號碼的路徑參數。

   在此範例中，您會在偵測到錯誤條件時，將 `GET` 方法的回應程式碼覆寫為 `400`。

1. 在**資源**樹狀結構中的 `/{petId}` 下，選擇 `GET` 方法。

1. 首先，測試目前的 API 實作。

   選擇**測試**標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

1. 針對 **petId**，輸入 **-1**，然後選擇**測試**。

   **回應內文**指出超出範圍錯誤：

   ```
   {
     "errors": [
       {
         "key": "GetPetRequest.petId",
         "message": "The value is out of range."
       }
     ]
   }
   ```

   此外，**日誌**下的最後一行結尾為：`Method completed with status: 200`。

   整合已成功完成，但發生錯誤。現在您將根據整合回應覆寫狀態碼。

1. 在**整合回應**索引標籤上，針對**預設 - 回應**，選擇**編輯**。

1. 選擇**對應範本**。

1. 選擇**新增對應範本**。

1. 針對**內容類型**，輸入 **application/json**。

1. 針對**範本內文**，輸入下列內容：

   ```
   #set($inputRoot = $input.path('$'))
   $input.json("$")
   #if($inputRoot.toString().contains("error"))
   #set($context.responseOverride.status = 400)
   #end
   ```

   如果整合回應包含字串 `error`，則此映射範本會使用 `$context.responseOverride.status` 變數將狀態碼覆寫為 `400`。

1. 選擇**儲存**。

1. 選擇**測試**標籤。

1. 針對 **petId**，輸入 **-1**。

1. 在結果中，**Response Body (回應內文)** 表示超出範圍錯誤：

   ```
   {
     "errors": [
       {
         "key": "GetPetRequest.petId",
         "message": "The value is out of range."
       }
     ]
   }
   ```

   然而，**日誌**下的最後一列結尾現在會是：`Method completed with status: 400`。

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

 在此範例中，您使用 [body](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) 屬性將 OpenAPI 定義檔案匯入 API Gateway 中。

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Body: 
        openapi: 3.0.1
        info:
          title: PetStore Example 1
          description: Example pet store API.
          version: "2025-01-14T00:13:18Z"
        paths:
          /pets/{petId}:
            get:
              parameters:
                - name: petId
                  in: path
                  required: true
                  schema:
                    type: string
              responses:
                "200":
                  description: 200 response
              x-amazon-apigateway-integration:
                httpMethod: GET
                uri: http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets/{petId}
                responses:
                  default:
                    statusCode: "200"
                    responseTemplates:
                      application/json: |-
                        #set($inputRoot = $input.path('$'))
                        $input.json("$")
                        #if($inputRoot.toString().contains("error"))
                        #set($context.responseOverride.status = 400)
                        #end
                requestParameters:
                  integration.request.path.petId: method.request.path.petId
                passthroughBehavior: when_no_match
                type: http
        components:
          schemas:
            Pet:
              type: object
              properties:
                id:
                  type: integer
                type:
                  type: string
                price:
                  type: number
  ApiGatewayDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  ApiGatewayDeployment20250219:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  Stage:
    Type: 'AWS::ApiGateway::Stage'
    Properties:
       DeploymentId: !Ref ApiGatewayDeployment20250219
       RestApiId: !Ref Api
       StageName: prod
```

------
#### [ OpenAPI ]

以下 OpenAPI 定義會建立 `GET pets/{petId}` 資源，並根據整合內文覆寫狀態碼。

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "PetStore Example 1",
    "description" : "Example pet store API.",
    "version" : "2025-01-14T00:13:18Z"
  },
  "paths" : {
    "/pets/{petId}" : {
      "get" : {
        "parameters" : [ {
          "name" : "petId",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response"
          }
        },
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets/{petId}",
          "responses" : {
            "default" : {
              "statusCode" : "200",
              "responseTemplates" : {
                "application/json" : "#set($inputRoot = $input.path('$'))\n$input.json(\"$\")\n#if($inputRoot.toString().contains(\"error\"))\n#set($context.responseOverride.status = 400)\n#end"
              }
            }
          },
          "requestParameters" : {
            "integration.request.path.petId" : "method.request.path.petId"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  },
  "components" : {
    "schemas" : {
      "Pet" : {
        "type" : "object",
        "properties" : {
          "id" : {
            "type" : "integer"
          },
          "type" : {
            "type" : "string"
          },
          "price" : {
            "type" : "number"
          }
        }
      }
    }
  }
}
```

------

## 範例 2：覆寫請求標頭並建立新標頭
<a name="apigateway-override-request-response-examples-2"></a>

下列範例使用[範例 API](api-gateway-create-api-from-example.md) 覆寫請求標頭並建立新標頭。

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

**透過建立新標頭來覆寫方法的請求標頭**

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

1. 選擇您在上述教學課程中建立的範例 API。API 的名稱應為 **PetStore**。

1. 在**資源**樹狀結構中的 `/pet` 下，選擇 `GET` 方法。

1. 在**方法請求**索引標籤上，針對**方法請求設定**，選擇**編輯**。

1. 選擇 **HTTP 請求標頭**，然後選擇**新增標頭**。

1. 對於**名稱**，輸入 **header1**。

1. 選擇**新增標頭**，然後建立名為 **header2** 的第二個標頭。

1. 選擇**儲存**。

   現在，請使用映射範本將這些標頭合併成一個標頭值。

1. 在**整合請求**索引標籤上，針對**整合請求設定**，選擇**編輯**。

1. 針對**請求內文傳遞**，選取**未定義範本時 (建議)**。

1. 選擇**對應範本**，然後執行下列動作：

   1. 選擇**新增映射範本**。

   1. 針對**內容類型**，輸入 **application/json**。

   1. 針對**範本內文**，輸入下列內容：

      ```
      #set($header1Override = "pets")
      #set($header3Value = "$input.params('header1')$input.params('header2')")
      $input.json("$")
      #set($context.requestOverride.header.header3 = $header3Value)
      #set($context.requestOverride.header.header1 = $header1Override)
      #set($context.requestOverride.header.multivalueheader=[$header1Override, $header3Value])
      ```

      此映射範本會將 `header1` 覆寫為字串 `pets`，並建立結合 `header1` 和 `header2` 且名為 `$header3Value` 的多值標頭。

1. 選擇**儲存**。

1. 選擇**測試**標籤。

1. 在**標頭**下，複製下列程式碼：

   ```
   header1:header1Val
   header2:header2Val
   ```

1. 選擇 **Test (測試)**。

   在**日誌**中，您應該會看到包括此文字的項目：

   ```
   Endpoint request headers: {header3=header1Valheader2Val, 
   header2=header2Val, header1=pets, x-amzn-apigateway-api-id=api-id,
   Accept=application/json, multivalueheader=pets,header1Valheader2Val}
   ```

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

 在此範例中，您使用 [body](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-body) 屬性將 OpenAPI 定義檔案匯入 API Gateway 中。

```
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Body: 
        openapi: 3.0.1
        info:
          title: PetStore Example 2
          description: Example pet store API.
          version: "2025-01-14T00:36:18Z"
        paths:
          /pets:
            get:
              parameters:
                - name: header2
                  in: header
                  schema:
                    type: string
                - name: page
                  in: query
                  schema:
                    type: string
                - name: type
                  in: query
                  schema:
                    type: string
                - name: header1
                  in: header
                  schema:
                    type: string
              responses:
                "200":
                  description: 200 response
              x-amazon-apigateway-integration:
                httpMethod: GET
                uri: http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets
                responses:
                  default:
                    statusCode: "200"
                requestParameters:
                  integration.request.header.header1: method.request.header.header1
                  integration.request.header.header2: method.request.header.header2
                  integration.request.querystring.page: method.request.querystring.page
                  integration.request.querystring.type: method.request.querystring.type
                requestTemplates:
                  application/json: |-
                    #set($header1Override = "pets")
                    #set($header3Value = "$input.params('header1')$input.params('header2')")
                    $input.json("$")
                    #set($context.requestOverride.header.header3 = $header3Value)
                    #set($context.requestOverride.header.header1 = $header1Override)
                    #set($context.requestOverride.header.multivalueheader=[$header1Override, $header3Value])
                passthroughBehavior: when_no_match
                type: http
        components:
          schemas:
            Pet:
              type: object
              properties:
                id:
                  type: integer
                type:
                  type: string
                price:
                  type: number
  ApiGatewayDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  ApiGatewayDeployment20250219:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn: Api 
    Properties: 
      RestApiId: !Ref Api
  Stage:
    Type: 'AWS::ApiGateway::Stage'
    Properties:
       DeploymentId: !Ref ApiGatewayDeployment20250219
       RestApiId: !Ref Api
       StageName: prod
```

------
#### [ OpenAPI ]

 以下 OpenAPI 定義會建立 `GET pets` 資源，以及覆寫請求標頭並建立新標頭。

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "PetStore Example 2",
    "description" : "Example pet store API.",
    "version" : "2025-01-14T00:36:18Z"
  },
  "paths" : {
    "/pets" : {
      "get" : {
        "parameters" : [ {
          "name" : "header2",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "page",
          "in" : "query",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "type",
          "in" : "query",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "header1",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "200" : {
            "description" : "200 response"
          }
        },
        "x-amazon-apigateway-integration" : {
          "httpMethod" : "GET",
          "uri" : "http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets",
          "responses" : {
            "default" : {
              "statusCode" : "200"
            }
          },
          "requestParameters" : {
            "integration.request.header.header1" : "method.request.header.header1",
            "integration.request.header.header2" : "method.request.header.header2",
            "integration.request.querystring.page" : "method.request.querystring.page",
            "integration.request.querystring.type" : "method.request.querystring.type"
          },
          "requestTemplates" : {
            "application/json" : "#set($header1Override = \"pets\")\n#set($header3Value = \"$input.params('header1')$input.params('header2')\")\n$input.json(\"$\")\n#set($context.requestOverride.header.header3 = $header3Value)\n#set($context.requestOverride.header.header1 = $header1Override)\n#set($context.requestOverride.header.multivalueheader=[$header1Override, $header3Value])"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "http"
        }
      }
    }
  }
}
```

------

若要使用映射範本覆寫，請新增一或多個下列 `$context` 變數。如需 `$context` 變數清單，請參閱 [資料轉換的內容變數](api-gateway-mapping-template-reference.md#context-variable-reference)。

# 教學課程：修改 AWS 服務整合的整合請求和回應
<a name="set-up-data-transformations-in-api-gateway"></a>

下列教學課程說明如何使用映射範本轉換來設定映射範本，以使用主控台和 CLI AWS 轉換整合請求和回應。

**Topics**
+ [使用 API Gateway 主控台設定資料轉換](#mapping-example-console)
+ [使用 CLI AWS 設定資料轉換](#mapping-example-cli)
+ [已完成的資料轉換 CloudFormation 範本](#api-gateway-data-transformations-full-cfn-stack)

## 使用 API Gateway 主控台設定資料轉換
<a name="mapping-example-console"></a>

在本教學課程中，您將使用下列 .zip 檔案 [data-transformation-tutorial-console.zip](samples/data-transformation-tutorial-console.zip)，建立不完整的 API 和 DynamoDB 資料表。此不完整的 API 具有 `/pets` 資源，其中含有 `GET` 和 `POST` 方法。
+ `GET` 方法將從 `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP 端點取得資料。輸出資料將根據 [API Gateway 中 REST API 的映射範本轉換](models-mappings.md) 中的對應範本進行轉換。
+ `POST` 方法可讓使用者使用對應範本，將寵物資訊 `POST` 至 Amazon DynamoDB 資料表。

下載並解壓縮 [的應用程式建立範本 CloudFormation](samples/data-transformation-tutorial-console.zip)。您將使用此範本建立 DynamoDB 資料表，以發布寵物資訊和不完整的 API。您將完成 API Gateway 主控台中的其餘步驟。

**建立 CloudFormation 堆疊**

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

1. 選擇 **Create stack (建立堆疊)**，然後選擇 **With new resources (standard) (使用新資源 (標準))**。

1. 對於 **Specify template (指定範本)**，選擇 **Upload a template file (上傳範本檔案)**。

1. 選取您下載的範本。

1. 選擇 **Next** (下一步)。

1. 針對 **Stack name (堆疊名稱)**，輸入 **data-transformation-tutorial-console**，然後選擇 **Next (下一步)**。

1. 針對 **Configure stack options (設定堆疊選項)**，選擇 **Next (下一步)**。

1. 針對 **功能**，確認 CloudFormation 可以在您的帳戶中建立 IAM 資源。

1. 選擇**下一步**，然後選擇**提交**。

CloudFormation 會佈建範本中指定的資源。完成資源佈建可能需要幾分鐘的時間。當您的 CloudFormation 堆疊狀態為 **CREATE\$1COMPLETE** 時，您就可以繼續進行下一個步驟。

**測試 `GET` 整合回應**

1. 在 CloudFormation 堆疊**的資源**索引標籤上**data-transformation-tutorial-console**，選取 API 的實體 ID。

1. 在主導覽窗格中，選擇**資源**，然後選取 **GET** 方法。

1. 選擇**測試**標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

   測試的輸出將顯示下列內容：

   ```
   [
     {
       "id": 1,
       "type": "dog",
       "price": 249.99
     },
     {
       "id": 2,
       "type": "cat",
       "price": 124.99
     },
     {
       "id": 3,
       "type": "fish",
       "price": 0.99
     }
   ]
   ```

   您將根據 [API Gateway 中 REST API 的映射範本轉換](models-mappings.md)中的對應範本轉換此輸出。

**轉換 `GET` 整合回應**

1. 選擇**整合回應**索引標籤。

   目前，沒有已定義的對應範本，因此不會轉換整合回應。

1. 針對**預設 - 回應**，選擇**編輯**。

1. 選擇**對應範本**，然後執行下列動作：

   1. 選擇**新增映射範本**。

   1. 針對**內容類型**，輸入 **application/json**。

   1. 針對**範本內文**，輸入下列內容：

      ```
      #set($inputRoot = $input.path('$'))
      [
      #foreach($elem in $inputRoot)
        {
          "description" : "Item $elem.id is a $elem.type.",
          "askingPrice" : $elem.price
        }#if($foreach.hasNext),#end
      
      #end
      ]
      ```

   選擇**儲存**。

**測試 `GET` 整合回應**
+ 選擇**測試**索引標籤，然後選擇**測試**。

  測試的輸出將顯示轉換後的回應。

  ```
  [
    {
      "description" : "Item 1 is a dog.",
      "askingPrice" : 249.99
    },
    {
      "description" : "Item 2 is a cat.",
      "askingPrice" : 124.99
    },
    {
      "description" : "Item 3 is a fish.",
      "askingPrice" : 0.99
    }
  ]
  ```

**從 `POST` 方法轉換輸入資料**

1. 選擇 **POST** 方法。

1. 選擇**整合請求**索引標籤，然後針對**整合請求設定**，選擇**編輯**。

    CloudFormation 範本已填入一些整合請求欄位。
   +  整合類型為 AWS 服務。
   +  AWS 服務 是 DynamoDB。
   +  HTTP 方法為 `POST`。
   +  動作為 `PutItem`。
   +  允許 API Gateway 將項目放入 DynamoDB 資料表的執行角色是 `data-transformation-tutorial-console-APIGatewayRole`. CloudFormation created this role，以允許 API Gateway 具有與 DynamoDB 互動的最低許可。

    尚未指定 DynamoDB 資料表的名稱。您將在下列步驟中指定此名稱。

1. 針對**請求內文傳遞**，選取**永不**。

   這意味著 API 將拒絕 Content-Type 沒有對應範本的資料。

1. 選擇**對應範本**。

1. **內容類型**會設定為 `application/json`。這表示不是 application/json 的內容類型將遭 API 拒絕。如需整合傳遞行為的詳細資訊，請參閱 [API Gateway 中 REST API 沒有映射範本時，承載的方法請求行為](integration-passthrough-behaviors.md)。

1. 將下列程式碼輸入至文字編輯器。

   ```
   {
       "TableName":"data-transformation-tutorial-console-ddb",
       "Item": {
           "id": {
               "N": $input.json("$.id")
           },
           "type": {
               "S": $input.json("$.type")
           },
           "price": {
               "N": $input.json("$.price")
           }
       }
   }
   ```

    此範本會將資料表指定為 `data-transformation-tutorial-console-ddb`，並將項目設為 `id`、`type` 和 `price`。這些項目將來自 `POST` 方法的內文。您也可以使用資料模型來協助建立對應範本。如需詳細資訊，請參閱[API Gateway 中的 REST API 的請求驗證](api-gateway-method-request-validation.md)。

1. 選擇**儲存**以儲存您的映射範本。

**從 `POST` 方法新增方法和整合回應**

 CloudFormation 已建立空白方法和整合回應。您將編輯此回應，以提供詳細資訊。如需如何編輯回應的詳細資訊，請參閱 [API Gateway 中 REST API 的參數映射範例](request-response-data-mappings.md)。

1. 在**整合回應**索引標籤上，針對**預設 - 回應**選擇**編輯**。

1. 選擇**對應範本**，然後選擇**新增對應範本**。

1. 針對 **Content-Type**，輸入 **application/json**。

1. 在程式碼編輯器中，輸入下列輸出對應範本以傳送輸出訊息：

   ```
   { "message" : "Your response was recorded at $context.requestTime" }
   ```

   如需內容變數的詳細資訊，請參閱 [資料轉換的內容變數](api-gateway-mapping-template-reference.md#context-variable-reference)。

1. 選擇**儲存**以儲存您的對應範本。

**測試 `POST` 方法**

選擇**測試**標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

1. 在請求內文中，輸入下列範例。

   ```
   {
             "id": "4",
             "type" : "dog",
             "price": "321"
   }
   ```

1. 選擇**測試**。

   輸出應該會顯示您的成功訊息。

    您可以在 [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/) 開啟 DynamoDB 主控台，以驗證範例項目是否位於您的資料表中。

**刪除 CloudFormation 堆疊**

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

1. 選取您的 CloudFormation 堆疊。

1. 選擇**刪除**，然後確認您的選擇。

## 使用 CLI AWS 設定資料轉換
<a name="mapping-example-cli"></a>

在本教學課程中，您將使用下列 .zip 檔案 [data-transformation-tutorial-cli.zip](samples/data-transformation-tutorial-cli.zip)，建立不完整的 API 和 DynamoDB 資料表。這個不完整的 API 具有 `/pets` 資源，其中含有與 `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP 端點整合的 `GET` 方法。您將建立 `POST` 方法，以連線至 DynamoDB 資料表，並使用對應範本將資料輸入至 DynamoDB 資料表。
+ 您將根據 [API Gateway 中 REST API 的映射範本轉換](models-mappings.md)中的對應範本轉換輸出資料。
+ 您將建立 `POST` 方法，允許使用者使用對應範本，將寵物資訊 `POST` 至 Amazon DynamoDB 資料表。

**建立 CloudFormation 堆疊**

下載並解壓縮 [的應用程式建立範本 CloudFormation](samples/data-transformation-tutorial-cli.zip)。

若要完成下列教學課程，您需要 [AWS Command Line Interface (AWS CLI) 第 2 版](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

對於長命令，逸出字元 (`\`) 用於將命令分割為多行。
**注意**  
在 Windows 中，作業系統的內建終端機不支援您常用的某些 Bash CLI 命令 (例如 `zip`)。若要取得 Ubuntu 和 Bash 的 Windows 整合版本，請[安裝適用於 Linux 的 Windows 子系統](https://learn.microsoft.com/en-us/windows/wsl/install)。本指南中的 CLI 命令範例使用 Linux 格式。如果您使用的是 Windows CLI，必須重新格式化包含內嵌 JSON 文件的命令。

1.  使用下列命令來建立 CloudFormation 堆疊。

   ```
   aws cloudformation create-stack --stack-name data-transformation-tutorial-cli --template-body file://data-transformation-tutorial-cli.zip --capabilities CAPABILITY_NAMED_IAM 
   ```

1. CloudFormation 會佈建範本中指定的資源。完成資源佈建可能需要幾分鐘的時間。使用下列命令來查看 CloudFormation 堆疊的狀態。

   ```
   aws cloudformation describe-stacks --stack-name data-transformation-tutorial-cli
   ```

1. 當您的 CloudFormation 堆疊狀態為 時`StackStatus: "CREATE_COMPLETE"`，請使用下列命令來擷取未來步驟的相關輸出值。

   ```
    aws cloudformation describe-stacks --stack-name data-transformation-tutorial-cli --query "Stacks[*].Outputs[*].{OutputKey: OutputKey, OutputValue: OutputValue, Description: Description}"
   ```

   輸出值如下：
   + ApiRole，這是允許 API Gateway 將項目放入 DynamoDB 資料表的角色名稱。對於本教學課程，角色名稱為 `data-transformation-tutorial-cli-APIGatewayRole-ABCDEFG`。
   + DDBTableName，這是 DynamoDB 資料表的名稱。對於本教學課程，資料表名稱為 `data-transformation-tutorial-cli-ddb`。
   + ResourceId，這是 `GET` 和 `POST` 方法公開所在寵物資源的 ID。對於本教學課程，資源 ID 為 `efg456`
   + ApiId，這是 API 的 ID。對於本教學課程，API ID 為 `abc123`。

**在資料轉換之前測試 `GET` 方法**
+ 使用下列命令測試 `GET` 方法。

  ```
  aws apigateway test-invoke-method --rest-api-id abc123 \
            --resource-id efg456 \
            --http-method GET
  ```

  測試的輸出將顯示下列內容。

  ```
  [
    {
      "id": 1,
      "type": "dog",
      "price": 249.99
    },
    {
      "id": 2,
      "type": "cat",
      "price": 124.99
    },
    {
      "id": 3,
      "type": "fish",
      "price": 0.99
    }
  ]
  ```

  您將根據 [API Gateway 中 REST API 的映射範本轉換](models-mappings.md)中的對應範本轉換此輸出。

**轉換 `GET` 整合回應**
+ 使用下列命令更新 `GET` 方法的整合回應。將 *rest-api-id* 和 *resource-id* 取代為您的值。

  使用下列命令建立整合回應。

  ```
  aws apigateway put-integration-response --rest-api-id abc123 \
    --resource-id efg456 \
    --http-method GET \
    --status-code 200 \
    --selection-pattern "" \
    --response-templates '{"application/json": "#set($inputRoot = $input.path(\"$\"))\n[\n#foreach($elem in $inputRoot)\n {\n  \"description\": \"Item $elem.id is a $elem.type\",\n  \"askingPrice\": \"$elem.price\"\n }#if($foreach.hasNext),#end\n\n#end\n]"}'
  ```

**測試 `GET` 方法**
+ 使用下列命令測試 `GET` 方法。

  ```
  aws apigateway test-invoke-method --rest-api-id abc123 \
    --resource-id efg456 \
    --http-method GET \
  ```

  測試的輸出將顯示轉換後的回應。

  ```
  [
    {
      "description" : "Item 1 is a dog.",
      "askingPrice" : 249.99
    },
    {
      "description" : "Item 2 is a cat.",
      "askingPrice" : 124.99
    },
    {
      "description" : "Item 3 is a fish.",
      "askingPrice" : 0.99
    }
  ]
  ```

**建立 `POST` 方法**

1. 使用下列命令，在 `/pets` 資源上建立新方法。

   ```
   aws apigateway put-method --rest-api-id abc123 \
     --resource-id efg456 \
     --http-method POST \
     --authorization-type "NONE" \
   ```

   此方法可讓您將寵物資訊傳送至您在 CloudFormation 堆疊中建立的 DynamoDB 資料表。

1.  使用下列命令在 `POST`方法上建立 AWS 服務 整合。

   ```
   aws apigateway put-integration --rest-api-id abc123 \
     --resource-id efg456 \
     --http-method POST \
     --type AWS \
     --integration-http-method POST \
     --uri "arn:aws:apigateway:us-east-2:dynamodb:action/PutItem" \
     --credentials arn:aws:iam::111122223333:role/data-transformation-tutorial-cli-APIGatewayRole-ABCDEFG \
     --request-templates '{"application/json":"{\"TableName\":\"data-transformation-tutorial-cli-ddb\",\"Item\":{\"id\":{\"N\":$input.json(\"$.id\")},\"type\":{\"S\":$input.json(\"$.type\")},\"price\":{\"N\":$input.json(\"$.price\")} }}"}'
   ```

1.  使用下列命令，為 `POST` 方法的成功呼叫建立方法回應。

   ```
   aws apigateway put-method-response --rest-api-id abc123 \
     --resource-id efg456 \
     --http-method POST \
     --status-code 200
   ```

1. 使用下列命令，為 `POST` 方法的成功呼叫建立整合回應。

   ```
   aws apigateway put-integration-response --rest-api-id abc123 \
     --resource-id efg456 \
     --http-method POST \
     --status-code 200 \
     --selection-pattern "" \
     --response-templates '{"application/json": "{\"message\": \"Your response was recorded at $context.requestTime\"}"}'
   ```

**測試 `POST` 方法**
+ 使用下列命令測試 `POST` 方法。

  ```
  aws apigateway test-invoke-method --rest-api-id abc123 \
    --resource-id efg456 \
    --http-method POST \
    --body '{\"id\": \"4\", \"type\": \"dog\", \"price\": \"321\"}'
  ```

  輸出將顯示成功訊息。

**刪除 CloudFormation 堆疊**
+ 使用下列命令來刪除您的 CloudFormation 資源。

  ```
  aws cloudformation delete-stack  --stack-name data-transformation-tutorial-cli
  ```

## 已完成的資料轉換 CloudFormation 範本
<a name="api-gateway-data-transformations-full-cfn-stack"></a>

下列範例是已完成的 CloudFormation 範本，其會使用 和 `POST`方法建立具有 `/pets` 資源的 API `GET`和 DynamoDB 資料表。
+ `GET` 方法將從 `http://petstore-demo-endpoint.execute-api.com/petstore/pets` HTTP 端點取得資料。輸出資料將根據 [API Gateway 中 REST API 的映射範本轉換](models-mappings.md)中的對應範本進行轉換。
+ `POST` 方法可讓使用者使用對應範本，將寵物資訊 `POST` 至 DynamoDB 資料表。

### 範本範例 CloudFormation
<a name="mapping-template-cfn-example"></a>

```
AWSTemplateFormatVersion: 2010-09-09
Description: A completed Amazon API Gateway REST API that uses non-proxy integration to POST to an Amazon DynamoDB table and non-proxy integration to GET transformed pets data.
Parameters:
  StageName:
    Type: String
    Default: v1
    Description: Name of API stage.
Resources:
  DynamoDBTable:
    Type: 'AWS::DynamoDB::Table'
    Properties:
      TableName: !Sub data-transformation-tutorial-complete
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: N
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      ProvisionedThroughput:
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5
  APIGatewayRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17		 	 	 
        Statement:
          - Action:
              - 'sts:AssumeRole'
            Effect: Allow
            Principal:
              Service:
                - apigateway.amazonaws.com
      Policies:
        - PolicyName: APIGatewayDynamoDBPolicy
          PolicyDocument:
            Version: 2012-10-17		 	 	 
            Statement:
              - Effect: Allow
                Action:
                  - 'dynamodb:PutItem'
                Resource: !GetAtt DynamoDBTable.Arn
  Api:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      Name: data-transformation-complete-api
      ApiKeySourceType: HEADER
  PetsResource:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref Api
      ParentId: !GetAtt Api.RootResourceId
      PathPart: 'pets'
  PetsMethodGet:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref PetsResource
      HttpMethod: GET
      ApiKeyRequired: false
      AuthorizationType: NONE
      Integration:
        Type: HTTP
        Credentials: !GetAtt APIGatewayRole.Arn
        IntegrationHttpMethod: GET
        Uri: http://petstore-demo-endpoint.execute-api.com/petstore/pets/
        PassthroughBehavior: WHEN_NO_TEMPLATES
        IntegrationResponses:
          - StatusCode: '200'
            ResponseTemplates:
              application/json: "#set($inputRoot = $input.path(\"$\"))\n[\n#foreach($elem in $inputRoot)\n {\n  \"description\": \"Item $elem.id is a $elem.type\",\n  \"askingPrice\": \"$elem.price\"\n }#if($foreach.hasNext),#end\n\n#end\n]"
      MethodResponses:
        - StatusCode: '200'
  PetsMethodPost:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      RestApiId: !Ref Api
      ResourceId: !Ref PetsResource
      HttpMethod: POST
      ApiKeyRequired: false
      AuthorizationType: NONE
      Integration:
        Type: AWS
        Credentials: !GetAtt APIGatewayRole.Arn
        IntegrationHttpMethod: POST
        Uri: arn:aws:apigateway:us-west-1:dynamodb:action/PutItem
        PassthroughBehavior: NEVER
        RequestTemplates: 
          application/json: "{\"TableName\":\"data-transformation-tutorial-complete\",\"Item\":{\"id\":{\"N\":$input.json(\"$.id\")},\"type\":{\"S\":$input.json(\"$.type\")},\"price\":{\"N\":$input.json(\"$.price\")} }}"
        IntegrationResponses:
          - StatusCode: 200
            ResponseTemplates:
              application/json: "{\"message\": \"Your response was recorded at $context.requestTime\"}"
      MethodResponses:
        - StatusCode: '200'

  ApiDeployment:
    Type: 'AWS::ApiGateway::Deployment'
    DependsOn:
      - PetsMethodGet
    Properties:
      RestApiId: !Ref Api
      StageName: !Sub '${StageName}'
Outputs:
  ApiId:
    Description: API ID for CLI commands
    Value: !Ref Api
  ResourceId:
    Description: /pets resource ID for CLI commands
    Value: !Ref PetsResource
  ApiRole:
    Description: Role ID to allow API Gateway to put and scan items in DynamoDB table
    Value: !Ref APIGatewayRole
  DDBTableName:
    Description: DynamoDB table name
    Value: !Ref DynamoDBTable
```

# 使用變數進行 API Gateway 映射範本轉換的範例
<a name="api-gateway-mapping-variable-examples"></a>

以下範例說明如何在映射範本中使用 `$context`、`input` 和 `util` 變數。您可以使用模擬整合或 Lambda 非代理整合，將輸入事件傳回至 API Gateway。如需資料轉換支援的所有變數的清單，請參閱 [用於 API Gateway 資料轉換的變數](api-gateway-mapping-template-reference.md)。

## 範例 1：將多個 `$context` 變數傳遞至整合端點
<a name="context-variables-template-example"></a>

以下範例顯示一個映射範本，其會將傳入的 `$context` 變數映射至整合請求承載中名稱稍有不同的後端變數：

```
{
    "stage" : "$context.stage",
    "request_id" : "$context.requestId",
    "api_id" : "$context.apiId",
    "resource_path" : "$context.resourcePath",
    "resource_id" : "$context.resourceId",
    "http_method" : "$context.httpMethod",
    "source_ip" : "$context.identity.sourceIp",
    "user-agent" : "$context.identity.userAgent",
    "account_id" : "$context.identity.accountId",
    "api_key" : "$context.identity.apiKey",
    "caller" : "$context.identity.caller",
    "user" : "$context.identity.user",
    "user_arn" : "$context.identity.userArn"
}
```

此映射範本的輸出應如下所示：

```
{
  stage: 'prod',
  request_id: 'abcdefg-000-000-0000-abcdefg',
  api_id: 'abcd1234',
  resource_path: '/',
  resource_id: 'efg567',
  http_method: 'GET',
  source_ip: '192.0.2.1',
  user-agent: 'curl/7.84.0',
  account_id: '111122223333',
  api_key: 'MyTestKey',
  caller: 'ABCD-0000-12345',
  user: 'ABCD-0000-12345',
  user_arn: 'arn:aws:sts::111122223333:assumed-role/Admin/carlos-salazar'
}
```

其中一個變數是 API 金鑰。此範例假設該方法需要 API 金鑰。

## 範例 2：透過 JSON 承載將所有請求參數傳遞至整合端點
<a name="input-examples-mapping-templates"></a>

下列範例會透過 JSON 承載將所有請求參數 (包含 `path`、`querystring` 和 `header`) 傳遞至整合端點：

```
#set($allParams = $input.params())
{
  "params" : {
    #foreach($type in $allParams.keySet())
    #set($params = $allParams.get($type))
    "$type" : {
      #foreach($paramName in $params.keySet())
      "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
      #if($foreach.hasNext),#end
      #end
    }
    #if($foreach.hasNext),#end
    #end
  }
}
```

如果請求具有下列輸入參數：
+ 名為 `myparam` 的路徑參數
+ 查詢字串參數 `querystring1=value1,value2`
+ 標頭 `"header1" : "value1"`。

此映射範本的輸出應如下所示：

```
{"params":{"path":{"example2":"myparamm"},"querystring":{"querystring1":"value1,value2"},"header":{"header1":"value1"}}}
```

## 範例 3：將方法請求的子區段傳遞至整合端點
<a name="input-example-json-mapping-template"></a>

 下列範例使用輸入參數 `name` 僅擷取 `name` 參數，並使用輸入參數 `input.json('$')` 擷取方法請求的整個內文：

```
{
    "name" : "$input.params('name')",
    "body" : $input.json('$') 
}
```

對於包含查詢字串參數 `name=Bella&type=dog` 和下列內文的請求：

```
{
    "Price" : "249.99",
    "Age": "6"
}
```

此映射範本的輸出應如下所示：

```
{
    "name" : "Bella",
    "body" : {"Price":"249.99","Age":"6"}
}
```

此映射範本會移除查詢字串參數 `type=dog`。

 如果 JSON 輸入包含 JavaScript 無法剖析的非逸出字元，則 API Gateway 可能會傳回 400 回應。套用 `$util.escapeJavaScript($input.json('$'))` 以確保 JSON 輸入可正確剖析。

套用 `$util.escapeJavaScript($input.json('$'))` 的前一個範例如下所示：

```
{
    "name" : "$input.params('name')",
    "body" : "$util.escapeJavaScript($input.json('$'))"
}
```

在這種情況下，此映射範本的輸出應如下所示：

```
{
    "name" : "Bella",
    "body": {"Price":"249.99","Age":"6"}
}
```

## 範例 4：使用 JSONPath 表達式將方法請求的子區段傳遞至整合端點
<a name="input-example-inputs-mapping-template"></a>

下列範例使用 JSONPath 表達式，僅從請求內文擷取輸入參數 `name` 和 `Age`：

```
{
    "name" : "$input.params('name')",
    "body" : $input.json('$.Age')  
}
```

對於包含查詢字串參數 `name=Bella&type=dog` 和下列內文的請求：

```
{
    "Price" : "249.99",
    "Age": "6"
}
```

此映射範本的輸出應如下所示：

```
{
    "name" : "Bella",
    "body" : "6"
}
```

此映射範本會從內文中移除查詢字串參數 `type=dog` 和 `Price` 欄位。

 如果方法請求承載包含 JavaScript 無法剖析的非逸出字元，API Gateway 可能會傳回 `400` 回應。套用 `$util.escapeJavaScript()` 以確保 JSON 輸入可正確剖析。

套用 `$util.escapeJavaScript($input.json('$.Age'))` 的前一個範例如下所示：

```
{
    "name" : "$input.params('name')",
    "body" : "$util.escapeJavaScript($input.json('$.Age'))" 
}
```

在這種情況下，此映射範本的輸出應如下所示：

```
{
    "name" : "Bella",
    "body": "\"6\""
}
```

## 範例 5：使用 JSONPath 表達式將有關方法請求的資訊傳遞至整合端點
<a name="input-example-request-and-response"></a>

下列範例使用 `$input.params()`、`$input.path()` 和 `$input.json()` 將有關方法請求的資訊傳送至整合端點。此映射範本使用 `size()` 方法來提供清單中的元素數量。

```
{
    "id" : "$input.params('id')",
    "count" : "$input.path('$.things').size()",
    "things" : $input.json('$.things')
}
```

對於包含路徑參數 `123` 和下列內文的請求：

```
{
      "things": {
            "1": {},
            "2": {},
            "3": {}
      }
}
```

此映射範本的輸出應如下所示：

```
{"id":"123","count":"3","things":{"1":{},"2":{},"3":{}}}
```

 如果方法請求承載包含 JavaScript 無法剖析的非逸出字元，API Gateway 可能會傳回 `400` 回應。套用 `$util.escapeJavaScript()` 以確保 JSON 輸入可正確剖析。

套用 `$util.escapeJavaScript($input.json('$.things'))` 的前一個範例如下所示：

```
{
     "id" : "$input.params('id')",
     "count" : "$input.path('$.things').size()",
     "things" : "$util.escapeJavaScript($input.json('$.things'))"
}
```

此映射範本的輸出應如下所示：

```
{"id":"123","count":"3","things":"{\"1\":{},\"2\":{},\"3\":{}}"}
```

# 用於 API Gateway 資料轉換的變數
<a name="api-gateway-mapping-template-reference"></a>

建立參數映射時，您可以使用內容變數作為資料來源。建立映射範本轉換時，您可以在您使用 [Velocity 範本語言 (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) 編寫的指令碼中使用內容變數、輸入和 util 變數。如需使用這些參考變數的映射範本範例，請參閱 [使用變數進行 API Gateway 映射範本轉換的範例](api-gateway-mapping-variable-examples.md)。

如需存取記錄的參考變數清單，請參閱 [API Gateway 存取記錄的變數](api-gateway-variables-for-access-logging.md)。

## 資料轉換的內容變數
<a name="context-variable-reference"></a>

您可以使用下列區分大小寫的 `$context` 變數進行資料轉換。


| 參數 | Description | 
| --- | --- | 
| \$1context.accountId |  API 擁有者 AWS 的帳戶 ID。  | 
| \$1context.apiId |  API Gateway 指派給您 API 的識別碼。  | 
| \$1context.authorizer.claims.property |  成功驗證方法發起人之後，從 Amazon Cognito 使用者集區傳回之宣告的屬性。如需詳細資訊，請參閱 [使用 Amazon Cognito 使用者集區做為授權方，藉以控制對 REST API 的存取](apigateway-integrate-with-cognito.md)。  呼叫 `$context.authorizer.claims` 會傳回 null。   | 
| \$1context.authorizer.principalId |  與用戶端所傳送並從 API Gateway Lambda 授權方 (先前稱作自訂授權方) 所傳回之字符相關聯的主要使用者身分。如需詳細資訊，請參閱 [使用 API Gateway Lambda 授權方](apigateway-use-lambda-authorizer.md)。  | 
| \$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"` 字串。 對於*屬性*，唯一支援的特殊字元是底線 `(_)` 字元。 如需詳細資訊，請參閱[使用 API Gateway Lambda 授權方](apigateway-use-lambda-authorizer.md)。  | 
| \$1context.awsEndpointRequestId |   AWS 端點的請求 ID。  | 
| \$1context.deploymentId | API 部署的 ID。 | 
| \$1context.domainName |  用來調用 API 的完整網域名稱。這應該與傳入的 `Host` 標頭相同。  | 
| \$1context.domainPrefix |  `$context.domainName` 的第一個標籤。  | 
| \$1context.error.message |  包含 API Gateway 錯誤訊息的字串。此變數只能用於 Velocity 範本語言引擎無法處理的 [GatewayResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_GatewayResponse.html) 本文映射範本及存取記錄中的簡單變數替換。如需詳細資訊，請參閱[使用 CloudWatch 指標監控 WebSocket API 執行](apigateway-websocket-api-logging.md)及[設定閘道回應以自訂錯誤回應](api-gateway-gatewayResponse-definition.md#customize-gateway-responses)。  | 
| \$1context.error.messageString | \$1context.error.message 的引用值，即 "\$1context.error.message"。 | 
| \$1context.error.responseType |  [GatewayResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_GatewayResponse.html) 的[類型](https://docs.aws.amazon.com/apigateway/latest/api/API_GatewayResponse.html#responseType)。此變數只能用於 Velocity 範本語言引擎無法處理的 [GatewayResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_GatewayResponse.html) 本文映射範本及存取記錄中的簡單變數替換。如需詳細資訊，請參閱[使用 CloudWatch 指標監控 WebSocket API 執行](apigateway-websocket-api-logging.md)及[設定閘道回應以自訂錯誤回應](api-gateway-gatewayResponse-definition.md#customize-gateway-responses)。  | 
| \$1context.error.validationErrorString |  字串，其中包含詳細的驗證錯誤訊息。  | 
| \$1context.extendedRequestId | API Gateway 產生和指派給 API 請求的延伸 ID。延伸請求 ID 包含有助於偵錯和疑難排解的資訊。 | 
| \$1context.httpMethod |  使用的 HTTP 方法。有效值包含：`DELETE`、`GET`、`HEAD`、`OPTIONS`、`PATCH`、`POST` 和 `PUT`。  | 
| \$1context.identity.accountId |  與請求相關聯的 AWS 帳戶 ID。  | 
| \$1context.identity.apiKey |  對於需要 API 金鑰的 API 方法，此變數是與方法請求相關聯的 API 金鑰。對於不需要 API 金鑰的方法，此變數為 null。如需詳細資訊，請參閱 [API Gateway 中 REST API 的用量計畫和 API 金鑰](api-gateway-api-usage-plans.md)。  | 
| \$1context.identity.apiKeyId | 與需要 API 金鑰之 API 請求相關聯的 API 金鑰 ID。 | 
| \$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)。  | 
| \$1context.identity.sourceIp |  對 API Gateway 端點提出請求之即時 TCP 連線的來源 IP 位址。  | 
| \$1context.identity.clientCert.clientCertPem |  用戶端在交互 TLS 驗證期間所呈現的 PEM 編碼用戶端憑證。當用戶端使用已啟用交互 TLS 的自訂網域名稱存取 API 時會顯示。只有在交互 TLS 驗證失敗時才會顯示在存取記錄檔中。  | 
| \$1context.identity.clientCert.subjectDN |  用戶端提供之憑證主體的辨別名稱。當用戶端使用已啟用交互 TLS 的自訂網域名稱存取 API 時會顯示。只有在交互 TLS 驗證失敗時才會顯示在存取記錄檔中。  | 
| \$1context.identity.clientCert.issuerDN |  用戶端提供之憑證發行者的辨別名稱。當用戶端使用已啟用交互 TLS 的自訂網域名稱存取 API 時會顯示。只有在交互 TLS 驗證失敗時才會顯示在存取記錄檔中。  | 
| \$1context.identity.clientCert.serialNumber |  憑證的序號。當用戶端使用已啟用交互 TLS 的自訂網域名稱存取 API 時會顯示。只有在交互 TLS 驗證失敗時才會顯示在存取記錄檔中。  | 
| \$1context.identity.clientCert.validity.notBefore |  憑證無效之前的日期。當用戶端使用已啟用交互 TLS 的自訂網域名稱存取 API 時會顯示。只有在交互 TLS 驗證失敗時才會顯示在存取記錄檔中。  | 
| \$1context.identity.clientCert.validity.notAfter |  憑證無效之後的日期。當用戶端使用已啟用交互 TLS 的自訂網域名稱存取 API 時會顯示。只有在交互 TLS 驗證失敗時才會顯示在存取記錄檔中。  | 
|  \$1context.identity.vpcId | 對 API Gateway 端點提出請求之 VPC 的 VPC ID。 | 
|  \$1context.identity.vpceId |  對 API Gateway 端點提出請求之 VPC 端點的 VPC 端點 ID。只會在您擁有私有 API 時顯示。  | 
| \$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)。如需詳細資訊，請參閱[https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html)。  | 
| \$1context.isCanaryRequest |  如果請求導向 Canary，則傳回 `true`；如果請求未導向 Canary，則傳回 `false`。只會在啟用 Canary 時顯示。 | 
| \$1context.path | 請求路徑。例如，對於 https://\$1rest-api-id\$1.execute-api.\$1region\$1.amazonaws.com/\$1stage\$1/root/child 的非代理請求 URL，\$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 |  請求的 ID。用戶端可以覆寫此請求 ID。使用 `$context.extendedRequestId` 即可取得 API Gateway 產生的唯一請求 ID。  | 
| \$1context.requestOverride.header.header\$1name |  請求標題會覆寫。如果此參數已經定義，它包含要使用的標頭 (而不是在 **Integration Request (整合請求)** 窗格中定義的 **HTTP Headers (HTTP 標頭)**)。如需詳細資訊，請參閱 [覆寫 API Gateway 中 REST API 的 API 請求和回應參數及狀態碼](apigateway-override-request-response-parameters.md)。  | 
| \$1context.requestOverride.path.path\$1name |  請求路徑會覆寫。如果此參數已經定義，它包含要使用的請求路徑 (而不是在 **Integration Request (整合請求)** 窗格中定義的 **URL Path Parameters (URL 路徑參數)**)。如需詳細資訊，請參閱 [覆寫 API Gateway 中 REST API 的 API 請求和回應參數及狀態碼](apigateway-override-request-response-parameters.md)。  | 
| \$1context.requestOverride.querystring.querystring\$1name |  請求查詢字串會覆寫。如果此參數已經定義，它包含要使用的請求查詢字串 (而不是在 **Integration Request (整合請求) ** 窗格中定義的 **URL Query String (URL 查詢字串)**)。如需詳細資訊，請參閱 [覆寫 API Gateway 中 REST API 的 API 請求和回應參數及狀態碼](apigateway-override-request-response-parameters.md)。  | 
| \$1context.responseOverride.header.header\$1name | 回應標題會覆寫。如果此參數已經定義，它包含要傳回的標頭 (而不是在 Integration Response (整合回應) 窗格中定義為 Default mapping (預設映射) 的 Response header (回應標頭))。如需詳細資訊，請參閱 [覆寫 API Gateway 中 REST API 的 API 請求和回應參數及狀態碼](apigateway-override-request-response-parameters.md)。 | 
| \$1context.responseOverride.status | 回應狀態碼會覆寫。如果此參數已經定義，它包含要傳回的狀態碼 (而不是在 Integration Response (整合回應) 窗格中定義為 Default mapping (預設映射) 的 Method response status (方法回應狀態))。如需詳細資訊，請參閱 [覆寫 API Gateway 中 REST API 的 API 請求和回應參數及狀態碼](apigateway-override-request-response-parameters.md)。 | 
| \$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.resourceId |  API Gateway 指派給您的資源的識別碼。  | 
| \$1context.resourcePath |  您資源的路徑。例如，對於非代理請求 URI `https://{rest-api-id}.execute-api.{region}.amazonaws.com/{stage}/root/child`，`$context.resourcePath` 值是 `/root/child`。如需詳細資訊，請參閱 [教學：建立具有 HTTP 非代理整合的 REST API](api-gateway-create-api-step-by-step.md)。  | 
| \$1context.stage |  API 請求的部署階段 (例如，`Beta` 或 `Prod`)。  | 
| \$1context.wafResponseCode |  從 [AWS WAF](https://docs.aws.amazon.com/waf/latest/developerguide/waf-chapter.html) 收到的回應：`WAF_ALLOW` 或 `WAF_BLOCK`。若該階段與 web ACL 不相關聯，將不會設定此值。如需詳細資訊，請參閱 [使用 AWS WAF 來保護 API Gateway APIs 中的 REST API](apigateway-control-access-aws-waf.md)。  | 
| \$1context.webaclArn |  Web ACL 的完整 ARN，用來決定是否允許或封鎖請求。若該階段與 web ACL 不相關聯，將不會設定此值。如需詳細資訊，請參閱[使用 AWS WAF 來保護 API Gateway APIs 中的 REST API](apigateway-control-access-aws-waf.md)。  | 

## 輸入變數
<a name="input-variable-reference"></a>

您可以使用下列區分大小寫的 `$input` 變數來參考方法請求承載和方法請求參數。可使用以下函數：


| 變數和函數 | 描述 | 
| --- | --- | 
| \$1input.body |  傳回原始請求承載做為字串。您可以使用 `$input.body` 保留整個浮點數，例如 `10.00`。 | 
| \$1input.json(x) | 此函數會評估 JSONPath 表達式，並傳回結果作為 JSON 字串。 例如，`$input.json('$.pets')` 會傳回代表 `pets` 結構的 JSON 字串。 如需 JSONPath 的詳細資訊，請參閱 [JSONPath](https://goessner.net/articles/JsonPath/) 或[適用於 Java 的 JSONPath](https://github.com/json-path/JsonPath)。 | 
| \$1input.params() |  傳回所有請求參數的映射。我們建議您使用 `$util.escapeJavaScript` 清理結果，以避免潛在的注入攻擊。為了完全控制請求清理，請使用沒有模板的代理整合，並處理整合中的請求清理。 | 
| \$1input.params(x) | 從路徑、查詢字串或標頭值 (以此順序搜尋) 傳回方法請求參數值，而參數名稱字串為 `x`。我們建議您使 `$util.escapeJavaScript` 用清理參數，以避免潛在的注入攻擊。為了完全控制參數清理，請使用沒有模板的代理整合，並處理整合中的請求清理。 | 
| \$1input.path(x) | 採用 JSONPath 表達式字串 (`x`)，並傳回結果的 JSON 物件呈現。這可讓您存取和運用 [Apache Velocity 範本語言 (VTL)](https://velocity.apache.org/engine/devel/vtl-reference.html) 中原生承載的元素。 例如，如果表達式 `$input.path('$.pets')` 傳回如下物件： <pre>[<br />  { <br />    "id": 1, <br />    "type": "dog", <br />    "price": 249.99 <br />  }, <br />  { <br />    "id": 2, <br />    "type": "cat", <br />    "price": 124.99 <br />  }, <br />  { <br />    "id": 3, <br />    "type": "fish", <br />    "price": 0.99 <br />  } <br />]</pre> `$input.path('$.pets').size()` 會傳回 `"3"`。 如需 JSONPath 的詳細資訊，請參閱 [JSONPath](https://goessner.net/articles/JsonPath/) 或[適用於 Java 的 JSONPath](https://github.com/json-path/JsonPath)。 | 

## 階段變數
<a name="stagevariables-template-reference"></a>

您可以使用下列階段變數作為方法整合中 ARN 和 URL 的預留位置。如需詳細資訊，請參閱[在 API Gateway 中使用 REST API 的階段變數](stage-variables.md)。


| 語法 | Description | 
| --- | --- | 
| \$1stageVariables.variable\$1name、\$1stageVariables['variable\$1name'] 或 \$1\$1stageVariables['variable\$1name']\$1  |  *variable\$1name* 代表階段變數名稱。  | 

## Util 變數
<a name="util-template-reference"></a>

您可以使用下列區分大小寫的 `$util` 變數，針對映射範本使用公用程式函數。除非特別指定，否則預設字元集為 UTF-8。


| 函數 | 描述 | 
| --- | --- | 
| \$1util.escapeJavaScript() |  使用 JavaScript 字串規則來逸出字串中的字元。  此函數會將任何一般單引號 (`'`) 轉換為逸出單引號 (`\'`)。不過，逸出單引號不適用於 JSON。因此，將此函數的輸出用於 JSON 屬性時，您必須將任何逸出單引號 (`\'`) 轉換為一般單引號 (`'`)。下列範例顯示這種情況： <pre> "input" : "$util.escapeJavaScript(data).replaceAll("\\'","'")"</pre>   | 
| \$1util.parseJson() |   採用「字串化」JSON，並傳回結果的物件呈現。您可以使用此函數的結果，來存取和運用 Apache Velocity 範本語言 (VTL) 中原生承載的元素。例如，如果您有下列承載： <pre>{"errorMessage":"{\"key1\":\"var1\",\"key2\":{\"arr\":[1,2,3]}}"}</pre>  並使用下列映射範本  <pre>#set ($errorMessageObj = $util.parseJson($input.path('$.errorMessage')))<br />{<br />   "errorMessageObjKey2ArrVal" : $errorMessageObj.key2.arr[0]<br />}<br /></pre> 您將會收到下列輸出： <pre>{<br />   "errorMessageObjKey2ArrVal" : 1<br />}<br /></pre>  | 
| \$1util.urlEncode() | 將字串轉換為 "application/x-www-form-urlencoded" 格式。 | 
| \$1util.urlDecode() | 解碼 "application/x-www-form-urlencoded" 字串。 | 
| \$1util.base64Encode() | 將資料編碼為 base64 編碼字串。 | 
| \$1util.base64Decode() | 解碼 base64 編碼字串中的資料。 | 

# API Gateway 中 REST API 的閘道回應
<a name="api-gateway-gatewayResponse-definition"></a>

 閘道回應以 API Gateway 定義的回應類型識別。回應包含 HTTP 狀態碼、一組由參數對應指定的額外標頭，以及非 [VTL](https://velocity.apache.org/engine/devel/vtl-reference.html) 對應範本所產生的承載。

 在 API Gateway REST API 中，閘道回應以 [GatewayResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_GatewayResponse.html) 表示。在 OpenAPI 中，`GatewayResponse` 執行個體是以 [x-amazon-apigateway-gateway-responses.gatewayResponse](api-gateway-swagger-extensions-gateway-responses.gatewayResponse.md) 延伸來加以說明。

若要啟用閘道回應，您可以在 API 層級設定[支援回應類型](supported-gateway-response-types.md)的閘道回應。每當 API Gateway 傳回該類型的回應時，就會套用閘道回應中定義的標頭映射與承載映射範本，將映射的結果傳回給 API 發起人。

 在下一節中，我們將示範如何使用 API Gateway 主控台與 API Gateway REST API 來設定閘道回應。

## 設定閘道回應以自訂錯誤回應
<a name="customize-gateway-responses"></a>

如果 API Gateway 無法處理傳入請求，則它會傳送錯誤回應給用戶端，但不會將請求轉送到整合後端。錯誤回應預設包含一則簡短的描述性錯誤訊息。例如，如果您嘗試在未定義的 API 資源上呼叫操作，您會收到 `{ "message": "Missing Authentication Token" }` 訊息的錯誤回應。如果您是初次使用 API Gateway，您可能會發現很難了解實際發生錯誤的原因。

 針對一些錯誤回應，API Gateway 允許 API 開發人員進行自訂以傳回不同格式的回應。在 `Missing Authentication Token` 範例中，您可以將含有可能原因的提示新增至原始回應承載，如下列範例所示：`{"message":"Missing Authentication Token", "hint":"The HTTP method or resources may not be supported."}`。

 當您的 API 在外部交換和 AWS 雲端之間協調時，您可以使用 VTL 映射範本進行整合請求或整合回應，將承載從一個格式映射到另一個格式。不過，VTL 對應範本僅適用於具有成功回應的有效請求。

針對無效的請求，API Gateway 會完全略過整合並傳回錯誤回應。您必須使用自訂，將錯誤回應轉譯成 Exchange 相容的格式。在本例中，會在只支援簡單變數替換的非 VTL 對應範本中轉譯自訂。

 將 API Gateway 所產生的錯誤回應一般化為 API Gateway 所產生的任何回應，此操作稱為*閘道回應*。這可區分 API Gateway 所產生的回應與整合回應。閘道回應對應範本可存取 `$context` 變數值與 `$stageVariables` 屬性值，以及 `method.request.param-position.param-name` 格式的方法請求參數。

如需 `$context` 變數的詳細資訊，請參閱「[資料轉換的內容變數](api-gateway-mapping-template-reference.md#context-variable-reference)」。如需有關 `$stageVariables` 的詳細資訊，請參閱 [階段變數](api-gateway-mapping-template-reference.md#stagevariables-template-reference)。如需有關方法請求參數的詳細資訊，請參閱 [輸入變數](api-gateway-mapping-template-reference.md#input-variable-reference)。

**Topics**
+ [設定閘道回應以自訂錯誤回應](#customize-gateway-responses)
+ [使用 API Gateway 主控台設定 REST API 的閘道回應](set-up-gateway-response-using-the-console.md)
+ [使用 API Gateway REST API 設定閘道回應](set-up-gateway-response-using-the-api.md)
+ [設定 OpenAPI 中的閘道回應自訂](set-up-gateway-responses-in-swagger.md)
+ [API Gateway 的閘道回應類型](supported-gateway-response-types.md)

# 使用 API Gateway 主控台設定 REST API 的閘道回應
<a name="set-up-gateway-response-using-the-console"></a>

下列範例顯示如何使用 API Gateway 主控台設定 REST API 的閘道回應 

**使用 API Gateway 主控台自訂閘道回應**

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

1. 選擇 REST API。

1. 在主導覽窗格中，選擇**閘道資源**。

1. 選擇回應類型，然後選擇**編輯**。在此逐步說明中，我們使用**遺漏身分驗證權杖**作為範例。

1. 您可以變更 API Gateway 所產生的**狀態碼**，以傳回符合您的 API 需求的不同狀態碼。在此範例中，自訂會將狀態碼從預設值 (`403`) 變更為 `404`，因為當用戶端呼叫可視為找不到的不支援或無效資源時會出現此錯誤訊息。

1. 若要傳回自訂標頭，請在**回應標頭**下，選擇**新增標頭**。為了方便說明，我們新增下列自訂標頭：

   ```
   Access-Control-Allow-Origin:'a.b.c'
   x-request-id:method.request.header.x-amzn-RequestId
   x-request-path:method.request.path.petId
   x-request-query:method.request.querystring.q
   ```

   在上述標頭對應中，靜態網域名稱 (`'a.b.c'`) 會對應到 `Allow-Control-Allow-Origin` 標頭以允許 API 的 CORS 存取；`x-amzn-RequestId` 的輸入請求標頭會對應到回應中的 `request-id`；傳入請求的 `petId` 路徑變數會對應到回應中的 `request-path` 標頭；而原始請求的 `q` 查詢參數會對應到回應的 `request-query` 標頭。

1. 在**回應範本**下，將**內容類型**保持為 `application/json`，然後在**範本內文**編輯器中輸入下列內文對應範本：

   ```
   {
        "message":"$context.error.messageString",
        "type": "$context.error.responseType",
        "statusCode": "'404'",
        "stage": "$context.stage",
        "resourcePath": "$context.resourcePath",
        "stageVariables.a": "$stageVariables.a"
   }
   ```

   此範例示範如何將 `$context` 與 `$stageVariables` 屬性對應到閘道回應內文的屬性。

1. 選擇**儲存變更**。

1. 將 API 部署到新的或現有的階段。

透過呼叫下列 CURL 命令進行閘道回應測試，並假設映射 API 方法的調用 URL 為 `https://o81lxisefl.execute-api.us-east-1.amazonaws.com/custErr/pets/{petId}`：

```
curl -v -H 'x-amzn-RequestId:123344566' https://o81lxisefl.execute-api.us-east-1.amazonaws.com/custErr/pets/5/type?q=1
```

由於額外查詢字串參數 `q=1` 與 API 不相容，因此會從指定的閘道回應傳回錯誤。您應該取得類似如下的閘道回應：

```
> GET /custErr/pets/5?q=1 HTTP/1.1
Host: o81lxisefl.execute-api.us-east-1.amazonaws.com
User-Agent: curl/7.51.0
Accept: */*
 
HTTP/1.1 404 Not Found
Content-Type: application/json
Content-Length: 334
Connection: keep-alive
Date: Tue, 02 May 2017 03:15:47 GMT
x-amzn-RequestId: 123344566
Access-Control-Allow-Origin: a.b.c
x-amzn-ErrorType: MissingAuthenticationTokenException
header-1: static
x-request-query: 1
x-request-path: 5
X-Cache: Error from cloudfront
Via: 1.1 441811a054e8d055b893175754efd0c3.cloudfront.net (CloudFront)
X-Amz-Cf-Id: nNDR-fX4csbRoAgtQJ16u0rTDz9FZWT-Mk93KgoxnfzDlTUh3flmzA==
 
{
     "message":"Missing Authentication Token",
     "type": MISSING_AUTHENTICATION_TOKEN,
     "statusCode": '404',
     "stage": custErr,
     "resourcePath": /pets/{petId},
     "stageVariables.a": a
}
```

上述範例假設 API 後端是[寵物店](http://petstore-demo-endpoint.execute-api.com/petstore/pets)，而且 API 已定義階段變數 `a`。

# 使用 API Gateway REST API 設定閘道回應
<a name="set-up-gateway-response-using-the-api"></a>

 使用 API Gateway REST API 自訂閘道回應之前，您必須已建立 API 並已取得其識別符。若要擷取 API 識別符，您可以遵循 [restapi:gateway-responses](https://docs.aws.amazon.com/apigateway/latest/api/API_GetGatewayResponses.html) 連結關係並查看結果。

**使用 API Gateway REST API 自訂閘道回應**

1. 若要覆寫整個 [GatewayResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_GatewayResponse.html) 執行個體，請呼叫 [gatewayresponse:put](https://docs.aws.amazon.com/apigateway/latest/api/API_PutGatewayResponse.html) 動作。在 URL 路徑參數中指定所需的 [responseType](https://docs.aws.amazon.com/apigateway/latest/api/API_GatewayResponse.html#responseType)，並在請求酬載中提供 [statusCode](https://docs.aws.amazon.com/apigateway/latest/api/API_GatewayResponse.html#statusCode)、[responseParameters](https://docs.aws.amazon.com/apigateway/latest/api/API_GatewayResponse.html#responseParameters) 及 [responseTemplates](https://docs.aws.amazon.com/apigateway/latest/api/API_GatewayResponse.html#responseTemplates) 映射。

1. 若要更新 `GatewayResponse` 執行個體的一部分，請呼叫 [gatewayresponse:update](https://docs.aws.amazon.com/apigateway/latest/api/API_UpdateGatewayResponse.html) 動作。在 URL 路徑參數中指定所需的 `responseType`，並在請求承載中提供您需要的個別 `GatewayResponse` 屬性，例如 `responseParameters` 或 `responseTemplates` 映射。

# 設定 OpenAPI 中的閘道回應自訂
<a name="set-up-gateway-responses-in-swagger"></a>

 您可以在 API 根層級使用 `x-amazon-apigateway-gateway-responses` 延伸，來自訂 OpenAPI 中的閘道回應。下列 OpenAPI 定義示範如何自訂 `MISSING_AUTHENTICATION_TOKEN` 類型的 [GatewayResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_GatewayResponse.html)。

```
  "x-amazon-apigateway-gateway-responses": {
    "MISSING_AUTHENTICATION_TOKEN": {
      "statusCode": 404,
      "responseParameters": {
        "gatewayresponse.header.x-request-path": "method.input.params.petId",
        "gatewayresponse.header.x-request-query": "method.input.params.q",
        "gatewayresponse.header.Access-Control-Allow-Origin": "'a.b.c'",
        "gatewayresponse.header.x-request-header": "method.input.params.Accept"
      },
      "responseTemplates": {
        "application/json": "{\n     \"message\": $context.error.messageString,\n     \"type\":  \"$context.error.responseType\",\n     \"stage\":  \"$context.stage\",\n     \"resourcePath\":  \"$context.resourcePath\",\n     \"stageVariables.a\":  \"$stageVariables.a\",\n     \"statusCode\": \"'404'\"\n}"
      }
    }
```

在此範例中，自訂會將狀態碼從預設值 (`403`) 變更為 `404`。它也會將 `application/json` 媒體類型的四個標頭參數與一個內文對應範本新增至閘道回應。

# API Gateway 的閘道回應類型
<a name="supported-gateway-response-types"></a>

 API Gateway 公開下列 API 開發人員可自訂的閘道回應。


| 閘道回應類型 | 預設狀態碼 | 描述 | 
| --- | --- | --- | 
| ACCESS\$1DENIED | 403 | 授權失敗的閘道回應；例如，自訂或 Amazon Cognito 授權方拒絕存取時。如果未指定回應類型，此回應預設為 `DEFAULT_4XX` 類型。 | 
| API\$1CONFIGURATION\$1ERROR | 500 | 無效 API 組態的閘道回應，包括提交的端點地址無效、制定二進位支援時二進位資料的 Base64 編碼失敗，或整合回應映射不符合任何範本且未設定預設範本。如果未指定回應類型，此回應預設為 `DEFAULT_5XX` 類型。 | 
| AUTHORIZER\$1CONFIGURATION\$1ERROR | 500 | 無法連線到自訂或 Amazon Cognito 授權方時的閘道回應。如果未指定回應類型，此回應預設為 `DEFAULT_5XX` 類型。 | 
| AUTHORIZER\$1FAILURE | 500 | 自訂或 Amazon Cognito 授權方無法驗證發起人時的閘道回應。如果未指定回應類型，此回應預設為 `DEFAULT_5XX` 類型。 | 
| BAD\$1REQUEST\$1PARAMETERS | 400 | 根據啟用的請求驗證程式無法驗證請求參數時的閘道回應。如果未指定回應類型，此回應預設為 `DEFAULT_4XX` 類型。 | 
| BAD\$1REQUEST\$1BODY | 400 | 根據啟用的請求驗證程式無法驗證請求內文時的閘道回應。如果未指定回應類型，此回應預設為 `DEFAULT_4XX` 類型。 | 
| DEFAULT\$14XX |  Null | 狀態碼為 `4XX` 之未指定回應類型的預設閘道回應。變更此後援閘道回應的狀態碼會將所有其他 `4XX` 回應的狀態碼變更為新的值。將此狀態碼重設為 Null 會將所有其他 `4XX` 回應的狀態碼還原成其原始值。  [AWS WAF 自訂回應](https://docs.aws.amazon.com/waf/latest/developerguide/waf-custom-request-response.html)優先於自訂閘道回應。   | 
| DEFAULT\$15XX | Null | 狀態碼為 `5XX` 之未指定回應類型的預設閘道回應。變更此後援閘道回應的狀態碼會將所有其他 `5XX` 回應的狀態碼變更為新的值。將此狀態碼重設為 Null 會將所有其他 `5XX` 回應的狀態碼還原成其原始值。 | 
| EXPIRED\$1TOKEN | 403 |  AWS 身分驗證字符過期錯誤的閘道回應。如果未指定回應類型，此回應預設為 `DEFAULT_4XX` 類型。 | 
| INTEGRATION\$1FAILURE | 504 | 整合失敗錯誤的閘道回應。如果未指定回應類型，此回應預設為 `DEFAULT_5XX` 類型。 | 
| INTEGRATION\$1TIMEOUT | 504 | 整合逾時錯誤的閘道回應。如果未指定回應類型，此回應預設為 `DEFAULT_5XX` 類型。 | 
| INVALID\$1API\$1KEY | 403 | 針對需要 API 金鑰之方法提交的 API 金鑰無效的閘道回應。如果未指定回應類型，此回應預設為 `DEFAULT_4XX` 類型。 | 
| INVALID\$1SIGNATURE | 403 | 無效 AWS 簽章錯誤的閘道回應。如果未指定回應類型，此回應預設為 `DEFAULT_4XX` 類型。 | 
| MISSING\$1AUTHENTICATION\$1TOKEN | 403 | 遺漏身分驗證字符錯誤的閘道回應，例如用戶端嘗試呼叫不支援的 API 方法或資源時。如果未指定回應類型，此回應預設為 `DEFAULT_4XX` 類型。 | 
| QUOTA\$1EXCEEDED | 429 | 用量計劃超額錯誤的閘道回應。如果未指定回應類型，此回應預設為 `DEFAULT_4XX` 類型。 | 
| REQUEST\$1TOO\$1LARGE | 413 | 請求太大錯誤的閘道回應。如果未指定回應類型，此回應預設為：`HTTP content length exceeded 10485760 bytes`。 | 
| RESOURCE\$1NOT\$1FOUND | 404 | API 請求通過身分驗證與授權之後 (API 金鑰身分驗證與授權除外)，API Gateway 找不到指定資源時的閘道回應。如果未指定回應類型，此回應預設為 `DEFAULT_4XX` 類型。 | 
| THROTTLED | 429 | 超過用量計劃、方法、階段或帳戶層級調節限制時的閘道回應。如果未指定回應類型，此回應預設為 `DEFAULT_4XX` 類型。 | 
| UNAUTHORIZED | 401 | 自訂或 Amazon Cognito 授權方無法驗證發起人時的閘道回應。 | 
| UNSUPPORTED\$1MEDIA\$1TYPE | 415 | 承載屬於不支援的媒體類型時的閘道回應 (如果啟用嚴格的傳遞行為)。如果未指定回應類型，此回應預設為 `DEFAULT_4XX` 類型。 | 
| WAF\$1FILTERED | 403 | 請求遭 AWS WAF封鎖時所出現的閘道回應。如果未指定回應類型，此回應預設為 `DEFAULT_4XX` 類型。  [AWS WAF 自訂回應](https://docs.aws.amazon.com/waf/latest/developerguide/waf-custom-request-response.html)優先於自訂閘道回應。   | 

# API Gateway 中 REST API 的 CORS
<a name="how-to-cors"></a>

[跨來源資源共享 (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) 是一種瀏覽器安全功能，限制從瀏覽器中執行之指令碼啟動的跨來源 HTTP 請求。如需詳細資訊，請參閱[什麼是 CORS？](https://aws.amazon.com/what-is/cross-origin-resource-sharing/)。

## 決定是否啟用 CORS 支援
<a name="apigateway-cors-request-types"></a>

*跨來源* HTTP 請求是針對下列項目所提出的請求：
+ 不同的*網域* (例如，從 `example.com` 到 `amazondomains.com`)
+ 不同的*子網域* (例如，從 `example.com` 到 `petstore.example.com`)
+ 不同的*連接埠* (例如，從 `example.com` 到 `example.com:10777`)
+ 不同的*通訊協定* (例如，從 `https://example.com` 到 `http://example.com`)

 如果您無法存取 API 並收到包含 `Cross-Origin Request Blocked` 的錯誤訊息，您可能需要啟用 CORS。

跨來源 HTTP 請求可分為兩種類型：*簡單*請求和*非簡單*請求。

## 針對簡單請求啟用 CORS
<a name="apigateway-cors-simple-request"></a>

如果下列所有條件皆為真，則 HTTP 請求為*簡單*請求：
+ 它是針對只允許 `GET`、`HEAD` 和 `POST` 請求的 API 資源所發出的。
+ 如果它是 `POST` 方法請求，則必須包含 `Origin` 標頭。
+ 請求承載內容類型為 `text/plain`、`multipart/form-data` 或 `application/x-www-form-urlencoded`。
+ 請求不包含自訂標頭。
+ [Mozilla CORS 文件中針對簡單請求](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests)列出的任何其他需求。

對於簡單的跨來源 `POST` 方法請求，來自您資源的回應需要包含標頭 `Access-Control-Allow-Origin: '*'` 或 `Access-Control-Allow-Origin:'origin'`。

所有其他跨來源 HTTP 請求都是*非簡單*請求。

## 針對非簡單請求啟用 CORS
<a name="apigateway-enable-cors-non-simple"></a>

如果您的 API 資源收到非簡單請求，則您必須啟用其他 CORS 支援，取決於您的整合類型。

### 針對非代理整合啟用 CORS
<a name="apigateway-enable-cors-mock"></a>

對於這些整合，[CORS 通訊協定](https://fetch.spec.whatwg.org/#http-cors-protocol)需要瀏覽器將預檢請求傳送到伺服器，並等待伺服器的核准 (或請求憑證)，然後再傳送實際請求。您必須設定 API，才能將適當的回應傳送至預檢請求。

 若要建立預檢回應：

1. 建立具有模擬整合的 `OPTIONS` 方法。

1. 將下列回應標頭新增至 200 方法回應：
   + `Access-Control-Allow-Headers`
   + `Access-Control-Allow-Methods`
   + `Access-Control-Allow-Origin`

1. 將整合傳遞行為設定為 `NEVER`。在此案例中，未映射內容類型的方法請求會遭到拒絕，並顯示 HTTP 415 Unsupported Media Type (不支援的媒體類型) 回應。如需詳細資訊，請參閱[API Gateway 中 REST API 沒有映射範本時，承載的方法請求行為](integration-passthrough-behaviors.md)。

1. 輸入回應標頭的值。若要允許所有來源、所有方法和常見的標頭，請使用下列標頭值：
   + `Access-Control-Allow-Headers: 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'`
   + `Access-Control-Allow-Methods: 'DELETE,GET,HEAD,OPTIONS,PUT,POST,PATCH'`
   + `Access-Control-Allow-Origin: '*'`

在建立預檢請求之後，至少針對所有 200 回應，您必須為所有已啟用 CORS 的方法傳回 `Access-Control-Allow-Origin: '*'` 或 `Access-Control-Allow-Origin:'origin'` 標頭。

### 使用 為非代理整合啟用 CORS AWS 管理主控台
<a name="apigateway-enable-cors-mock-console"></a>

您可以使用 AWS 管理主控台 來啟用 CORS。API Gateway 會建立 `OPTIONS` 方法，並將 `Access-Control-Allow-Origin` 標頭新增至現有方法的整合回應。這並不一定可行，有時您需要手動修改整合回應，至少針對所有 200 回應，為所有已啟用 CORS 的方法傳回 `Access-Control-Allow-Origin` 標題。

如果您將 API 的二進位媒體類型設定為 `*/*`，當 API Gateway 建立 `OPTIONS` 方法時，請將 `contentHandling` 變更為 `CONVERT_TO_TEXT`。

以下 [update-integration](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-integration.html) 命令會將整合請求的 `contentHandling` 變更為 `CONVERT_TO_TEXT`：

```
aws apigateway update-integration \
  --rest-api-id abc123 \
  --resource-id aaa111 \
  --http-method OPTIONS \
  --patch-operations op='replace',path='/contentHandling',value='CONVERT_TO_TEXT'
```

以下 [update-integration-response](https://docs.aws.amazon.com/cli/latest/reference/apigateway/update-integration-response.html) 命令會將整合回應的 `contentHandling` 變更為 `CONVERT_TO_TEXT`：

```
aws apigateway update-integration-response \
  --rest-api-id abc123 \
  --resource-id aaa111 \
  --http-method OPTIONS \
  --status-code 200 \
  --patch-operations op='replace',path='/contentHandling',value='CONVERT_TO_TEXT'
```

## 針對代理整合啟用 CORS 支援
<a name="apigateway-enable-cors-proxy"></a>

對於 Lambda 代理整合或 HTTP 代理整合，您的後端負責傳回 `Access-Control-Allow-Origin`、`Access-Control-Allow-Methods` 和 `Access-Control-Allow-Headers` 標頭，因為代理整合不會傳回整合回應。

下列範例 Lambda 函數會傳回必要的 CORS 標頭：

------
#### [ Node.js ]

```
export const handler = async (event) => {
    const response = {
        statusCode: 200,
        headers: {
            "Access-Control-Allow-Headers" : "Content-Type",
            "Access-Control-Allow-Origin": "https://www.example.com",
            "Access-Control-Allow-Methods": "OPTIONS,POST,GET"
        },
        body: JSON.stringify('Hello from Lambda!'),
    };
    return response;
};
```

------
#### [ Python 3 ]

```
import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'headers': {
            'Access-Control-Allow-Headers': 'Content-Type',
            'Access-Control-Allow-Origin': 'https://www.example.com',
            'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
        },
        'body': json.dumps('Hello from Lambda!')
    }
```

------

**Topics**
+ [決定是否啟用 CORS 支援](#apigateway-cors-request-types)
+ [針對簡單請求啟用 CORS](#apigateway-cors-simple-request)
+ [針對非簡單請求啟用 CORS](#apigateway-enable-cors-non-simple)
+ [針對代理整合啟用 CORS 支援](#apigateway-enable-cors-proxy)
+ [使用 API Gateway 主控台在資源上啟用 CORS](how-to-cors-console.md)
+ [使用 API Gateway 匯入 API 在資源上啟用 CORS](enable-cors-for-resource-using-swagger-importer-tool.md)
+ [測試 API Gateway API 的 CORS](apigateway-test-cors.md)

# 使用 API Gateway 主控台在資源上啟用 CORS
<a name="how-to-cors-console"></a>

您可以使用 API Gateway 主控台，為您已建立的 REST API 資源上的一個或所有方法啟用 CORS 支援。啟用 COR 支援後，將整合傳遞行為設定為 `NEVER`。在此案例中，未映射內容類型的方法請求會遭到拒絕，並顯示 HTTP 415 Unsupported Media Type (不支援的媒體類型) 回應。如需詳細資訊，請參閱[API Gateway 中 REST API 沒有映射範本時，承載的方法請求行為](integration-passthrough-behaviors.md)

**重要**  
資源可以包含子資源。對資源及其方法啟用 CORS 支援並不會對子資源及其方法遞迴啟用此支援。

**若要在 REST API 資源上啟用 CORS 支援**

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

1. 選擇一個 API。

1. 在**資源**下，選擇一個資源。

1. 在**資源詳細資訊**區段中，選擇**啟用 CORS**。

      
![\[在資源窗格中，選擇啟用 CORS。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/amazon-api-gateway-new-console-enable-cors.png)

1.  在**啟用 CORS** 方塊中，執行下列操作：

   1. (選用) 如果您已建立自訂閘道回應，並且想要針對回應啟用 CORS 支援，請選取閘道回應。

   1. 選取每一種方法以啟用 CORS 支援。`OPTION` 方法必須啟用 CORS。

      如果您為 `ANY` 方法啟用 CORS 支援，則所有方法的 CORS 都會啟用。

   1.  在 **Access-Control-Allow-Headers** 輸入欄位中，輸入逗號分隔標頭清單的靜態字串，用戶端必須在資源的實際請求中提交這些標頭。使用主控台提供的 `'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'` 標頭清單，或指定您自己的標頭。

   1. 使用主控台提供的 `'*'` 值以做為 **Access-Control-Allow-Origin** 標頭值，以允許所有來源中的存取請求，或指定允許其存取資源的起源。

   1. 選擇**儲存**。  
![\[選擇允許哪些標頭\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/amazon-api-gateway-new-console-enable-cors-resources.png)
**重要**  
 將上述說明應用在代理整合中的 `ANY` 方法時，不會設定任何適用的 CORS 標頭。反之，您的後端必須傳回適當的 CORS 標頭，例如 `Access-Control-Allow-Origin`。

在 `GET` 方法上啟用 CORS 之後，如果資源中尚未有 `OPTIONS` 方法，則系統會將此方法新增至資源。`OPTIONS` 方法的 `200` 回應會自動設定為傳回三個 `Access-Control-Allow-*` 標頭，來完成預檢交握。此外，根據預設也會設定實際 (`GET`) 方法，以在其 200 回應中傳回 `Access-Control-Allow-Origin` 標頭。對於其他類型的回應，如果您不想要傳回 `Cross-origin access` 錯誤，則需要使用 '\$1' 或特定來源手動進行設定，以傳回 `Access-Control-Allow-Origin'` 標頭。

在您的資源上啟用 CORS 支援之後，您必須部署或重新部署 API，新的設定才能生效。如需詳細資訊，請參閱[建立部署](set-up-deployments.md#create-deployment)。

**注意**  
如果您在遵循程序後無法在資源上啟用 CORS 支援，建議您比較 CORS 組態與範例 API `/pets` 資源。若要了解如何建立範例 API，請參閱 [教學課程：匯入範例來建立 REST API](api-gateway-create-api-from-example.md)。

# 使用 API Gateway 匯入 API 在資源上啟用 CORS
<a name="enable-cors-for-resource-using-swagger-importer-tool"></a>

如果您使用 [API Gateway 匯入 API](api-gateway-import-api.md)，即可透過 OpenAPI 檔案來設定 CORS 支援。您必須先在傳回必要標頭的資源中定義 `OPTIONS` 方法。

**注意**  
Web 瀏覽器必須在每個接受 CORS 請求的 API 方法中設定 Access-Control-Allow-Headers 與 Access-Control-Allow-Origin 標頭。此外，某些瀏覽器會先向相同資源中的 `OPTIONS` 方法提出 HTTP 請求，然後預期收到相同的標頭。

## 示例 `Options` 方法
<a name="enable-cors-for-resource-using-swagger-importer-tool-options"></a>

下列範例為模擬整合建立 `OPTIONS` 方法。

------
#### [ OpenAPI 3.0 ]

```
/users:
  options:
    summary: CORS support
    description: |
      Enable CORS by returning correct headers
    tags:
    - CORS
    responses:
      200:
        description: Default response for CORS method
        headers:
          Access-Control-Allow-Origin:
            schema:
              type: "string"
          Access-Control-Allow-Methods:
            schema:
              type: "string"
          Access-Control-Allow-Headers:
            schema:
              type: "string"
        content: {}
    x-amazon-apigateway-integration:
      type: mock
      requestTemplates:
        application/json: "{\"statusCode\": 200}"
      passthroughBehavior: "never"
      responses:
        default:
          statusCode: "200"
          responseParameters:
            method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
            method.response.header.Access-Control-Allow-Methods: "'*'"
            method.response.header.Access-Control-Allow-Origin: "'*'"
```

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

```
/users: 
   options:
      summary: CORS support
      description: |
        Enable CORS by returning correct headers
      consumes:
        - "application/json"
      produces:
        - "application/json"
      tags:
        - CORS
      x-amazon-apigateway-integration:
        type: mock
        requestTemplates: "{\"statusCode\": 200}"
        passthroughBehavior: "never"
        responses:
          "default":
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Headers : "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
              method.response.header.Access-Control-Allow-Methods : "'*'"
              method.response.header.Access-Control-Allow-Origin : "'*'"
      responses:
        200:
          description: Default response for CORS method
          headers:
            Access-Control-Allow-Headers:
              type: "string"
            Access-Control-Allow-Methods:
              type: "string"
            Access-Control-Allow-Origin:
              type: "string"
```

------

一旦您為資源設定 `OPTIONS` 方法，您就可以將必要的標頭新增至相同資源中需要接受 CORS 請求的其他方法。

1. 對回應類型宣告 **Access-Control-Allow-Origin** 與 **Headers**。

------
#### [ OpenAPI 3.0 ]

   ```
       responses:
         200:
           description: Default response for CORS method
           headers:
             Access-Control-Allow-Origin:
               schema:
                 type: "string"
             Access-Control-Allow-Methods:
               schema:
                 type: "string"
             Access-Control-Allow-Headers:
               schema:
                 type: "string"
           content: {}
   ```

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

   ```
       responses:
           200:
             description: Default response for CORS method
             headers:
               Access-Control-Allow-Headers:
                 type: "string"
               Access-Control-Allow-Methods:
                 type: "string"
               Access-Control-Allow-Origin:
                 type: "string"
   ```

------

1. 在 `x-amazon-apigateway-integration` 標籤中，將這些標頭的對應設定為您的靜態值：

------
#### [ OpenAPI 3.0 ]

   ```
       responses:
           default:
             statusCode: "200"
             responseParameters:
               method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
               method.response.header.Access-Control-Allow-Methods: "'*'"
               method.response.header.Access-Control-Allow-Origin: "'*'"
             responseTemplates:
               application/json: |
                 {}
   ```

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

   ```
       responses:
             "default":
               statusCode: "200"
               responseParameters:
                 method.response.header.Access-Control-Allow-Headers : "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
                 method.response.header.Access-Control-Allow-Methods : "'*'"
                 method.response.header.Access-Control-Allow-Origin : "'*'"
   ```

------

## API 範例
<a name="enable-cors-for-resource-using-swagger-importer-tool-complete-example"></a>

下列範例會建立具有 `HTTP` 整合 `OPTIONS` 方法和 `GET` 方法的完整 API。

------
#### [ OpenAPI 3.0 ]

```
openapi: "3.0.1"
info:
  title: "cors-api"
  description: "cors-api"
  version: "2024-01-16T18:36:01Z"
servers:
- url: "/{basePath}"
  variables:
    basePath:
      default: "/test"
paths:
  /:
    get:
      operationId: "GetPet"
      responses:
        "200":
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        httpMethod: "GET"
        uri: "http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets"
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Origin: "'*'"
        passthroughBehavior: "never"
        type: "http"
    options:
      responses:
        "200":
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Empty"
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        passthroughBehavior: "never"
        type: "mock"
components:
  schemas:
    Empty:
      type: "object"
```

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

```
swagger: "2.0"
info:
  description: "cors-api"
  version: "2024-01-16T18:36:01Z"
  title: "cors-api"
basePath: "/test"
schemes:
- "https"
paths:
  /:
    get:
      operationId: "GetPet"
      produces:
      - "application/json"
      responses:
        "200":
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              type: "string"
      x-amazon-apigateway-integration:
        httpMethod: "GET"
        uri: "http://petstore.execute-api.us-east-1.amazonaws.com/petstore/pets"
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Origin: "'*'"
        passthroughBehavior: "never"
        type: "http"
    options:
      consumes:
      - "application/json"
      produces:
      - "application/json"
      responses:
        "200":
          description: "200 response"
          schema:
            $ref: "#/definitions/Empty"
          headers:
            Access-Control-Allow-Origin:
              type: "string"
            Access-Control-Allow-Methods:
              type: "string"
            Access-Control-Allow-Headers:
              type: "string"
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'GET,OPTIONS'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        passthroughBehavior: "never"
        type: "mock"
definitions:
  Empty:
    type: "object"
```

------

# 測試 API Gateway API 的 CORS
<a name="apigateway-test-cors"></a>

您可以透過叫用 API 來測試 API 的 CORS 組態，並在回應中檢查 CORS 標頭。下面的 `curl` 命令會傳送 OPTIONS 請求至已部署的 API。

```
curl -v -X OPTIONS https://{restapi_id}.execute-api.{region}.amazonaws.com/{stage_name}
```

```
< HTTP/1.1 200 OK
< Date: Tue, 19 May 2020 00:55:22 GMT
< Content-Type: application/json
< Content-Length: 0
< Connection: keep-alive
< x-amzn-RequestId: a1b2c3d4-5678-90ab-cdef-abc123
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Headers: Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token
< x-amz-apigw-id: Abcd=
< Access-Control-Allow-Methods: DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT
```

回應中的 `Access-Control-Allow-Origin`、`Access-Control-Allow-Headers` 和 `Access-Control-Allow-Methods` 標頭會顯示 API 支援 CORS。如需詳細資訊，請參閱[API Gateway 中 REST API 的 CORS](how-to-cors.md)。

# API Gateway 中 REST API 的二進位媒體類型
<a name="api-gateway-payload-encodings"></a>

在 API Gateway 中，API 請求與回應可以有文字或二進位承載。文字承載是 `UTF-8` 編碼的 JSON 字串。二進位承載是文字承載以外的任何項目。例如，二進位承載可以是 JPEG 檔案、GZip 檔案或 XML 檔案。支援二進位媒體所需的 API 組態取決於您的 API 是否使用代理或非代理整合。

如果您使用代理整合與承載回應串流，則不需要設定二進位媒體類型。如需詳細資訊，請參閱[在 API Gateway 中串流代理整合的整合回應](response-transfer-mode.md)。

## AWS Lambda 代理整合
<a name="api-gateway-payload-encodings-proxy"></a>

若要處理 AWS Lambda 代理整合的二進位承載，您必須對函數的回應進行 base64 編碼。您也必須為 API 配置 [binaryMediaTypes](https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html#apigw-Type-RestApi-binaryMediaTypes)。您的 API `binaryMediaTypes` 組態是 API 視為二進位資料的內容類型列表。範例二進位媒體類型包括 `image/png` 或 `application/octet-stream`。您可以使用萬用字元 (`*`) 來涵蓋多種媒體類型。

API Gateway 會使用來自用戶端的第一個 `Accept` 標頭來判斷回應是否應該傳回二進位媒體。若要在無法控制 `Accept` 標頭值的順序 (例如來自瀏覽器的請求) 時傳回二進位媒體，請將 API 的二進位媒體類型設定為 `*/*`。

如需範例程式碼，請參閱 [在 API Gateway 中從 Lambda 代理整合傳回二進位媒體](lambda-proxy-binary-media.md)。

如果您使用 Lambda 代理整合與承載回應串流，則不需要設定二進位媒體類型。如需詳細資訊，請參閱[在 API Gateway 中設定 Lambda 代理整合與承載回應串流](response-transfer-mode-lambda.md)。

## 非代理伺服器整合
<a name="api-gateway-payload-encodings-non-proxy"></a>

若要處理非代理整合的二進位承載，您可以將媒體類型新增至 `RestApi` 資源的 [binaryMediaTypes](https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html#apigw-Type-RestApi-binaryMediaTypes) 清單。您的 API `binaryMediaTypes` 組態是 API 視為二進位資料的內容類型列表。或者，您可以在 [Integration](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html) 與 [IntegrationResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html) 資源上設定 [contentHandling](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html#contentHandling) 屬性。`contentHandling` 值可以是 `CONVERT_TO_BINARY`、`CONVERT_TO_TEXT` 或未定義。

**注意**  
若是 `MOCK` 或私有整合，不支援在 AWS 管理主控台中設定 `contentHandling` 屬性。您必須使用 AWS CLI CloudFormation、 或 SDK 來設定`contentHandling`屬性。

根據 `contentHandling` 值，以及回應的 `Content-Type` 標頭或傳入請求的 `Accept` 標頭是否符合 `binaryMediaTypes` 清單中的項目，API Gateway 可以將原始二進位位元組編碼為 Base64 編碼字串、將 Base64 編碼字串解碼回其原始位元組，或傳遞本文而不進行任何修改。

您必須遵循下列方式設定 API，以在 API Gateway 中支援 API 的二進位承載：
+ 將所需的二進位媒體類型新增至 [RestApi](https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html) 資源上的 `binaryMediaTypes` 清單。如果未定義此屬性與 `contentHandling` 屬性，則會將承載當作 UTF-8 編碼的 JSON 字串來處理。
+ 將 [Integration](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html) 資源的 `contentHandling` 屬性定址。
  + 若要讓請求承載從 base64 編碼的字串轉換為其二進位 Blob，請將屬性設定為 `CONVERT_TO_BINARY`。
  + 若要將請求承載從二進位 Blob 轉換為 base64 編碼的字串，請將屬性設定為 `CONVERT_TO_TEXT`。
  + 若要在不修改的情況下傳遞承載，請將屬性保留為未定義。若要在未經修改的情況下傳遞二進位承載，您也必須確定 `Content-Type` 符合其中一個 `binaryMediaTypes` 項目，並且已針對 API 啟用[傳遞行為](integration-passthrough-behaviors.md)。
+ 設定 [IntegrationResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html) 資源的 `contentHandling` 屬性。`contentHandling` 屬性、用戶端請求中的 `Accept` 標頭，以及 API 的 `binaryMediaTypes` 組合會決定 API Gateway 處理內容類型轉換的方式。如需詳細資訊，請參閱[API Gateway 中的內容類型轉換](api-gateway-payload-encodings-workflow.md)。

**重要**  
當請求的 `Accept` 標頭中包含多個媒體類型時，API Gateway 只會採用第一個 `Accept` 媒體類型。如果您無法控制 `Accept` 媒體類型的順序，而且二進位內容的媒體類型不是清單中的第一個類型，您可以在 API 的 `binaryMediaTypes` 清單中新增第一個 `Accept` 媒體類型。API Gateway 將以二進位處理此清單中的所有內容類型。  
例如，若要在瀏覽器中使用 `<img>` 元素來傳送 JPEG 檔案，瀏覽器可能會在請求中傳送 `Accept:image/webp,image/*,*/*;q=0.8`。透過將 `image/webp` 新增至 `binaryMediaTypes` 清單，端點就能收到二進位格式的 JPEG 檔案。

如需 API Gateway 如何處理文字和二進位承載的詳細資訊，請參閱[API Gateway 中的內容類型轉換](api-gateway-payload-encodings-workflow.md)。

# API Gateway 中的內容類型轉換
<a name="api-gateway-payload-encodings-workflow"></a>

 您的 API 的 `binaryMediaTypes`、用戶端請求中的標頭，以及整合 `contentHandling` 屬性的組合將決定 API Gateway 編碼有效承載的方式。

下表顯示 API Gateway 如何轉換請求的 `Content-Type` 標頭、[RestApi](https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html) 資源的 `binaryMediaTypes` 清單與 [Integration](https://docs.aws.amazon.com/apigateway/latest/api/API_Integration.html) 資源的 `contentHandling` 屬性值之特定組態的請求酬載。


| 方法請求承載 | 請求 `Content-Type` 標頭 | `binaryMediaTypes` | `contentHandling` | 整合請求承載 | 
| --- | --- | --- | --- | --- | 
| 文字資料 | 任何資料類型 | 未定義 | 未定義 | UTF8 編碼字串 | 
| 文字資料 | 任何資料類型 | 未定義 | CONVERT\$1TO\$1BINARY | Base64 解碼的二進位 Blob | 
| 文字資料 | 任何資料類型 | 未定義 | CONVERT\$1TO\$1TEXT | UTF8 編碼字串 | 
| 文字資料 | 文字資料類型 | 設定相符媒體類型 | 未定義 | 文字資料 | 
| 文字資料 | 文字資料類型 | 設定相符媒體類型 | CONVERT\$1TO\$1BINARY | Base64 解碼的二進位 Blob | 
| 文字資料 | 文字資料類型 | 設定相符媒體類型 | CONVERT\$1TO\$1TEXT | 文字資料 | 
| 二進位資料 | 二進位資料類型 | 設定相符媒體類型 | 未定義 | 二進位資料 | 
| 二進位資料 | 二進位資料類型 | 設定相符媒體類型 | CONVERT\$1TO\$1BINARY | 二進位資料 | 
| 二進位資料 | 二進位資料類型 | 設定相符媒體類型 | CONVERT\$1TO\$1TEXT | Base64 編碼字串 | 

下表顯示 API Gateway 如何轉換請求的 `Accept` 標頭、[RestApi](https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html) 資源的 `binaryMediaTypes` 清單與 [IntegrationResponse](https://docs.aws.amazon.com/apigateway/latest/api/API_IntegrationResponse.html) 資源的 `contentHandling` 屬性值之特定組態的回應酬載。

**重要**  
 當請求的 `Accept` 標頭中包含多個媒體類型時，API Gateway 只會採用第一個 `Accept` 媒體類型。如果您無法控制 `Accept` 媒體類型的順序，而且二進位內容的媒體類型不是清單中的第一個類型，您可以在 API 的 `binaryMediaTypes` 清單中新增第一個 `Accept` 媒體類型。API Gateway 將以二進位處理此清單中的所有內容類型。  
例如，若要在瀏覽器中使用 `<img>` 元素來傳送 JPEG 檔案，瀏覽器可能會在請求中傳送 `Accept:image/webp,image/*,*/*;q=0.8`。透過將 `image/webp` 新增至 `binaryMediaTypes` 清單，端點就能收到二進位格式的 JPEG 檔案。


| 整合回應承載 | 請求 `Accept` 標頭 | `binaryMediaTypes` | `contentHandling` | 方法回應承載 | 
| --- | --- | --- | --- | --- | 
| 文字或二進位資料 | 文字類型 | 未定義 | 未定義 | UTF8 編碼字串 | 
| 文字或二進位資料 | 文字類型 | 未定義 | CONVERT\$1TO\$1BINARY | Base64 解碼的 Blob | 
| 文字或二進位資料 | 文字類型 | 未定義 | CONVERT\$1TO\$1TEXT | UTF8 編碼字串 | 
| 文字資料 | 文字類型 | 設定相符媒體類型 | 未定義 | 文字資料 | 
| 文字資料 | 文字類型 | 設定相符媒體類型 | CONVERT\$1TO\$1BINARY | Base64 解碼的 Blob | 
| 文字資料 | 文字類型 | 設定相符媒體類型 | CONVERT\$1TO\$1TEXT | UTF8 編碼字串 | 
| 文字資料 | 二進位類型 | 設定相符媒體類型 | 未定義 | Base64 解碼的 Blob | 
| 文字資料 | 二進位類型 | 設定相符媒體類型 | CONVERT\$1TO\$1BINARY | Base64 解碼的 Blob | 
| 文字資料 | 二進位類型 | 設定相符媒體類型 | CONVERT\$1TO\$1TEXT | UTF8 編碼字串 | 
| 二進位資料 | 文字類型 | 設定相符媒體類型 | 未定義 | Base64 編碼字串 | 
| 二進位資料 | 文字類型 | 設定相符媒體類型 | CONVERT\$1TO\$1BINARY | 二進位資料 | 
| 二進位資料 | 文字類型 | 設定相符媒體類型 | CONVERT\$1TO\$1TEXT | Base64 編碼字串 | 
| 二進位資料 | 二進位類型 | 設定相符媒體類型 | 未定義 | 二進位資料 | 
| 二進位資料 | 二進位類型 | 設定相符媒體類型 | CONVERT\$1TO\$1BINARY | 二進位資料 | 
| 二進位資料 | 二進位類型 | 設定相符媒體類型 | CONVERT\$1TO\$1TEXT | Base64 編碼字串 | 

將文字承載轉換成二進位 Blob 時，API Gateway 會假設文字資料是 Base64 編碼字串，並將二進位資料輸出為 Base64 解碼的 Blob。如果轉換失敗，它會傳回 `500` 回應，表示 API 組態錯誤。您不會為這類轉換提供對應範本，但您必須在 API 上啟用[傳遞行為](integration-passthrough-behaviors.md)。

將二進位承載轉換成文字字串時，API Gateway 一律會在二進位資料上套用 Base64 編碼。您可以為這類承載定義對應範本，但只能透過 `$input.body` 存取對應範本中的 Base64 編碼字串，如下列範例對應範本摘要所示。

```
{   
    "data": "$input.body"
}
```

若要傳遞二進位承載而不進行任何修改，您必須在 API 上啟用[傳遞行為](integration-passthrough-behaviors.md)。

# 使用 API Gateway 主控台啟用二進位支援
<a name="api-gateway-payload-encodings-configure-with-console"></a>

本節說明如何使用 API Gateway 主控台來啟用二進位支援。舉例來說，我們使用與 Amazon S3 整合的 API。我們將重點放在設定支援的媒體類型，以及指定應該如何處理承載的作業上。如需如何建立與 Amazon S3 整合之 API 的詳細資訊，請參閱[教學：建立 REST API 做為 Amazon S3 代理](integrating-api-with-aws-services-s3.md)。

**使用 API Gateway 主控台啟用二進位支援**

1. 設定 API 的二進位媒體類型：

   1. 建立新的 API 或選擇現有的 API。在此範例中，我們將 API 命名為 `FileMan`。

   1. 在主導覽面板中所選取的 API 下，選擇 **API 設定**。

   1. 在 **API 設定**窗格的**二進位媒體類型**區段中，選擇**管理媒體類型**。

   1. 選擇**新增二進位媒體類型**。

   1. 在輸入文字欄位中，輸入必要的媒體類型，例如 **image/png**。如果需要，請重複此步驟來新增更多媒體類型。若要支援所有二進位媒體類型，請指定 `*/*`。

   1. 選擇**儲存變更**。

1. 設定如何處理 API 方法的訊息承載：

   1. 在 API 中建立新的資源或選擇現有的資源。在此範例中，我們使用 `/{folder}/{item}` 資源。

   1. 在資源上建立新的方法或選擇現有的方法。舉例來說，我們使用與 Amazon S3 中 `GET /{folder}/{item}` 動作整合的 `Object GET` 方法。

   1. 針對**內容處理**，選擇一個選項。

         
![\[在 API Gateway 主控台中設定 GET 方法。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/binary-support-content-handling-on-method-new-console.png)

      如果您不想要在用戶端與後端接受相同的二進位格式時轉換本文，請選擇**傳遞**。例如，當後端需要二進位請求承載以 JSON 屬性傳入時，選擇**轉換為文字**，以將二進位本文轉換成 Base64 編碼字串。此外，當用戶端提交 Base64 編碼字串且後端需要原始二進位格式時，或是當端點傳回 Base64 編碼字串且用戶端只接受二進位輸出時，選擇**轉換為二進位**。

   1. 針對**請求內文傳遞**，選擇**未定義範本時 (建議)**以在請求內文上啟用傳遞行為。

      您也可以選擇**永不**。這意味著 API 將拒絕 content-types 沒有對應範本的資料。

   1. 在整合請求中保留傳入請求的 `Accept` 標頭。如果您將 `contentHandling` 設定為 `passthrough` 並想要在執行階段覆寫該設定，則應該這麼做。

         
![\[在整合請求中保留 Accept 標頭。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/binary-support-preserve-incoming-accept-header-new-console.png)

   1. 若要轉換成文字，請定義對應範本，將 Base64 編碼的二進位資料設為必要的格式。

      以下是要轉換為文字的對應範本範例：

      ```
      {
        "operation": "thumbnail",
        "base64Image": "$input.body"
      }
      ```

      此對應範本的格式取決於輸入的端點需求。

   1. 選擇**儲存**。

# 使用 API Gateway REST API 啟用二進位支援
<a name="api-gateway-payload-encodings-configure-with-control-service-api"></a>

下列作業示範如何使用 API Gateway REST API 呼叫來啟用二進位支援。

**Topics**
+ [將支援的二進位媒體類型新增與更新至 API](#api-gateway-payload-encodings-setup-with-api-set-encodings-map)
+ [設定請求承載轉換](#api-gateway-payload-encodings-setup-with-api-set-integration-request-encoding)
+ [設定回應承載轉換](#api-gateway-payload-encodings-setup-with-api-set-integration-response-encoding)
+ [將二進位資料轉換成文字資料](#api-gateway-payload-encodings-convert-binary-to-string)
+ [將文字資料轉換成二進位承載](#api-gateway-payload-encodings-convert-string-to-binary)
+ [傳遞二進位承載](#api-gateway-payload-encodings-pass-binary-as-is)

## 將支援的二進位媒體類型新增與更新至 API
<a name="api-gateway-payload-encodings-setup-with-api-set-encodings-map"></a>

若要讓 API Gateway 支援新的二進位媒體類型，您必須將二進位媒體類型新增至 `RestApi` 資源的 `binaryMediaTypes` 清單。例如，若要讓 API Gateway 處理 JPEG 影像，請將 `RestApi` 請求提交至 `PATCH` 資源：

```
PATCH /restapis/<restapi_id>

{
  "patchOperations" : [ {
    "op" : "add",
    "path" : "/binaryMediaTypes/image~1jpeg"
  } 
 ]
}
```

`image/jpeg` 的 MIME 類型規格是 `path` 屬性值的一部分，因此會逸出為 `image~1jpeg`。

若要更新支援的二進位媒體類型，請從 `binaryMediaTypes` 資源的 `RestApi` 清單中取代或移除媒體類型。例如，若要將二進位支援從 JPEG 檔案變更為原始位元組，請對 `PATCH` 資源提交 `RestApi` 請求，如下所示。

```
PATCH /restapis/<restapi_id>

{
  "patchOperations" : [{
    "op" : "replace",
    "path" : "/binaryMediaTypes/image~1jpeg",
    "value" : "application/octet-stream"
  },
  {
    "op" : "remove",
    "path" : "/binaryMediaTypes/image~1jpeg"
  }]
}
```

## 設定請求承載轉換
<a name="api-gateway-payload-encodings-setup-with-api-set-integration-request-encoding"></a>

如果端點需要二進位輸入，請將 `contentHandling` 資源的 `Integration` 屬性設定為 `CONVERT_TO_BINARY`。若要執行這項操作，請提交 `PATCH` 請求，如下所示：

```
PATCH /restapis/<restapi_id>/resources/<resource_id>/methods/<http_method>/integration

{
  "patchOperations" : [ {
    "op" : "replace",
    "path" : "/contentHandling",
    "value" : "CONVERT_TO_BINARY"
  }]
}
```

## 設定回應承載轉換
<a name="api-gateway-payload-encodings-setup-with-api-set-integration-response-encoding"></a>

如果用戶端接受二進位 Blob 格式的結果，而不是從端點傳回的 Base64 編碼承載，將 `IntegrationResponse` 資源的 `contentHandling` 屬性設定為 `CONVERT_TO_BINARY`。若要這樣做，請提交 `PATCH` 請求，如下所示：

```
PATCH /restapis/<restapi_id>/resources/<resource_id>/methods/<http_method>/integration/responses/<status_code>

{
  "patchOperations" : [ {
    "op" : "replace",
    "path" : "/contentHandling",
    "value" : "CONVERT_TO_BINARY"
  }]
}
```

## 將二進位資料轉換成文字資料
<a name="api-gateway-payload-encodings-convert-binary-to-string"></a>

若要透過 API Gateway 將二進位資料做為輸入 AWS Lambda 或 Kinesis 的 JSON 屬性傳送，請執行下列動作：

1. 將 `application/octet-stream` 的新二進位媒體類型新增至 API 的 `binaryMediaTypes` 清單，以啟用 API 的二進位承載支援。

   ```
   PATCH /restapis/<restapi_id>
   
   {
     "patchOperations" : [ {
       "op" : "add",
       "path" : "/binaryMediaTypes/application~1octet-stream"
     } 
    ]
   }
   ```

1. 在 `CONVERT_TO_TEXT` 資源的 `contentHandling` 屬性上設定 `Integration`，並提供對應範本，以將二進位資料的 Base64 編碼字串指派給 JSON 屬性。在下列範例中，JSON 屬性是持有 Base64 編碼字串的 `body` 與 `$input.body`。

   ```
   PATCH /restapis/<restapi_id>/resources/<resource_id>/methods/<http_method>/integration
   
   {
     "patchOperations" : [
       {
         "op" : "replace",
         "path" : "/contentHandling",
         "value" : "CONVERT_TO_TEXT"
       },
       {
         "op" : "add",
         "path" : "/requestTemplates/application~1octet-stream",
         "value" : "{\"body\": \"$input.body\"}"
       }
     ]
   }
   ```

## 將文字資料轉換成二進位承載
<a name="api-gateway-payload-encodings-convert-string-to-binary"></a>

假設 Lambda 函數會傳回 Base64 編碼字串格式的影像檔。若要透過 API Gateway 將此二進位輸出傳遞給用戶端，請執行下列操作：

1. 新增 `binaryMediaTypes` 的二進位媒體類型 (如果尚未在清單中)，以更新 API 的 `application/octet-stream` 清單。

   ```
   PATCH /restapis/<restapi_id>
   
   {
     "patchOperations" : [ {
       "op" : "add",
       "path" : "/binaryMediaTypes/application~1octet-stream",
     }]
   }
   ```

1.  將 `contentHandling` 資源上的 `Integration` 屬性設定為 `CONVERT_TO_BINARY`。請勿定義對應範本。如果您未定義映射範本，API Gateway 可呼叫傳遞範本，將 Base64 解碼的二進位 Blob 做為影像檔傳回至用戶端。

   ```
   PATCH /restapis/<restapi_id>/resources/<resource_id>/methods/<http_method>/integration/responses/<status_code>
   
   {
     "patchOperations" : [
       {
         "op" : "replace",
         "path" : "/contentHandling",
         "value" : "CONVERT_TO_BINARY"
       }
     ]
   }
   ```

## 傳遞二進位承載
<a name="api-gateway-payload-encodings-pass-binary-as-is"></a>

 若要使用 API Gateway 將映像儲存在 Amazon S3 儲存貯體中，請執行下列動作：

1. 新增 `binaryMediaTypes` 的二進位媒體類型 (如果尚未在清單中)，以更新 API 的 `application/octet-stream` 清單。

   ```
   PATCH /restapis/<restapi_id>
   
   {
     "patchOperations" : [ {
       "op" : "add",
       "path" : "/binaryMediaTypes/application~1octet-stream"
     }
    ]
   }
   ```

1. 在 `contentHandling` 資源的 `Integration` 屬性上設定 `CONVERT_TO_BINARY`。將 `WHEN_NO_MATCH` 設定為 `passthroughBehavior` 屬性值，而不需要定義對應範本。這可讓 API Gateway 叫用傳遞範本。

   ```
   PATCH /restapis/<restapi_id>/resources/<resource_id>/methods/<http_method>/integration
   
   {
     "patchOperations" : [
       {
         "op" : "replace",
         "path" : "/contentHandling",
         "value" : "CONVERT_TO_BINARY"
       },
       {
         "op" : "replace",
         "path" : "/passthroughBehaviors",
         "value" : "WHEN_NO_MATCH"
       }
     ]
   }
   ```

# API Gateway 的匯入與匯出內容編碼
<a name="api-gateway-payload-encodings-import-and-export"></a>

 若要匯入 [RestApi](https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html) 上的 `binaryMediaTypes` 清單，請使用 API OpenAPI 定義檔的下列 API Gateway 延伸。此延伸也可用來匯出 API 設定。
+ [x-amazon-apigateway-binary-media-types 屬性](api-gateway-swagger-extensions-binary-media-types.md)

若要匯入與匯出 `Integration` 或 `IntegrationResponse` 資源上的 `contentHandling` 屬性值，請使用 OpenAPI 定義的下列 API Gateway 延伸：
+ [x-amazon-apigateway-integration 物件](api-gateway-swagger-extensions-integration.md)
+ [x-amazon-apigateway-integration.response 物件](api-gateway-swagger-extensions-integration-response.md)

# 在 API Gateway 中從 Lambda 代理整合傳回二進位媒體
<a name="lambda-proxy-binary-media"></a>

要從 [AWS Lambda 代理整合](set-up-lambda-proxy-integrations.md)傳回二進位媒體，您需要對 Lambda 函數的回應進行 base64 編碼。您還必須[配置 API 的二進位媒體類型](api-gateway-payload-encodings-configure-with-console.md)。當您設定 API 的二進位媒體類型時，API 會將該內容類型視為二進位資料。承載大小上限為 10 MB。

**注意**  
若要使用網頁瀏覽器來叫用具有此範例整合的 API，請將 API 的二進位媒體類型設定為 `*/*`。API Gateway 會使用來自用戶端的第一個 `Accept` 標頭來判斷回應是否應該傳回二進位媒體。若要在無法控制 `Accept` 標頭值的順序 (例如來自瀏覽器的請求) 時傳回二進位媒體，請將 API 的二進位媒體類型設定為 `*/*` (適用於所有內容類型)。

下列範例 Lambda 函數可將二進位映像從 Amazon S3 或文字傳回給用戶端。該函數的回應會包括一個 `Content-Type` 標頭，以指示給用戶端它傳回的資料類型。該函數會有條件地在其回應中設定 `isBase64Encoded` 屬性，具體取決於它傳回的資料類型。

------
#### [ Node.js ]

```
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3"

const client = new S3Client({region: 'us-east-2'});

export const handler = async (event) => {

  var randomint = function(max) {
    return Math.floor(Math.random() * max);
  }
  var number = randomint(2);
  if (number == 1){ 
    const input = {
      "Bucket" : "bucket-name",
      "Key" : "image.png"
      }
    try {
      const command = new GetObjectCommand(input)
      const response = await client.send(command);
      var str = await response.Body.transformToByteArray();
    } catch (err) {
      console.error(err);
    }
    const base64body = Buffer.from(str).toString('base64');
    return {
      'headers': { "Content-Type": "image/png" },
      'statusCode': 200,
      'body': base64body,
      'isBase64Encoded': true
      }
    } else {
        return {
        'headers': { "Content-Type": "text/html" },
        'statusCode': 200,
        'body': "<h1>This is text</h1>",
        }
    }
}
```

------
#### [ Python ]

```
import base64
import boto3
import json
import random

s3 = boto3.client('s3')

def lambda_handler(event, context):
    number = random.randint(0,1)
    if number == 1:
        response = s3.get_object(
            Bucket='bucket-name',
            Key='image.png',
        )
        image = response['Body'].read()
        return {
            'headers': { "Content-Type": "image/png" },
            'statusCode': 200,
            'body': base64.b64encode(image).decode('utf-8'),
            'isBase64Encoded': True
        }
    else:
        return {
            'headers': { "Content-type": "text/html" },
            'statusCode': 200,
            'body': "<h1>This is text</h1>",
        }
```

------

若要進一步了解二進位媒體類型，請參閱[API Gateway 中 REST API 的二進位媒體類型](api-gateway-payload-encodings.md)。

# 透過 API Gateway API 存取 Amazon S3 中的二進位檔案
<a name="api-gateway-content-encodings-examples-image-s3"></a>

下列範例示範如何使用 OpenAPI 檔案來存取 Amazon S3 中的影像、如何從 Amazon S3 下載影像，以及如何將影像上傳至 Amazon S3。

**Topics**
+ [存取 Amazon S3 中影像之範例 API 的 OpenAPI 檔案](#api-gateway-content-encodings-example-image-s3-swagger-file)
+ [從 Amazon S3 下載影像](#api-gateway-content-encodings-example-download-image-from-s3)
+ [將影像上傳至 Amazon S3](#api-gateway-content-encodings-example-upload-image-to-s3)

## 存取 Amazon S3 中影像之範例 API 的 OpenAPI 檔案
<a name="api-gateway-content-encodings-example-image-s3-swagger-file"></a>

下列 OpenAPI 檔案顯示一個範例 API，說明如何從 Amazon S3 下載影像檔，以及如何將影像檔上傳至 Amazon S3。此 API 會公開用於下載及上傳指定影像檔的 `GET /s3?key={file-name}` 與 `PUT /s3?key={file-name}` 方法。`GET` 方法會在「200 OK」回應中，將 Base64 編碼字串格式的影像檔當作 JSON 輸出的一部分傳回，後面接著所提供的映射範本。`PUT` 方法接受原始二進位 Blob 作為輸入，並傳回「200 OK」回應與空的承載。

------
#### [ OpenAPI 3.0 ]

```
{
   "openapi": "3.0.0",
   "info": {
      "version": "2016-10-21T17:26:28Z",
      "title": "ApiName"
   },
   "paths": {
      "/s3": {
         "get": {
            "parameters": [
               {
                  "name": "key",
                  "in": "query",
                  "required": false,
                  "schema": {
                     "type": "string"
                  }
               }
            ],
            "responses": {
               "200": {
                  "description": "200 response",
                  "content": {
                     "application/json": {
                        "schema": {
                           "$ref": "#/components/schemas/Empty"
                        }
                     }
                  }
               },
               "500": {
                  "description": "500 response"
               }
            },
            "x-amazon-apigateway-integration": {
               "credentials": "arn:aws:iam::123456789012:role/binarySupportRole",
               "responses": {
                  "default": {
                     "statusCode": "500"
                  },
                  "2\\d{2}": {
                     "statusCode": "200"
                  }
               },
               "requestParameters": {
                  "integration.request.path.key": "method.request.querystring.key"
               },
               "uri": "arn:aws:apigateway:us-west-2:s3:path/{key}",
               "passthroughBehavior": "when_no_match",
               "httpMethod": "GET",
               "type": "aws"
            }
         },
         "put": {
            "parameters": [
               {
                  "name": "key",
                  "in": "query",
                  "required": false,
                  "schema": {
                     "type": "string"
                  }
               }
            ],
            "responses": {
               "200": {
                  "description": "200 response",
                  "content": {
                     "application/json": {
                        "schema": {
                           "$ref": "#/components/schemas/Empty"
                        }
                     },
                     "application/octet-stream": {
                        "schema": {
                           "$ref": "#/components/schemas/Empty"
                        }
                     }
                  }
               },
               "500": {
                  "description": "500 response"
               }
            },
            "x-amazon-apigateway-integration": {
               "credentials": "arn:aws:iam::123456789012:role/binarySupportRole",
               "responses": {
                  "default": {
                     "statusCode": "500"
                  },
                  "2\\d{2}": {
                     "statusCode": "200"
                  }
               },
               "requestParameters": {
                  "integration.request.path.key": "method.request.querystring.key"
               },
               "uri": "arn:aws:apigateway:us-west-2:s3:path/{key}",
               "passthroughBehavior": "when_no_match",
               "httpMethod": "PUT",
               "type": "aws",
               "contentHandling": "CONVERT_TO_BINARY"
            }
         }
      }
   },
   "x-amazon-apigateway-binary-media-types": [
      "application/octet-stream",
      "image/jpeg"
   ],
   "servers": [
      {
         "url": "https://abcdefghi.execute-api.us-east-1.amazonaws.com/{basePath}",
         "variables": {
            "basePath": {
              "default": "/v1"
            }
         }
      }
   ],
   "components": {
      "schemas": {
         "Empty": {
            "type": "object",
            "title": "Empty Schema"
         }
      }
   }
}
```

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

```
{
  "swagger": "2.0",
  "info": {
    "version": "2016-10-21T17:26:28Z",
    "title": "ApiName"
  },
  "host": "abcdefghi.execute-api.us-east-1.amazonaws.com",
  "basePath": "/v1",
  "schemes": [
    "https"
  ],
  "paths": {
    "/s3": {
      "get": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "key",
            "in": "query",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          },
          "500": {
            "description": "500 response"
          }
        },
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/binarySupportRole",
          "responses": {
            "default": {
              "statusCode": "500"
            },
            "2\\d{2}": {
              "statusCode": "200"            }
          },
          "requestParameters": {
            "integration.request.path.key": "method.request.querystring.key"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{key}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "GET",
          "type": "aws"
        }
      },
      "put": {
        "produces": [
          "application/json", "application/octet-stream"
        ],
        "parameters": [
          {
            "name": "key",
            "in": "query",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          },
          "500": {
            "description": "500 response"
          }
        },
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/binarySupportRole",
          "responses": {
            "default": {
              "statusCode": "500"
            },
            "2\\d{2}": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.path.key": "method.request.querystring.key"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{key}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "PUT",
          "type": "aws",
          "contentHandling" : "CONVERT_TO_BINARY"
        }
      }
    }
  },
  "x-amazon-apigateway-binary-media-types" : ["application/octet-stream", "image/jpeg"],
  "definitions": {
    "Empty": {
      "type": "object",
      "title": "Empty Schema"
    }
  }
}
```

------

## 從 Amazon S3 下載影像
<a name="api-gateway-content-encodings-example-download-image-from-s3"></a>

從 Amazon S3 下載二進位 Blob 格式的影像檔 (`image.jpg`)：

```
GET /v1/s3?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/json
Accept: application/octet-stream
```

成功回應如下所示：

```
200 OK HTTP/1.1

[raw bytes]
```

由於 `Accept` 標頭已設定為 `application/octet-stream` 的二進位媒體類型，而且啟用 API 的二進位支援，因此會傳回原始位元組。

或者，若要從 Amazon S3 下載 Base64 編碼字串 (格式化為 JSON 屬性) 格式的影像檔 (`image.jpg`)，請將回應範本新增至 200 整合回應，如下列粗體 OpenAPI 定義區塊所示：

```
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/binarySupportRole",
          "responses": {
            "default": {
              "statusCode": "500"
            },
            "2\\d{2}": {
              "statusCode": "200",
              "responseTemplates": {
                "application/json": "{\n   \"image\": \"$input.body\"\n}"
              }
            }
          },
```

要下載影像檔的請求如下所示：

```
GET /v1/s3?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/json
Accept: application/json
```

成功回應如下所示：

```
200 OK HTTP/1.1

{
  "image": "W3JhdyBieXRlc10="
}
```

## 將影像上傳至 Amazon S3
<a name="api-gateway-content-encodings-example-upload-image-to-s3"></a>

將二進位 Blob 格式的影像檔 (`image.jpg`) 上傳至 Amazon S3：

```
PUT /v1/s3?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/octet-stream
Accept: application/json

[raw bytes]
```

成功回應如下所示：

```
200 OK HTTP/1.1        
```

將 Base64 編碼字串格式的影像檔 (`image.jpg`) 上傳至 Amazon S3：

```
PUT /v1/s3?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/json
Accept: application/json

W3JhdyBieXRlc10=
```

輸入承載必須是 Base64 編碼字串，因為 `Content-Type` 標頭值已設定為 `application/json`。成功回應如下所示：

```
200 OK HTTP/1.1
```

# 使用 API Gateway API 存取 Lambda 中的二進位檔案
<a name="api-gateway-content-encodings-examples-image-lambda"></a>

下列 OpenAPI 範例示範如何 AWS Lambda 透過 API Gateway API 存取 中的二進位檔案。此 API 會公開用於下載及上傳指定影像檔的 `GET /lambda?key={file-name}` 與 `PUT /lambda?key={file-name}` 方法。`GET` 方法會在「200 OK」回應中，將 Base64 編碼字串格式的影像檔當作 JSON 輸出的一部分傳回，後面接著所提供的映射範本。`PUT` 方法接受原始二進位 Blob 作為輸入，並傳回「200 OK」回應與空的承載。

您建立 API 呼叫的 Lambda 函數，而該函數必須傳回具有 `application/json` 的 `Content-Type` 標頭的 base64 編碼字串。

**Topics**
+ [存取 Lambda 中影像之範例 API 的 OpenAPI 檔案](#api-gateway-content-encodings-example-image-lambda-swagger-file)
+ [從 Lambda 下載影像](#api-gateway-content-encodings-example-download-image-from-lambda)
+ [將影像上傳至 Lambda](#api-gateway-content-encodings-example-upload-image-to-lambda)

## 存取 Lambda 中影像之範例 API 的 OpenAPI 檔案
<a name="api-gateway-content-encodings-example-image-lambda-swagger-file"></a>

下列 OpenAPI 檔案顯示一個範例 API，說明如何從 Lambda 下載影像檔，以及如何將影像檔上傳至 Lambda。

------
#### [ OpenAPI 3.0 ]

```
{
   "openapi": "3.0.0",
   "info": {
      "version": "2016-10-21T17:26:28Z",
      "title": "ApiName"
   },
   "paths": {
      "/lambda": {
         "get": {
            "parameters": [
               {
                  "name": "key",
                  "in": "query",
                  "required": false,
                  "schema": {
                     "type": "string"
                  }
               }
            ],
            "responses": {
               "200": {
                  "description": "200 response",
                  "content": {
                     "application/json": {
                        "schema": {
                           "$ref": "#/components/schemas/Empty"
                        }
                     }
                  }
               },
               "500": {
                  "description": "500 response"
               }
            },
            "x-amazon-apigateway-integration": {
               "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:image/invocations",
               "type": "AWS",
               "credentials": "arn:aws:iam::123456789012:role/Lambda",
               "httpMethod": "POST",
               "requestTemplates": {
                  "application/json": "{\n   \"imageKey\": \"$input.params('key')\"\n}"
               },
               "responses": {
                  "default": {
                     "statusCode": "500"
                  },
                  "2\\d{2}": {
                     "statusCode": "200",
                     "responseTemplates": {
                        "application/json": "{\n   \"image\": \"$input.body\"\n}"
                     }
                  }
               }
            }
         },
         "put": {
            "parameters": [
               {
                  "name": "key",
                  "in": "query",
                  "required": false,
                  "schema": {
                     "type": "string"
                  }
               }
            ],
            "responses": {
               "200": {
                  "description": "200 response",
                  "content": {
                     "application/json": {
                        "schema": {
                           "$ref": "#/components/schemas/Empty"
                        }
                     },
                     "application/octet-stream": {
                        "schema": {
                           "$ref": "#/components/schemas/Empty"
                        }
                     }
                  }
               },
               "500": {
                  "description": "500 response"
               }
            },
            "x-amazon-apigateway-integration": {
               "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:image/invocations",
               "type": "AWS",
               "credentials": "arn:aws:iam::123456789012:role/Lambda",
               "httpMethod": "POST",
               "contentHandling": "CONVERT_TO_TEXT",
               "requestTemplates": {
                  "application/json": "{\n   \"imageKey\": \"$input.params('key')\", \"image\": \"$input.body\"\n}"
               },
               "responses": {
                  "default": {
                     "statusCode": "500"
                  },
                  "2\\d{2}": {
                     "statusCode": "200"
                  }
               }
            }
         }
      }
   },
   "x-amazon-apigateway-binary-media-types": [
      "application/octet-stream",
      "image/jpeg"
   ],
   "servers": [
      {
         "url": "https://abcdefghi.execute-api.us-east-1.amazonaws.com/{basePath}",
         "variables": {
            "basePath": {
              "default": "/v1"
            }
         }
      }
   ],
   "components": {
      "schemas": {
         "Empty": {
            "type": "object",
            "title": "Empty Schema"
         }
      }
   }
}
```

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

```
{
  "swagger": "2.0",
  "info": {
    "version": "2016-10-21T17:26:28Z",
    "title": "ApiName"
  },
  "host": "abcdefghi.execute-api.us-east-1.amazonaws.com",
  "basePath": "/v1",
  "schemes": [
    "https"
  ],
  "paths": {
    "/lambda": {
      "get": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "key",
            "in": "query",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          },
          "500": {
            "description": "500 response"
          }
        },
        "x-amazon-apigateway-integration": {
          "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:image/invocations",
          "type": "AWS",
          "credentials": "arn:aws:iam::123456789012:role/Lambda",
          "httpMethod": "POST",
          "requestTemplates": {
            "application/json": "{\n   \"imageKey\": \"$input.params('key')\"\n}"
          },
          "responses": {
            "default": {
              "statusCode": "500"
            },
            "2\\d{2}": {
              "statusCode": "200",
              "responseTemplates": {
                "application/json": "{\n   \"image\": \"$input.body\"\n}"
              }
            }
          }
        }
      },
      "put": {
        "produces": [
          "application/json", "application/octet-stream"
        ],
        "parameters": [
          {
            "name": "key",
            "in": "query",
            "required": false,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          },
          "500": {
            "description": "500 response"
          }
        },
        "x-amazon-apigateway-integration": {
          "uri": "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:123456789012:function:image/invocations",
          "type": "AWS",
          "credentials": "arn:aws:iam::123456789012:role/Lambda",
          "httpMethod": "POST",
          "contentHandling" : "CONVERT_TO_TEXT",
          "requestTemplates": {
            "application/json": "{\n   \"imageKey\": \"$input.params('key')\", \"image\": \"$input.body\"\n}"
          },
          "responses": {
            "default": {
              "statusCode": "500"
            },
            "2\\d{2}": {
              "statusCode": "200"
            }
          }
        }
      }
    }
  },
  "x-amazon-apigateway-binary-media-types" : ["application/octet-stream", "image/jpeg"],
  "definitions": {
    "Empty": {
      "type": "object",
      "title": "Empty Schema"
    }
  }
}
```

------

## 從 Lambda 下載影像
<a name="api-gateway-content-encodings-example-download-image-from-lambda"></a>

從 Lambda 下載二進位 Blob 格式的影像檔 (`image.jpg`)：

```
GET /v1/lambda?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/json
Accept: application/octet-stream
```

成功回應如下所示：

```
200 OK HTTP/1.1

[raw bytes]
```

從 Lambda 下載 Base64 編碼字串格式的影像檔 (`image.jpg`) 並格式化為 JSON 屬性：

```
GET /v1/lambda?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/json
Accept: application/json
```

成功回應如下所示：

```
200 OK HTTP/1.1

{
  "image": "W3JhdyBieXRlc10="
}
```

## 將影像上傳至 Lambda
<a name="api-gateway-content-encodings-example-upload-image-to-lambda"></a>

將二進位 Blob 格式的影像檔 (`image.jpg`) 上傳至 Lambda：

```
PUT /v1/lambda?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/octet-stream
Accept: application/json

[raw bytes]
```

成功回應如下所示：

```
200 OK            
```

將 Base64 編碼字串格式的影像檔 (`image.jpg`) 上傳至 Lambda：

```
PUT /v1/lambda?key=image.jpg HTTP/1.1
Host: abcdefghi.execute-api.us-east-1.amazonaws.com
Content-Type: application/json
Accept: application/json

W3JhdyBieXRlc10=
```

成功回應如下所示：

```
200 OK           
```

# 在 API Gateway 中調用 REST API
<a name="how-to-call-api"></a>

若要呼叫已部署的 API，用戶端會將請求提交至 API Gateway 元件服務的 URL 以執行 API (也稱為 `execute-api`)。

REST API 的基本 URL 格式如下所示：

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

其中 *api-id* 是 API 識別碼，*region* 是 AWS 區域，而 *stage* 是 API 部署的階段名稱。

**重要**  
在您可以叫用 API 之前，您必須先在 API Gateway 中部署 API。如需有關部署 API 的指示，請參閱[在 API Gateway 中部署 REST API](how-to-deploy-api.md)。

**Topics**
+ [取得 API 的調用 URL](#apigateway-how-to-call-rest-api)
+ [呼叫 API](#apigateway-call-api)
+ [使用 API Gateway 主控台來測試 REST API 方法](how-to-test-method.md)
+ [使用由 API Gateway 產生的 Java 軟體開發套件來執行 REST API](how-to-call-apigateway-generated-java-sdk.md)
+ [使用由 API Gateway 為 REST API 產生的 Android 軟體開發套件](how-to-generate-sdk-android.md)
+ [使用 API Gateway 為 REST API 所產生的 JavaScript 軟體開發套件](how-to-generate-sdk-javascript.md)
+ [使用由 API Gateway 為 REST API 產生的 Ruby 軟體開發套件](how-to-call-sdk-ruby.md)
+ [在 Objective-C 或 Swift 中使用 API Gateway 為 REST API 產生的 iOS 軟體開發套件](how-to-generate-sdk-ios.md)

## 取得 API 的調用 URL
<a name="apigateway-how-to-call-rest-api"></a>

您可以使用主控台 AWS CLI，或匯出的 OpenAPI 定義來取得 API 的調用 URL。

### 使用主控台取得 API 的調用 URL
<a name="apigateway-obtain-url-console"></a>

下列程序顯示如何在 REST API 主控台取得 API 的調用 URL。

**使用 REST API 主控台取得 API 的調用 URL**

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

1. 選擇部署的 API。

1. 從主導覽窗格選擇**階段**。

1. 在**階段詳細資訊**下，選擇複製圖示以複製 API 的調用 URL。

   此 URL 適用於 API 的根資源。  
![\[在建立 REST API 之後，主控台會顯示 API 的調用 URL。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/getting-started-rest-invoke-url.png)

1. 若要取得 API 中另一個資源的 API 調用 URL，請展開次要導覽窗格下的階段，然後選擇某個方法。

1. 選擇複製圖示以複製 API 的資源層級調用 URL。  
![\[REST API 的資源層級 URL 位於階段的次要導覽窗格下。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/resource-level-invoke-url.png)

#### 使用 AWS CLI 取得 API 的調用 URL
<a name="apigateway-obtain-url-cli"></a>

下列程序顯示如何使用 AWS CLI 取得 API 的調用 URL。

**使用 AWS CLI 取得 API 的調用 URL**

1. 使用下列命令以取得 `rest-api-id`。此命令會傳回您區域中的所有 `rest-api-id` 值。如需詳細資訊，請參閱 [get-rest-apis](https://docs.aws.amazon.com/cli/latest/reference/apigateway/get-rest-apis.html)。

   ```
   aws apigateway get-rest-apis
   ```

1. 將範例 `rest-api-id` 取代為您的 `rest-api-id`，將範例 *\$1stage-name\$1* 取代為您的 *\$1stage-name\$1*，並將 *\$1region\$1* 取代為您的區域。

   ```
   https://{restapi_id}.execute-api.{region}.amazonaws.com/{stage_name}/
   ```

##### 使用 API 的匯出 OpenAPI 定義檔以取得 API 的調用 URL
<a name="apigateway-obtain-url-openapi"></a>

您也可以合併 API 之已匯出 OpenAPI 定義檔的 `host` 與 `basePath` 欄位，藉以建構根 URL。如需有關如何匯出 API 的指示，請參閱 [從 API Gateway 匯出 REST API](api-gateway-export-api.md)。

## 呼叫 API
<a name="apigateway-call-api"></a>

您可以使用瀏覽器、curl 或其他應用程式 (例如 [Postman](https://www.postman.com/)) 呼叫已部署的 API。

此外，您可以使用 API Gateway 主控台來測試 API 呼叫。測試時會使用 API Gateway 的 `TestInvoke` 功能，其允許在部署 API 之前進行 API 測試。如需更多詳細資訊，請參閱 [使用 API Gateway 主控台來測試 REST API 方法](how-to-test-method.md)。

**注意**  
引動過程 URL 中的查詢字串參數值不能包含 `%%`。

### 使用 Web 瀏覽器調用 API
<a name="apigateway-call-api-brower"></a>

如果您的 API 允許匿名存取，您可以使用任何 Web 瀏覽器來調用任何 `GET` 方法。在瀏覽器的位址列中輸入完整的調用 URL。

對於其他方法或任何需要驗證的呼叫，您必須指定承載或簽署請求。您可以使用其中一個 AWS 軟體開發套件，在 HTML 頁面或用戶端應用程式後方的指令碼中處理這些作業。

#### 使用 curl 調用 API
<a name="apigateway-call-api-curl"></a>

您可以使用終端機中的 [curl](https://curl.se/) 等工具來呼叫 API。下列範例 curl 命令會在 API `prod` 階段的 `getUsers` 資源上調用 GET 方法。

------
#### [ Linux or Macintosh ]

```
curl -X GET 'https://b123abcde4.execute-api.us-west-2.amazonaws.com/prod/getUsers'
```

------
#### [ Windows ]

```
curl -X GET "https://b123abcde4.execute-api.us-west-2.amazonaws.com/prod/getUsers"
```

------

# 使用 API Gateway 主控台來測試 REST API 方法
<a name="how-to-test-method"></a>

使用 API Gateway 主控台來測試 REST API 方法。

**Topics**
+ [先決條件](#how-to-test-method-prerequisites)
+ [使用 API Gateway 主控台測試方法](#how-to-test-method-console)

## 先決條件
<a name="how-to-test-method-prerequisites"></a>
+ 您必須指定所要測試之方法的設定。請遵循中的說明進行[API Gateway 中 REST API 的方法](how-to-method-settings.md)

## 使用 API Gateway 主控台測試方法
<a name="how-to-test-method-console"></a>

**重要**  
使用 API Gateway 主控台測試方法可能會對資源產生無法復原的變更。使用 API Gateway 主控台測試方法與在 API Gateway 主控台之外呼叫方法是相同的。例如，如果您使用 API Gateway 主控台呼叫刪除 API 資源的方法，當方法呼叫成功時，將會刪除 API 的資源。

**若要測試方法**

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

1. 選擇 REST API。

1. 在 **Resources (資源)** 窗格中，選擇您要測試的方法。

1. 選擇**測試**標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。  
![\[使用測試標籤來測試您的 API。其位於方法回應標籤旁。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/api-gateway-test-new-console.png)

    在顯示的任何方塊 (例如**查詢字串**、**標頭**和**請求內文**) 中輸入值。主控台預設應用程式/json 表單中的方法要求包含這些值。

   如要了解可能需要指定的其他選項，請聯絡 API 擁有者。

1. 選擇 **Test (測試)**。下列資訊會隨即顯示：
   + **Request (請求)** 是針對方法所呼叫的資源路徑。
   + **Status (狀態)** 是回應的 HTTP 狀態碼。
   + **延遲 (ms)** 是從呼叫者收到請求，到傳回回應之間的時間。
   + **回應內文**是 HTTP 回應內文。
   + **回應標頭**是 HTTP 回應標頭。
**提示**  
根據映射，HTTP 狀態碼、回應內文與回應標頭可能會與 Lambda 函數、HTTP 代理或 AWS 服務代理所傳送的內容不同。
   + **Logs (日誌)** 是模擬的 Amazon CloudWatch Logs 項目，如果在 API Gateway 主控台之外呼叫此方法，將會寫入該項目。
**注意**  
雖然 CloudWatch Logs 項目是模擬的，但方法呼叫的結果是真實的。

 除了使用 API Gateway 主控台之外，您還可以使用適用於 API Gateway 的 AWS CLI 或 AWS 軟體開發套件來測試方法的叫用。若要使用 AWS CLI 來執行這項操作，請參閱 [test-invoke-method](https://docs.aws.amazon.com/cli/latest/reference/apigateway/test-invoke-method.html)。

# 使用由 API Gateway 產生的 Java 軟體開發套件來執行 REST API
<a name="how-to-call-apigateway-generated-java-sdk"></a>

在本節中，我們以[簡易計算機](simple-calc-lambda-api-swagger-definition.md) API 為例，概述使用 API Gateway 為 REST API 所產生之 Java 軟體開發套件的步驟。繼續之前，您必須完成[在 API Gateway 中為 REST API 產生 SDK](how-to-generate-sdk.md)中的步驟。

**安裝及使用 API Gateway 所產生的 Java 軟體開發套件**

1. 將您稍早下載之 API Gateway 所產生的 .zip 檔案內容解壓縮。

1. 下載並安裝 [Apache Maven](https://maven.apache.org/) (必須是 3.5 版或更新版本)。

1. 下載並安裝 [JDK 8](https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html)。

1. 設定 `JAVA_HOME` 環境變數。

1.  前往存放 pom.xml 檔案的解壓縮開發套件資料夾。此資料夾預設為 `generated-code`。執行 **mvn install** 命令，將已編譯的成品檔案安裝到您的本機 Maven 儲存庫。這會建立 `target` 資料夾，其中包含已編譯的開發套件程式庫。

1.  在空目錄中輸入下列命令建立用戶端專案 Stub，以使用安裝的開發套件程式庫呼叫 API。

   ```
   mvn -B archetype:generate \
       -DarchetypeGroupdId=org.apache.maven.archetypes \
       -DgroupId=examples.aws.apig.simpleCalc.sdk.app \
       -DartifactId=SimpleCalc-sdkClient
   ```
**注意**  
 上述命令中加入了分隔符號 `\` 以利閱讀。整個命令應該放在一行且不使用分隔符號。

    此命令會建立應用程式 Stub。應用程式 Stub 在專案根目錄 (上述命令中的 *SimpleCalc-sdkClient*) 下包含 `pom.xml` 檔案與 `src` 資料夾。一開始有兩個來源檔案：`src/main/java/{package-path}/App.java` 與 `src/test/java/{package-path}/AppTest.java`。在此範例中，*\$1package-path\$1* 是 `examples/aws/apig/simpleCalc/sdk/app`。此套件路徑衍生自 `DarchetypeGroupdId` 值。您可以使用 `App.java` 檔案作為用戶端應用程式的範本，而且您可以視需要在相同的資料夾中新增其他檔案。您可以使用 `AppTest.java` 檔案作為應用程式的單元測試範本，而且您可以視需要將其他測試程式碼檔案新增至相同的測試資料夾。

1. 將所產生 `pom.xml` 檔案中的套件相依性更新為以下內容，並視需要替代成您專案的 `groupId`、`artifactId`、`version` 與 `name` 屬性：

   ```
   <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>examples.aws.apig.simpleCalc.sdk.app</groupId>
     <artifactId>SimpleCalc-sdkClient</artifactId>
     <packaging>jar</packaging>
     <version>1.0-SNAPSHOT</version>
     <name>SimpleCalc-sdkClient</name>
     <url>http://maven.apache.org</url>
   
      <dependencies>
         <dependency>
             <groupId>com.amazonaws</groupId>
             <artifactId>aws-java-sdk-core</artifactId>
             <version>1.11.94</version>
         </dependency>
         <dependency>
             <groupId>my-apig-api-examples</groupId>
             <artifactId>simple-calc-sdk</artifactId>
             <version>1.0.0</version>
         </dependency>
         
       <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>4.12</version>
         <scope>test</scope>
       </dependency>
   
       <dependency>
           <groupId>commons-io</groupId>
           <artifactId>commons-io</artifactId>
           <version>2.5</version>
       </dependency>    
     </dependencies>
   
     <build>
       <plugins>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-compiler-plugin</artifactId>
           <version>3.5.1</version>
           <configuration>
             <source>1.8</source>
             <target>1.8</target>
           </configuration>
         </plugin>
       </plugins>
     </build>
   </project>
   ```
**注意**  
 如果 `aws-java-sdk-core` 的相依成品有較新版本與以上指定的版本 (`1.11.94`) 不相容，則必須將 `<version>` 標籤更新為較新版本。

1.  接下來，我們將示範如何透過呼叫開發套件的 `getABOp(GetABOpRequest req)`、`getApiRoot(GetApiRootRequest req)` 與 `postApiRoot(PostApiRootRequest req)` 方法，使用開發套件來呼叫 API。這些方法分別對應到具有 `GET /{a}/{b}/{op}` API 請求承載的 `GET /?a={x}&b={y}&op={operator}`、`POST /` 與 `{"a": x, "b": y, "op": "operator"}` 方法。

    請更新 `App.java` 檔案如下：

   ```
   package examples.aws.apig.simpleCalc.sdk.app;
   
   import java.io.IOException;
   
   import com.amazonaws.opensdk.config.ConnectionConfiguration;
   import com.amazonaws.opensdk.config.TimeoutConfiguration;
   
   import examples.aws.apig.simpleCalc.sdk.*;
   import examples.aws.apig.simpleCalc.sdk.model.*;
   import examples.aws.apig.simpleCalc.sdk.SimpleCalcSdk.*;
   
   public class App 
   {
       SimpleCalcSdk sdkClient;
   
       public App() {
           initSdk();
       }
   
       // The configuration settings are for illustration purposes and may not be a recommended best practice.
       private void initSdk() {
           sdkClient = SimpleCalcSdk.builder()
                 .connectionConfiguration(
                     new ConnectionConfiguration()
                           .maxConnections(100)
                           .connectionMaxIdleMillis(1000))
                 .timeoutConfiguration(
                     new TimeoutConfiguration()
                           .httpRequestTimeout(3000)
                           .totalExecutionTimeout(10000)
                           .socketTimeout(2000))
           .build();
   
       }
       // Calling shutdown is not necessary unless you want to exert explicit control of this resource.
       public void shutdown() {
           sdkClient.shutdown();
       }
        
       // GetABOpResult getABOp(GetABOpRequest getABOpRequest)
       public Output getResultWithPathParameters(String x, String y, String operator) {
       	operator = operator.equals("+") ? "add" : operator;
       	operator = operator.equals("/") ? "div" : operator; 
   
           GetABOpResult abopResult = sdkClient.getABOp(new GetABOpRequest().a(x).b(y).op(operator));
           return abopResult.getResult().getOutput();
       }
   
       public Output getResultWithQueryParameters(String a, String b, String op) {
           GetApiRootResult rootResult = sdkClient.getApiRoot(new GetApiRootRequest().a(a).b(b).op(op));
           return rootResult.getResult().getOutput();
       }
   
       public Output getResultByPostInputBody(Double x, Double y, String o) {
       	PostApiRootResult postResult = sdkClient.postApiRoot(
       		new PostApiRootRequest().input(new Input().a(x).b(y).op(o)));
       	return postResult.getResult().getOutput();
       }
   
       public static void main( String[] args )
       {
           System.out.println( "Simple calc" );
           // to begin
           App calc = new App();
           
           // call the SimpleCalc API
           Output res = calc.getResultWithPathParameters("1", "2", "-");
           System.out.printf("GET /1/2/-: %s\n", res.getC());
   
           // Use the type query parameter
           res = calc.getResultWithQueryParameters("1", "2", "+");
           System.out.printf("GET /?a=1&b=2&op=+: %s\n", res.getC());
   
           // Call POST with an Input body.
           res = calc.getResultByPostInputBody(1.0, 2.0, "*");
           System.out.printf("PUT /\n\n{\"a\":1, \"b\":2,\"op\":\"*\"}\n %s\n", res.getC());
   
           
       }
   }
   ```

    在上述範例中，用來執行個體化開發套件用戶端的組態設定僅供說明，不一定是建議的最佳實務。此外，呼叫 `sdkClient.shutdown()` 是選擇性的，特別是如果您需要精確控制何時釋放資源。

 我們已示範使用 Java 開發套件呼叫 API 的基本模式。您可以延伸說明來呼叫其他 API 方法。

# 使用由 API Gateway 為 REST API 產生的 Android 軟體開發套件
<a name="how-to-generate-sdk-android"></a>

在本節中，我們將概述使用 API Gateway 為 REST API 所產生之 Android 軟體開發套件的步驟。您必須已完成[在 API Gateway 中為 REST API 產生 SDK](how-to-generate-sdk.md)中的步驟，才能繼續往下進行。

**注意**  
 所產生的開發套件與 Android 4.4 (含) 以前的版本不相容。如需詳細資訊，請參閱 [Amazon API Gateway 重要說明](api-gateway-known-issues.md)。

**安裝及使用 API Gateway 所產生的 Android 軟體開發套件**

1. 將您稍早下載之 API Gateway 所產生的 .zip 檔案內容解壓縮。

1. 下載並安裝 [Apache Maven](https://maven.apache.org/) (最好是 3.x 版)。

1. 下載並安裝 [JDK 8](https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html)。

1. 設定 `JAVA_HOME` 環境變數。

1. 執行 **mvn install** 命令，將已編譯的成品檔案安裝到您的本機 Maven 儲存庫。這會建立 `target` 資料夾，其中包含已編譯的開發套件程式庫。

1. 將 `target` 資料夾中的開發套件檔案 (其名稱衍生自您在產生開發套件時所指定的 **Artifact Id** (成品 ID) 與 **Artifact Version** (成品版本)，例如 `simple-calcsdk-1.0.0.jar`)，連同 `target/lib` 資料夾中的所有其他程式庫，一起複製到您專案的 `lib` 資料夾中。

   如果您使用 Android Studio，請在您的用戶端應用程式模組下建立一個 `libs` 資料夾，然後將必要的 .jar 檔案複製到此資料夾中。確認模組之 Gradle 檔案中的相依性區段包含以下內容。

   ```
       compile fileTree(include: ['*.jar'], dir: 'libs')
       compile fileTree(include: ['*.jar'], dir: 'app/libs')
   ```

   確定未宣告重複的 .jar 檔案。

1. 使用 `ApiClientFactory` 類別來初始化 API Gateway 產生的軟體開發套件。例如：

   ```
   ApiClientFactory factory = new ApiClientFactory();
   
   // Create an instance of your SDK. Here, 'SimpleCalcClient.java' is the compiled java class for the SDK generated by API Gateway. 
   final SimpleCalcClient client = factory.build(SimpleCalcClient.class);
   
   // Invoke a method: 
   //   For the 'GET /?a=1&b=2&op=+' method exposed by the API, you can invoke it by calling the following SDK method:
   
   Result output = client.rootGet("1", "2", "+");
   
   //     where the Result class of the SDK corresponds to the Result model of the API.
   //
   
   //   For the 'GET /{a}/{b}/{op}'  method exposed by the API, you can call the following SDK method to invoke the request,
   
   Result output = client.aBOpGet(a, b, c);
   
   //     where a, b, c can be "1", "2", "add", respectively.
   
   //   For the following API method:
   //        POST /
   //        host: ...
   //        Content-Type: application/json
   //    
   //        { "a": 1, "b": 2, "op": "+" }
   // you can call invoke it by calling the rootPost method of the SDK as follows:
   Input body = new Input();
   input.a=1;
   input.b=2;
   input.op="+";
   Result output = client.rootPost(body);
   
   //      where the Input class of the SDK corresponds to the Input model of the API.
   
   // Parse the result:
   //     If the 'Result' object is { "a": 1, "b": 2, "op": "add", "c":3"}, you retrieve the result 'c') as 
   
   String result=output.c;
   ```

1. 若要使用 Amazon Cognito 憑證提供者授權呼叫您的 API，請使用 `ApiClientFactory` 類別透過 API Gateway 所產生的軟體開發套件來傳遞一組 AWS 憑證，如下列範例所示。

   ```
   // Use CognitoCachingCredentialsProvider to provide AWS credentials
   // for the ApiClientFactory
   AWSCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
           context,          // activity context
           "identityPoolId", // Cognito identity pool id
           Regions.US_EAST_1 // region of Cognito identity pool
   );
   
   ApiClientFactory factory = new ApiClientFactory()
     .credentialsProvider(credentialsProvider);
   ```

1. 若要使用 API Gateway 所產生的軟體開發套件來設定 API 金鑰，請使用類似如下的程式碼。

   ```
   ApiClientFactory factory = new ApiClientFactory()
     .apiKey("YOUR_API_KEY");
   ```

# 使用 API Gateway 為 REST API 所產生的 JavaScript 軟體開發套件
<a name="how-to-generate-sdk-javascript"></a>

下列程序顯示如何使用 API Gateway 產生的 JavaScript SDK。

**注意**  
這些說明假設您已完成[在 API Gateway 中為 REST API 產生 SDK](how-to-generate-sdk.md)中的指示。

**重要**  
如果您的 API 只定義了 ANY 方法，則產生的軟體開發套件將不會包含 `apigClient.js` 檔案，而且您將需要自行定義 ANY 方法。

**安裝、啟動及呼叫 API Gateway 為 REST API 所產生的 JavaScript 軟體開發套件**

1. 將您稍早下載之 API Gateway 所產生的 .zip 檔案內容解壓縮。

1. 針對 API Gateway 所產生之軟體開發套件將會呼叫的所有方法，啟用跨來源資源分享 (CORS)。如需說明，請參閱[API Gateway 中 REST API 的 CORS](how-to-cors.md)。

1. 在您的網頁中，包含下列指令碼的參考。

   ```
   <script type="text/javascript" src="lib/axios/dist/axios.standalone.js"></script>
   <script type="text/javascript" src="lib/CryptoJS/rollups/hmac-sha256.js"></script>
   <script type="text/javascript" src="lib/CryptoJS/rollups/sha256.js"></script>
   <script type="text/javascript" src="lib/CryptoJS/components/hmac.js"></script>
   <script type="text/javascript" src="lib/CryptoJS/components/enc-base64.js"></script>
   <script type="text/javascript" src="lib/url-template/url-template.js"></script>
   <script type="text/javascript" src="lib/apiGatewayCore/sigV4Client.js"></script>
   <script type="text/javascript" src="lib/apiGatewayCore/apiGatewayClient.js"></script>
   <script type="text/javascript" src="lib/apiGatewayCore/simpleHttpClient.js"></script>
   <script type="text/javascript" src="lib/apiGatewayCore/utils.js"></script>
   <script type="text/javascript" src="apigClient.js"></script>
   ```

1. 在您的程式碼中，使用類似如下的程式碼來初始化 API Gateway 所產生的軟體開發套件。

   ```
   var apigClient = apigClientFactory.newClient();
   ```

   若要使用 AWS 登入資料初始化 API Gateway 產生的 SDK，請使用類似以下的程式碼。如果您使用 AWS 登入資料，對 API 的所有請求都會簽署。

   ```
   var apigClient = apigClientFactory.newClient({
     accessKey: 'ACCESS_KEY',
     secretKey: 'SECRET_KEY',
   });
   ```

   若要搭配 API Gateway 所產生的軟體開發套件使用 API 金鑰，請使用類似如下的程式碼，將 API 金鑰當做參數傳遞給 `Factory` 物件。如果您使用 API 金鑰，則會將它指定為 `x-api-key` 標頭的一部分，而且 API 的所有請求都會經過簽署。這表示您必須為每個請求設定適當的 CORS Accept 標頭。

   ```
   var apigClient = apigClientFactory.newClient({
     apiKey: 'API_KEY'
   });
   ```

   

1. 使用類似如下的程式碼，在 API Gateway 中呼叫 API 方法。每個呼叫會傳回成功與失敗回呼的結果。

   ```
   var params = {
     // This is where any modeled request parameters should be added.
     // The key is the parameter name, as it is defined in the API in API Gateway.
     param0: '',
     param1: ''
   };
   
   var body = {
     // This is where you define the body of the request,
   };
   
   var additionalParams = {
     // If there are any unmodeled query parameters or headers that must be
     //   sent with the request, add them here.
     headers: {
       param0: '',
       param1: ''
     },
     queryParams: {
       param0: '',
       param1: ''
     }
   };
   
   apigClient.methodName(params, body, additionalParams)
       .then(function(result){
         // Add success callback code here.
       }).catch( function(result){
         // Add error callback code here.
       });
   ```

   此處，*methodName* 是從方法請求的資源路徑與 HTTP 動詞建構而來。對於 SimpleCalc API，開發套件方法用於 API 方法 

   ```
   1. GET /?a=...&b=...&op=...
   2. POST /
   
      { "a": ..., "b": ..., "op": ...}
   3. GET /{a}/{b}/{op}
   ```

   對應的開發套件方法如下所示：

   ```
   1. rootGet(params);      // where params={"a": ..., "b": ..., "op": ...} is resolved to the query parameters
   2. rootPost(null, body); // where body={"a": ..., "b": ..., "op": ...}
   3. aBOpGet(params);      // where params={"a": ..., "b": ..., "op": ...} is resolved to the path parameters
   ```

   

# 使用由 API Gateway 為 REST API 產生的 Ruby 軟體開發套件
<a name="how-to-call-sdk-ruby"></a>

下列程序顯示如何使用 API Gateway 產生的 Ruby SDK。

**注意**  
這些說明假設您已完成「[在 API Gateway 中為 REST API 產生 SDK](how-to-generate-sdk.md)」中的說明。

**安裝、執行個體化和呼叫 API Gateway 為 REST API 產生的 Ruby 軟體開發套件**

1. 解壓縮下載的 Ruby 開發套件檔案。產生的開發套件來源如下所示。  
![\[將下載的 Ruby 開發套件檔案解壓縮到 Ruby 模組\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/ruby-gem-of-generated-sdk-for-simplecalc.png)

   

1.  在終端機視窗中使用以下 shell 命令，從產生的開發套件來源建立 Ruby Gem：

   ```
   # change to /simplecalc-sdk directory
   cd simplecalc-sdk
   
   # build the generated gem
   gem build simplecalc-sdk.gemspec
   ```

   在此之後，**simplecalc-sdk-1.0.0.gem** 即可使用。

1.  安裝 gem：

   ```
   gem install simplecalc-sdk-1.0.0.gem
   ```

1.  建立用戶端應用程式。在應用程式中執行個體化和初始化 Ruby 開發套件用戶端：

   ```
   require 'simplecalc-sdk'
   client = SimpleCalc::Client.new(
       http_wire_trace: true,
       retry_limit: 5,
       http_read_timeout: 50
   )
   ```

   如果 API 已設定 `AWS_IAM`類型的授權，您可以在初始化`secretKey`期間提供 `accessKey`和 來包含發起人的 AWS 登入資料：

   ```
   require 'pet-sdk'
   client = Pet::Client.new(
       http_wire_trace: true,
       retry_limit: 5,
       http_read_timeout: 50,
       access_key_id: 'ACCESS_KEY',
       secret_access_key: 'SECRET_KEY'
   )
   ```

1.  在應用程式中透過開發套件呼叫 API。
**提示**  
 如果您不熟悉開發套件方法呼叫慣例，您可以參閱產生的開發套件 `client.rb` 資料夾中的 `lib` 檔案。此資料夾包含每個受支援 API 方法呼叫的文件。

   探索受支援的操作：

   ```
   # to show supported operations:
   puts client.operation_names
   ```

   這會產生以下顯示畫面，分別對應到 `GET /?a={.}&b={.}&op={.}`、`GET /{a}/{b}/{op}` 和 `POST /` 的 API 方法，加上 `{a:"…", b:"…", op:"…"}` 格式的承載：

   ```
   [:get_api_root, :get_ab_op, :post_api_root]
   ```

   若要呼叫 `GET /?a=1&b=2&op=+` API 方法，請呼叫以下 Ruby 開發套件方法：

   ```
   resp = client.get_api_root({a:"1", b:"2", op:"+"})
   ```

   若要呼叫 `POST /` API 方法加上 `{a: "1", b: "2", "op": "+"}` 承載，請呼叫以下 Ruby 開發套件方法：

   ```
   resp = client.post_api_root(input: {a:"1", b:"2", op:"+"})
   ```

   若要呼叫 `GET /1/2/+` API 方法，請呼叫以下 Ruby 開發套件方法：

   ```
   resp = client.get_ab_op({a:"1", b:"2", op:"+"})
   ```

   成功的開發套件方法呼叫傳回以下回應：

   ```
   resp : {
       result: {
           input: {
               a: 1,
               b: 2,
               op: "+"
           },
           output: {
               c: 3
           }
       }
   }
   ```

# 在 Objective-C 或 Swift 中使用 API Gateway 為 REST API 產生的 iOS 軟體開發套件
<a name="how-to-generate-sdk-ios"></a>

在本教學中，我們會示範如何在 Objective-C 或 Swift 應用程式中，使用 API Gateway 為 REST API 產生的 iOS 軟體開發套件，以呼叫基礎 API。我們會以 [SimpleCalc API](simple-calc-lambda-api.md) 為例，說明下列主題：
+ 如何在 Xcode 專案中安裝所需的 AWS Mobile SDK 元件
+ 如何在呼叫 API 的方法前，先建立 API 用戶端物件
+ 如何透過 API 用戶端物件上對應的開發套件方法呼叫 API 方法
+ 如何使用開發套件的對應模型類別準備方法輸入和剖析其結果

**Topics**
+ [使用產生的 iOS 開發套件 (Objective-C) 呼叫 API](#how-to-use-sdk-ios-objc)
+ [使用產生的 iOS 開發套件 (Swift) 呼叫 API](#how-to-generate-sdk-ios-swift)

## 使用產生的 iOS 開發套件 (Objective-C) 呼叫 API
<a name="how-to-use-sdk-ios-objc"></a>

開始下列程序之前，您必須先在 Objective-C 中完成[在 API Gateway 中為 REST API 產生 SDK](how-to-generate-sdk.md)中的 iOS 步驟，並下載已產生之軟體開發套件的 .zip 檔案。

### 在 Objective-C 專案中安裝由 API Gateway 產生的 AWS 行動 SDK 和 iOS SDK
<a name="use-sdk-ios-objc-install-sdk"></a>

下列程序說明如何安裝開發套件。

**安裝和使用 API Gateway 在 Objective-C 中產生的 iOS 軟體開發套件**

1. 將您稍早下載之 API Gateway 所產生的 .zip 檔案內容解壓縮。使用 [SimpleCalc API](simple-calc-lambda-api.md)，您可能希望將解壓縮的開發套件資料夾重新命名成類似 **sdk\$1objc\$1simple\$1calc**。在這個開發套件資料夾中，有 `README.md` 檔案和 `Podfile` 檔案。`README.md` 檔案包含開發套件的安裝和使用說明。本教學提供這些說明的詳細資訊。安裝利用 [CocoaPods](https://cocoapods.org) 匯入所需的 API Gateway 程式庫和其他相依 AWS 的 Mobile SDK 元件。您必須更新 `Podfile`，將開發套件匯入至您應用程式的 Xcode 專案。未封存的開發套件資料夾也包含 `generated-src` 資料夾，其中包含 API 之已產生開發套件的原始程式碼。

1. 啟動 Xcode 並建立新的 iOS Objective-C 專案。請記下專案的目標。您需要在 `Podfile` 中設定它。

      
![\[在 Xcode 中尋找目標。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/use-sdk-in-ios-objc-project-find-target.png)

1. 若要使用 CocoaPods AWS Mobile SDK for iOS 將 匯入 Xcode 專案，請執行下列動作：

   1. 在終端機視窗中執行下列命令來安裝 CocoaPods：

      ```
      sudo gem install cocoapods
      pod setup
      ```

   1. 將 `Podfile` 檔案從解壓縮開發套件資料夾複製至包含 Xcode 專案檔的相同目錄。將下列區塊：

      ```
      target '<YourXcodeTarget>' do
          pod 'AWSAPIGateway', '~> 2.4.7'
      end
      ```

      使用您專案的目標名稱：

      ```
      target 'app_objc_simple_calc' do
          pod 'AWSAPIGateway', '~> 2.4.7'
      end
      ```

      如果您的 Xcode 專案已包含一個名為 `Podfile` 的檔案，請將下行程式碼新增到此檔案：

      ```
      pod 'AWSAPIGateway', '~> 2.4.7'
      ```

   1. 開啟終端機視窗並執行下列命令：

      ```
      pod install
      ```

      這會安裝 API Gateway 元件和其他相依的 AWS Mobile SDK 元件。

   1. 關閉 Xcode 專案，然後開啟 `.xcworkspace` 檔案重新啟動 Xcode。

   1. 從解壓縮的開發套件 `.h` 目錄將所有的 `.m` 和 `generated-src` 檔案新增到您的 Xcode 專案。

         
![\[.h 和 .m 檔案位於產生的來源中\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/use-sdk-in-ios-objc-project-add-sdk-src.png)

   若要透過明確下載 AWS Mobile SDK 或使用 [Carthage](https://github.com/Carthage/Carthage#installing-carthage) 將 AWS Mobile SDK for iOS Objective-C 匯入您的專案，請遵循 *README.md* 檔案中的指示。請務必僅使用其中一個選項來匯入 AWS Mobile SDK。

### 使用 Objective-C 專案中 API Gateway 產生的 iOS 軟體開發套件呼叫 API 方法
<a name="use-sdk-ios-objc-call-sdk"></a>

當您使用兩個模型來處理這些方法的輸入 (`SIMPLE_CALC`) 和輸出 (`Input`)，為這個 [SimpleCalc API](simple-calc-lambda-api.md) 產生字首為 `Result` 的開發套件後，在開發套件中，產生的 API 用戶端類別會變為 `SIMPLE_CALCSimpleCalcClient`，而對應的資料類別則會分別成為 `SIMPLE_CALCInput` 和 `SIMPLE_CALCResult`。API 請求和回應會對應至開發套件方法，如下所示：
+ 下列的 API 請求：

  ```
  GET /?a=...&b=...&op=...
  ```

  會成為下列的開發套件方法：

  ```
  (AWSTask *)rootGet:(NSString *)op a:(NSString *)a b:(NSString *)b
  ```

  如果 `AWSTask.result` 模型已新增至方法回應，則 `SIMPLE_CALCResult` 屬性為 `Result` 類型。否則，屬性為 `NSDictionary` 類型。
+ 下列的此 API 請求：

  ```
  POST /
      
  {
     "a": "Number",
     "b": "Number",
     "op": "String"
  }
  ```

  會成為下列的開發套件方法：

  ```
  (AWSTask *)rootPost:(SIMPLE_CALCInput *)body
  ```
+ 下列的 API 請求：

  ```
  GET /{a}/{b}/{op}
  ```

  會成為下列的開發套件方法：

  ```
  (AWSTask *)aBOpGet:(NSString *)a b:(NSString *)b op:(NSString *)op
  ```

下列程序說明如何在 Objective-C 應用程式原始碼中呼叫 API 方法；例如，在 `viewDidLoad` 檔案中作為 `ViewController.m` 委派的一部分。

**透過 API Gateway 所產生的 iOS 軟體開發套件來呼叫 API**

1. 匯入 API 用戶端類別標頭檔案，以能在應用程式中呼叫 API 用戶端類別：

   ```
   #import "SIMPLE_CALCSimpleCalc.h"
   ```

   `#import` 陳述式也針對兩個模型類別匯入 `SIMPLE_CALCInput.h` 和 `SIMPLE_CALCResult.h`。

1. 將 API 用戶端類別執行個體化：

   ```
   SIMPLE_CALCSimpleCalcClient *apiInstance = [SIMPLE_CALCSimpleCalcClient defaultClient];
   ```

   若要使用 Amazon Cognito 與 API，請先在預設的 `AWSServiceManager` 物件上設定 `defaultServiceConfiguration` 屬性，如下所示，然後呼叫 `defaultClient` 方法以建立 API 用戶端物件 (如前例所示)：

   ```
   AWSCognitoCredentialsProvider *creds = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1 identityPoolId:your_cognito_pool_id];
   AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:creds];
   AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;
   ```

1. 呼叫 `GET /?a=1&b=2&op=+` 方法來執行 `1+2`：

   ```
   [[apiInstance rootGet: @"+" a:@"1" b:@"2"] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) {
       _textField1.text = [self handleApiResponse:task];
       return nil;
   }];
   ```

   協助程式函數 `handleApiResponse:task` 會在此將結果格式化為字串並顯示在文字欄位中 (`_textField1`)。

   ```
   - (NSString *)handleApiResponse:(AWSTask *)task {
       if (task.error != nil) {
           return [NSString stringWithFormat: @"Error: %@", task.error.description];
       } else if (task.result != nil && [task.result isKindOfClass:[SIMPLE_CALCResult class]]) {
           return [NSString stringWithFormat:@"%@ %@ %@ = %@\n",task.result.input.a, task.result.input.op, task.result.input.b, task.result.output.c];
       }
       return nil;
   }
   ```

   產生的顯示畫面為 `1 + 2 = 3`。

1. 呼叫具有承載的 `POST /` 來執行 `1-2`：

   ```
   SIMPLE_CALCInput *input = [[SIMPLE_CALCInput alloc] init];
       input.a = [NSNumber numberWithInt:1];
       input.b = [NSNumber numberWithInt:2];
       input.op = @"-";
       [[apiInstance rootPost:input] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) {
           _textField2.text = [self handleApiResponse:task];
           return nil;
       }];
   ```

   產生的顯示畫面為 `1 - 2 = -1`。

1. 呼叫 `GET /{a}/{b}/{op}` 來執行 `1/2`：

   ```
   [[apiInstance aBOpGet:@"1" b:@"2" op:@"div"] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) {
       _textField3.text = [self handleApiResponse:task];
       return nil;
   }];
   ```

   產生的顯示畫面為 `1 div 2 = 0.5`。在此，`div` 用來代替 `/`，因為後端的[簡單 Lambda 函數](simple-calc-nodejs-lambda-function.md)不處理 URL 編碼的路徑變數。

## 使用產生的 iOS 開發套件 (Swift) 呼叫 API
<a name="how-to-generate-sdk-ios-swift"></a>

開始下列程序之前，您必須先在 Swift 中完成[在 API Gateway 中為 REST API 產生 SDK](how-to-generate-sdk.md)中的 iOS 步驟，並下載已產生之軟體開發套件的 .zip 檔案。

**Topics**
+ [在 Swift 專案中安裝 AWS 行動 SDK 和 API Gateway 產生的 SDK](#use-sdk-ios-swift-install-sdk)
+ [在 Swift 專案中透過 API Gateway 所產生的 iOS 軟體開發套件來呼叫 API 方法](#use-sdk-ios-swift-call-api)

### 在 Swift 專案中安裝 AWS 行動 SDK 和 API Gateway 產生的 SDK
<a name="use-sdk-ios-swift-install-sdk"></a>

下列程序說明如何安裝開發套件。

**安裝和使用 API Gateway 在 Swift 中產生的 iOS 軟體開發套件**

1. 將您稍早下載之 API Gateway 所產生的 .zip 檔案內容解壓縮。使用 [SimpleCalc API](simple-calc-lambda-api.md)，您可能希望將解壓縮的開發套件資料夾重新命名成類似 **sdk\$1swift\$1simple\$1calc**。在這個開發套件資料夾中，有 `README.md` 檔案和 `Podfile` 檔案。`README.md` 檔案包含開發套件的安裝和使用說明。本教學提供這些說明的詳細資訊。安裝會利用 [CocoaPods](https://cocoapods.org) 來匯入所需的 AWS Mobile 開發套件元件。您必須更新 `Podfile`，以將開發套件匯入至您 Swift 應用程式的 Xcode 專案。未封存的開發套件資料夾也包含 `generated-src` 資料夾，其中包含 API 之已產生開發套件的原始程式碼。

1. 啟動 Xcode 並建立新的 iOS Swift 專案。請記下專案的目標。您需要在 `Podfile` 中設定它。

      
![\[在 Xcode 中尋找目標。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/use-sdk-in-ios-swift-project-find-target.png)

1. 若要使用 CocoaPods 將所需的 AWS Mobile SDK 元件匯入 Xcode 專案，請執行下列動作：

   1. 如果未安裝，請在終端機視窗中執行下列命令來安裝 CocoaPods：

      ```
      sudo gem install cocoapods
      pod setup
      ```

   1. 將 `Podfile` 檔案從解壓縮開發套件資料夾複製至包含 Xcode 專案檔的相同目錄。將下列區塊：

      ```
      target '<YourXcodeTarget>' do
          pod 'AWSAPIGateway', '~> 2.4.7'
      end
      ```

      取代為您專案的目標名稱，如下所示：

      ```
      target 'app_swift_simple_calc' do
          pod 'AWSAPIGateway', '~> 2.4.7'
      end
      ```

      如果您的 Xcode 專案已包含具有正確目標的 `Podfile`，您可以只將下列程式碼行新增至 `do ... end` 迴圈：

      ```
      pod 'AWSAPIGateway', '~> 2.4.7'
      ```

   1. 開啟終端機視窗，並在應用程式目錄中執行下列命令：

      ```
      pod install
      ```

      這會將 API Gateway 元件和任何相依的 AWS Mobile SDK 元件安裝到應用程式的專案中。

   1. 關閉 Xcode 專案，然後開啟 `*.xcworkspace` 檔案重新啟動 Xcode。

   1. 將所有開發套件的標頭檔案 (`.h`) 和 Swift 原始程式碼檔案 (`.swift`) 從擷取的 `generated-src` 目錄新增至 Xcode 專案。

         
![\[.h 和 .swift 檔案位於產生的來源中\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/use-sdk-in-ios-swift-project-add-sdk-src.png)

   1. 若要啟用從 Swift 程式碼專案呼叫 AWS Mobile SDK 的 Objective-C 程式庫，請在您 Xcode 專案組態的 **Swift 編譯器 - 一般**設定下，在 **Objective-C 橋接標頭**屬性上設定`Bridging_Header.h`檔案路徑：

         
![\[在「Swift 編譯器 - 一般」下，設定 Bridging_Header.h 檔案路徑。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/use-sdk-in-ios-swift-project-set-bridging-header.png)
**提示**  
您可以在 Xcode 的搜尋方塊中輸入 **bridging**，以尋找 **Objective-C Bridging Header (Objective-C 橋接標頭)** 屬性。

   1. 建置 Xcode 專案，驗證已正確地設定它，再繼續進行。如果您的 Xcode 使用的 Swift 版本比 AWS Mobile SDK 支援的版本更新，您會收到 Swift 編譯器錯誤。在這種情況下，於 **Swift Compiler - Version (Swift 編譯器 - 版本)** 設定下方，將 **Use Legacy Swift Language Version (使用傳統 Swift 語言版本)** 屬性設定為 **Yes (是)**：

         
![\[將 Legacy Swift 語言版本屬性設定為「是」。\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/use-sdk-in-ios-swift-project-set-legacy-swift-version.png)

   若要透過明確下載 AWS Mobile SDK 或使用 [Carthage](https://github.com/Carthage/Carthage#installing-carthage) 將適用於 iOS 的 AWS Mobile SDK 匯入您的專案，請遵循 SDK 套件隨附的 `README.md` 檔案中的指示。請務必僅使用其中一個選項來匯入 AWS Mobile SDK。

### 在 Swift 專案中透過 API Gateway 所產生的 iOS 軟體開發套件來呼叫 API 方法
<a name="use-sdk-ios-swift-call-api"></a>

當您使用兩個模型說明 API 請求和回應的輸入 (`Input`) 和輸出 (`Result`)，為這個 [SimpleCalc API](simple-calc-lambda-api.md) 產生字首為 `SIMPLE_CALC` 的開發套件後，在開發套件中，產生的 API 用戶端類別會變為 `SIMPLE_CALCSimpleCalcClient`，而對應的資料類別則會分別成為 `SIMPLE_CALCInput` 和 `SIMPLE_CALCResult`。API 請求和回應會對應至開發套件方法，如下所示：
+ 下列的 API 請求：

  ```
  GET /?a=...&b=...&op=...
  ```

  會成為下列的開發套件方法：

  ```
  public func rootGet(op: String?, a: String?, b: String?) -> AWSTask
  ```

  如果 `AWSTask.result` 模型已新增至方法回應，則 `SIMPLE_CALCResult` 屬性為 `Result` 類型。否則，它為 `NSDictionary` 類型。
+ 下列的此 API 請求：

  ```
  POST /
      
  {
     "a": "Number",
     "b": "Number",
     "op": "String"
  }
  ```

  會成為下列的開發套件方法：

  ```
  public func rootPost(body: SIMPLE_CALCInput) -> AWSTask
  ```
+ 下列的 API 請求：

  ```
  GET /{a}/{b}/{op}
  ```

  會成為下列的開發套件方法：

  ```
  public func aBOpGet(a: String, b: String, op: String) -> AWSTask
  ```

下列程序說明如何在 Swift 應用程式原始碼中呼叫 API 方法；例如，在 `viewDidLoad()` 檔案中做為 `ViewController.m` 委派的一部分。

**透過 API Gateway 所產生的 iOS 軟體開發套件來呼叫 API**

1. 將 API 用戶端類別執行個體化：

   ```
   let client = SIMPLE_CALCSimpleCalcClient.default()
   ```

   若要搭配 API 使用 Amazon Cognito，請先設定預設 AWS 服務組態 （如下所示），再取得`default`方法 （如先前所示）：

   ```
   let credentialsProvider = AWSCognitoCredentialsProvider(regionType: AWSRegionType.USEast1, identityPoolId: "my_pool_id")        
   let configuration = AWSServiceConfiguration(region: AWSRegionType.USEast1, credentialsProvider: credentialsProvider)        
   AWSServiceManager.defaultServiceManager().defaultServiceConfiguration = configuration
   ```

1. 呼叫 `GET /?a=1&b=2&op=+` 方法來執行 `1+2`：

   ```
   client.rootGet("+", a: "1", b:"2").continueWithBlock {(task: AWSTask) -> AnyObject? in
       self.showResult(task)
       return nil
   }
   ```

   其中，helper 函數 `self.showResult(task)` 會將結果或錯誤列印至主控台，例如：

   ```
   func showResult(task: AWSTask) {
       if let error = task.error {
           print("Error: \(error)")
       } else if let result = task.result {
           if result is SIMPLE_CALCResult {
               let res = result as! SIMPLE_CALCResult
               print(String(format:"%@ %@ %@ = %@", res.input!.a!, res.input!.op!, res.input!.b!, res.output!.c!))
           } else if result is NSDictionary {
               let res = result as! NSDictionary
               print("NSDictionary: \(res)")
           }
       }
   }
   ```

   在生產應用程式中，您可以在文字欄位中顯示結果或錯誤。產生的顯示畫面為 `1 + 2 = 3`。

1. 呼叫具有承載的 `POST /` 來執行 `1-2`：

   ```
   let body = SIMPLE_CALCInput()
   body.a=1
   body.b=2
   body.op="-"
   client.rootPost(body).continueWithBlock {(task: AWSTask) -> AnyObject? in
       self.showResult(task)
       return nil
   }
   ```

   產生的顯示畫面為 `1 - 2 = -1`。

1. 呼叫 `GET /{a}/{b}/{op}` 來執行 `1/2`：

   ```
   client.aBOpGet("1", b:"2", op:"div").continueWithBlock {(task: AWSTask) -> AnyObject? in
       self.showResult(task)
       return nil
   }
   ```

   產生的顯示畫面為 `1 div 2 = 0.5`。在此，`div` 用來代替 `/`，因為後端的[簡單 Lambda 函數](simple-calc-nodejs-lambda-function.md)不處理 URL 編碼的路徑變數。

# 在 API Gateway 中使用 OpenAPI 開發 REST API
<a name="api-gateway-import-api"></a>

您可以使用 API Gateway 將 REST API 從外部定義檔案匯入至 API Gateway。目前，API Gateway 支援 [OpenAPI v2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md) 和 [OpenAPI v3.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.1.md) 定義檔案，例外狀況列於 [適用於 REST API 的 Amazon API Gateway 重要說明](api-gateway-known-issues.md#api-gateway-known-issues-rest-apis) 中。您可以用新的定義覆寫 API 來更新 API，或與現有的 API 合併定義。您可以在請求 URL 中使用 `mode` 查詢參數來指定選項。

如需從 API Gateway 主控台使用「匯入 API」功能的教學課程，請參閱[教學課程：匯入範例來建立 REST API](api-gateway-create-api-from-example.md)。

**Topics**
+ [將邊緣最佳化 API 匯入至 API Gateway](import-edge-optimized-api.md)
+ [將區域 API 匯入至 API Gateway](import-export-api-endpoints.md)
+ [匯入 OpenAPI 檔案以更新現有的 API 定義](api-gateway-import-api-update.md)
+ [設定 OpenAPI `basePath` 屬性](api-gateway-import-api-basePath.md)
+ [AWS OpenAPI 匯入的 變數](import-api-aws-variables.md)
+ [將 API 匯入 API Gateway 的錯誤和警告](api-gateway-import-api-errors-warnings.md)
+ [從 API Gateway 匯出 REST API](api-gateway-export-api.md)

# 將邊緣最佳化 API 匯入至 API Gateway
<a name="import-edge-optimized-api"></a>

您可以匯入 API OpenAPI 定義檔來建立新的邊緣最佳化 API，方法是指定 `EDGE` 端點類型做為匯入操作的額外輸入 (除了 OpenAPI 檔案之外)。您可以使用 API Gateway 主控台 AWS CLI或 AWS SDK 來執行此操作。

如需從 API Gateway 主控台使用「匯入 API」功能的教學課程，請參閱[教學課程：匯入範例來建立 REST API](api-gateway-create-api-from-example.md)。

**Topics**
+ [使用 API Gateway 主控台匯入邊緣最佳化 API](#import-edge-optimized-api-with-console)
+ [使用 匯入邊緣最佳化 API AWS CLI](#import-edge-optimized-api-with-awscli)

## 使用 API Gateway 主控台匯入邊緣最佳化 API
<a name="import-edge-optimized-api-with-console"></a>

若要使用 API Gateway 主控台匯入邊緣最佳化 API，請執行以下操作：

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

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

1. 在 **REST API** 下，選擇 **Import** (匯入)。

1.  複製 API 的 OpenAPI 定義並將它貼入程式碼編輯器，或選擇**選擇檔案**，從本機磁碟機載入 OpenAPI 檔案。

1.  對於 **API 端點類型**，選取**邊緣最佳化**。

1.  選擇**建立 API** 以開始匯入 OpenAPI 定義。

## 使用 匯入邊緣最佳化 API AWS CLI
<a name="import-edge-optimized-api-with-awscli"></a>

以下 [import-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/import-rest-api.html) 命令會從 OpenAPI 定義檔案匯入 API，以建立新的邊緣最佳化 API：

```
aws apigateway import-rest-api \
    --fail-on-warnings \
    --body 'file://path/to/API_OpenAPI_template.json'
```

或將 `endpointConfigurationTypes` 查詢字串參數明確指定為 `EDGE`：

```
aws apigateway import-rest-api \
    --parameters endpointConfigurationTypes=EDGE \
    --fail-on-warnings \
    --body 'file://path/to/API_OpenAPI_template.json'
```



# 將區域 API 匯入至 API Gateway
<a name="import-export-api-endpoints"></a>

當您匯入 API 時，可以選擇 API 的區域端點組態。您可以使用 API Gateway 主控台 AWS CLI、 或 AWS SDK。

當您匯出 API 時，API 端點組態不會包含在匯出的 API 定義中。

如需從 API Gateway 主控台使用「匯入 API」功能的教學課程，請參閱[教學課程：匯入範例來建立 REST API](api-gateway-create-api-from-example.md)。

**Topics**
+ [使用 API Gateway 主控台匯入區域性 API](#import-regional-api-with-console)
+ [使用 匯入區域 API AWS CLI](#import-regional-api-with-awscli)

## 使用 API Gateway 主控台匯入區域性 API
<a name="import-regional-api-with-console"></a>

若要使用 API Gateway 主控台匯入區域端點的 API，請執行下列動作：

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

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

1. 在 **REST API** 下，選擇 **Import** (匯入)。

1.  複製 API 的 OpenAPI 定義並將它貼入程式碼編輯器，或選擇**選擇檔案**，從本機磁碟機載入 OpenAPI 檔案。

1. 對於 **API 端點類型**，選取**區域**。

1.  選擇**建立 API** 以開始匯入 OpenAPI 定義。

## 使用 匯入區域 API AWS CLI
<a name="import-regional-api-with-awscli"></a>

以下 [import-rest-api](https://docs.aws.amazon.com/cli/latest/reference/apigateway/import-rest-api.html) 命令會匯入 OpenAPI 定義檔案，並將端點類型設為區域：

```
aws apigateway import-rest-api \
    --parameters endpointConfigurationTypes=REGIONAL \
    --fail-on-warnings \
    --body 'file://path/to/API_OpenAPI_template.json'
```

# 匯入 OpenAPI 檔案以更新現有的 API 定義
<a name="api-gateway-import-api-update"></a>

 您可以匯入 API 定義只更新現有的 API，無需變更其端點組態，以及階段與階段變數，或參考 API 金鑰。

 匯入到更新操作可在兩種模式下進行：合併或覆寫。

當 API (`A`) 合併到另一個 (`B`)，如果兩個 API 不共用任何衝突的定義，則產生的 API 會保留 `A` 和 `B` 兩者的定義。發生衝突時，合併 API (`A`) 之方法定義會覆寫被合併 API (`B`) 的對應方法定義。例如，假設 `B` 已宣告以下列方法傳回 `200` 和 `206` 回應：

```
GET /a
POST /a
```

而 `A` 宣告以下列方法傳回 `200` 和 `400` 回應：

```
GET /a
```

當 `A` 合併到 `B`，產生的 API 會產出以下方法：

```
GET /a
```

傳回 `200` 和 `400` 回應，且 

```
POST /a
```

傳回 `200` 和 `206` 回應。

合併 API 適用於您已將外部 API 定義分解成多個更小的組件，而且一次只想要套用其中一個組件的變更時。例如，如果多個小組負責 API 的不同組件並有不同速率的變更時，則可能會出現此情況。在此模式下，現有 API 中的項目若在已匯入的定義中沒有特別定義，則會保持不變。

當 API (`A`) 覆寫另一個 API (`B`)，產生的 API 會採用覆寫的 API (`A`) 之定義。覆寫 API 適用於外部 API 定義包含完整的 API 定義時。在此模式下，現有 API 中的項目若在已匯入的定義中沒有特別定義，則會遭到刪除。

 若要合併 API，請將 `PUT` 請求提交給 `https://apigateway.<region>.amazonaws.com/restapis/<restapi_id>?mode=merge`。`restapi_id` 路徑參數值指定要與所提供的 API 定義合併的 API。

 下列程式碼片段顯示 `PUT` 請求範例，其中會將 JSON 中的 OpenAPI API 定義做為承載與 API Gateway 中已指定的 API 合併。

```
PUT /restapis/<restapi_id>?mode=merge
Host:apigateway.<region>.amazonaws.com
Content-Type: application/json
Content-Length: ...

An OpenAPI API definition in JSON
```

 合併更新操作可將兩個完整的 API 定義合併在一起。對於小型累加變更，您可以使用​[資源更新](https://docs.aws.amazon.com/apigateway/latest/api/API_UpdateResource.html)操作。

 若要覆寫 API，請將 `PUT` 請求提交給 `https://apigateway.<region>.amazonaws.com/restapis/<restapi_id>?mode=overwrite`。`restapi_id` 路徑參數指定要使用所提供 API 定義覆寫的 API。

 下列程式碼片段顯示使用 JSON 格式 OpenAPI 定義的承載覆寫請求的範例：

```
PUT /restapis/<restapi_id>?mode=overwrite
Host:apigateway.<region>.amazonaws.com
Content-Type: application/json
Content-Length: ...

An OpenAPI API definition in JSON
```

 未指定 `mode` 查詢參數時，會假設使用合併。

**注意**  
 `PUT` 操作為等冪，但不可部分完成。這表示如果在處理到一半時發生系統錯誤，API 最後可能會是錯誤狀態。不過，重複此操作會成功將 API 放到相同的最終狀態，就像是成功進行的第一個操作。

# 設定 OpenAPI `basePath` 屬性
<a name="api-gateway-import-api-basePath"></a>

在 [OpenAPI 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md) 中，您可以使用 `basePath` 屬性來提供 `paths` 屬性中所定義之每個路徑之前的一或多個路徑部分。由於 API Gateway 表達資源路徑的方式有幾種，因此匯入 API 功能會在匯入期間提供下列選項來解譯 `basePath` 屬性：ignore、prepend 和 split。

在 [https://swagger.io/docs/specification/api-host-and-base-path/](https://swagger.io/docs/specification/api-host-and-base-path/) 中，`basePath` 不再是頂層屬性。相反地，API Gateway 會使用[伺服器變數](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md#serverVariableObject)做為慣例。匯入 API 功能會提供相同選項，以在匯入期間解譯基本路徑。基本路徑會依下列所述進行識別：
+ 如果 API 未包含任何 `basePath` 變數，則匯入 API 功能會檢查 `server.url` 字串，以查看其是否包含超過 `"/"` 的路徑。若是，該路徑會用作基本路徑。
+ 如果 API 只包含一個 `basePath` 變數，則匯入 API 功能會使用它，做為基本路徑，即使未在 `server.url` 中參考它也一樣。
+ 如果 API 包含多個 `basePath` 變數，則匯入 API 功能只會使用第一個變數，做為基本路徑。

## Ignore
<a name="api-gateway-import-api-basePath-ignore"></a>

如果 OpenAPI 檔案具有 `basePath` 的 `/a/b/c` 值，而且 `paths` 屬性包含 `/e` 與 `/f`，則下列 `POST` 或 `PUT` 請求：

```
POST /restapis?mode=import&basepath=ignore
```



```
PUT /restapis/api_id?basepath=ignore
```

 會導致 API 中的下列資源：
+ `/`
+ `/e`
+ `/f`

 結果是將 `basePath` 視為不存在，並提供與主機相關之所有已宣告的 API 資源。例如，當您有自訂網域名稱，其 API 映射未包含 *Base Path (基底路徑)* 以及參考您生產階段的 *Stage (階段)* 值，就可以使用此選項。

**注意**  
 API Gateway 會自動為您建立根資源，即使您的定義檔中沒有明確宣告也一樣。

 未指定時，`basePath` 預設會採用 `ignore`。

## 前綴
<a name="api-gateway-import-api-basePath-prepend"></a>

 如果 OpenAPI 檔案具有 `basePath` 的 `/a/b/c` 值，而且 `paths` 屬性包含 `/e` 與 `/f`，則下列 `POST` 或 `PUT` 請求：

```
POST /restapis?mode=import&basepath=prepend
```



```
PUT /restapis/api_id?basepath=prepend
```

 會導致 API 中的下列資源：
+ `/`
+ `/a`
+ `/a/b`
+ `/a/b/c`
+ `/a/b/c/e`
+ `/a/b/c/f`

 結果是將 `basePath` 視為指定其他資源 (不含方法)，並將其新增至已宣告的資源集。例如，當不同小組負責 API 的不同組件，而且 `basePath` 可能參考每個小組之 API 組件的路徑位置時，就可以使用此選項。

**注意**  
 API Gateway 會自動為您建立中繼資源，即使您的定義中沒有明確宣告也一樣。

## Split
<a name="api-gateway-import-api-basePath-split"></a>

 如果 OpenAPI 檔案具有 `basePath` 的 `/a/b/c` 值，而且 `paths` 屬性包含 `/e` 與 `/f`，則下列 `POST` 或 `PUT` 請求：

```
POST /restapis?mode=import&basepath=split
```



```
PUT /restapis/api_id?basepath=split
```

 會導致 API 中的下列資源：
+ `/`
+ `/b`
+ `/b/c`
+ `/b/c/e`
+ `/b/c/f`

 結果是將最上層的路徑部分 `/a` 視為每個資源路徑的開頭，並在 API 本身內建立其他資源 (不含方法)。例如，當 `a` 是您要公開為 API 一部分的階段名稱時，就可以使用此選項。

# AWS OpenAPI 匯入的 變數
<a name="import-api-aws-variables"></a>

您可以在 OpenAPI 定義中使用下列 AWS 變數。API Gateway 會在匯入 API 時解析變數。若要指定變數，請使用 `${variable-name}`。下表說明可用的 AWS 變數。


| 變數名稱 | Description | 
| --- | --- | 
| AWS::AccountId | 匯入 API AWS 的帳戶 ID。例如：123456789012。 | 
| AWS::Partition | 匯入 API 的 AWS 分割區。對於標準 AWS 區域，分割區為 aws。 | 
| AWS::Region | 匯入 API AWS 的區域。例如 us-east-2。 | 

## AWS 變數範例
<a name="import-api-aws-variables-example"></a>

下列範例使用 AWS 變數來指定 整合的 AWS Lambda 函數。

------
#### [ OpenAPI 3.0 ]

```
openapi: "3.0.1"
info:
  title: "tasks-api"
  version: "v1.0"
paths:
  /:
    get:
      summary: List tasks
      description: Returns a list of tasks
      responses:
        200:
          description: "OK"
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Task"
        500:
          description: "Internal Server Error"
          content: {}
      x-amazon-apigateway-integration:
        uri:
          arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:LambdaFunctionName/invocations
        responses:
          default:
            statusCode: "200"
        passthroughBehavior: "when_no_match"
        httpMethod: "POST"
        contentHandling: "CONVERT_TO_TEXT"
        type: "aws_proxy"
components:
  schemas:
    Task:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        description:
          type: string
```

------

# 將 API 匯入 API Gateway 的錯誤和警告
<a name="api-gateway-import-api-errors-warnings"></a>

當您將外部定義檔案匯入 API Gateway 時，API Gateway 可能會產生警告和錯誤。下列各節討論匯入期間可能發生的錯誤和警告。

## 匯入期間的錯誤
<a name="api-gateway-import-api-errors"></a>

 匯入期間，OpenAPI 文件無效等重大問題可能會產生錯誤。這些錯誤會在失敗回應中以例外狀況 (例如 `BadRequestException`) 傳回。發生錯誤時，會捨棄新的 API 定義，而且不會對現有的 API 進行變更。

## 匯入期間的警告
<a name="api-gateway-import-api-warnings"></a>

 匯入期間，遺失模型參考等次要問題可能會產生警告。如果發生警告，並將 `failonwarnings=false` 查詢表達式附加至請求 URL，操作將會繼續。否則會復原更新。根據預設，`failonwarnings` 會設定為 `false`。在此類情況下，警告會在所產生的 [RestApi](https://docs.aws.amazon.com/apigateway/latest/api/API_RestApi.html) 資源中的欄位回傳。否則，警告會以例外狀況中的訊息傳回。

# 從 API Gateway 匯出 REST API
<a name="api-gateway-export-api"></a>

 一旦您使用 API Gateway 主控台或其他方式，在 API Gateway 中建立並配置 REST API，就可以使用 API Gateway Export API (屬於 Amazon API Gateway 控制服務的一部分) 將其匯出至 OpenAPI 檔案。若要使用 API Gateway Export API，您必須簽署 API 請求。如需簽署請求的詳細資訊，請參閱《*IAM 使用者指南*》中的[簽署 AWS API 請求](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html)。您可以選擇在匯出的 OpenAPI 定義檔中包含 API Gateway 整合延伸項目和 [Postman](https://www.postman.com) 延伸項目。

**注意**  
使用 匯出 API 時 AWS CLI，請務必包含延伸項目參數，如下列範例所示，以確保包含`x-amazon-apigateway-request-validator`延伸項目：  

```
aws apigateway get-export --parameters extensions='apigateway' --rest-api-id abcdefg123 --stage-name dev --export-type swagger latestswagger2.json
```

 如果 API 的承載類型不是 `application/json`，則無法匯出 API。如果您嘗試，則會收到錯誤回應，指出找不到 JSON 內文模型。

## 匯出 REST API 的請求
<a name="api-gateway-export-api-request"></a>

 使用匯出 API 時，您可以提交 GET 請求並將欲匯出的 API 指定為 URL 路徑的一部分，藉此匯出現有 REST API。請求 URL 的格式如下：

------
#### [ OpenAPI 3.0 ]

```
 https://<host>/restapis/<restapi_id>/stages/<stage_name>/exports/oas30
```

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

```
 https://<host>/restapis/<restapi_id>/stages/<stage_name>/exports/swagger
```

------

 您可以附加 `extensions` 查詢字串，以指定要包含 API Gateway 延伸 (具有 `integration` 值) 或是 Postman 延伸 (具有 `postman` 值)。

 此外，您也可以將 `Accept` 標頭設定為 `application/json` 或 `application/yaml`，分別接收 JSON 或 YAML 格式的 API 定義輸出。

 如需使用 API Gateway Export API 提交 GET 請求的詳細資訊，請參閱 [GetExport](https://docs.aws.amazon.com/apigateway/latest/api/API_GetExport.html)。

**注意**  
 如果您在 API 中定義模型，則模型必須適用於內容類型「application/json」，API Gateway 才會匯出模型。否則，API Gateway 會擲回例外狀況，其錯誤訊息為「只發現 ... 的非 JSON 內文模型」。  
 模型必須包含屬性，或是定義為特定 JSONSchema 類型。

## 下載 JSON 格式的 REST API OpenAPI 定義
<a name="api-gateway-export-api-download-swagger-json"></a>

以 JSON 格式的 OpenAPI 定義匯出並下載 REST API：

------
#### [ OpenAPI 3.0 ]

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/oas30
Host: apigateway.<region>.amazonaws.com
Accept: application/json
```

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

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/swagger
Host: apigateway.<region>.amazonaws.com
Accept: application/json
```

------

 例如，在這裡，`<region>` 可以是 `us-east-1`。如需可使用 API Gateway 的所有區域，請參閱[區域和端點](https://docs.aws.amazon.com/general/latest/gr/rande.html#apigateway_region)。

## 下載 YAML 格式的 REST API OpenAPI 定義
<a name="api-gateway-export-api-download-swagger-yaml"></a>

以 YAML 格式的 OpenAPI 定義匯出並下載 REST API：

------
#### [ OpenAPI 3.0 ]

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/oas30
Host: apigateway.<region>.amazonaws.com
Accept: application/yaml
```

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

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/swagger
Host: apigateway.<region>.amazonaws.com
Accept: application/yaml
```

------

## 下載 JSON 格式且具有 Postman 延伸的 REST API OpenAPI 定義
<a name="api-gateway-export-api-download-swagger-json-with-postman"></a>

以 JSON 格式的 OpenAPI 定義搭配 Postman 匯出並下載 REST API：

------
#### [ OpenAPI 3.0 ]

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/oas30?extensions=postman
Host: apigateway.<region>.amazonaws.com
Accept: application/json
```

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

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/swagger?extensions=postman
Host: apigateway.<region>.amazonaws.com
Accept: application/json
```

------

## 下載 YAML 格式且具有 API Gateway 整合的 REST API OpenAPI 定義
<a name="api-gateway-export-api-download-swagger-yaml-with-apig"></a>

以 YAML 格式的 OpenAPI 定義搭配 API Gateway 整合匯出並下載 REST API：

------
#### [ OpenAPI 3.0 ]

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/oas30?extensions=integrations
Host: apigateway.<region>.amazonaws.com
Accept: application/yaml
```

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

```
GET /restapis/<restapi_id>/stages/<stage_name>/exports/swagger?extensions=integrations
Host: apigateway.<region>.amazonaws.com
Accept: application/yaml
```

------

## 使用 API Gateway 主控台匯出 REST API
<a name="api-gateway-export-api-from-console"></a>

[將 REST API 部署至階段](set-up-deployments.md#create-deployment)之後，即可繼續使用 API Gateway 主控台，將階段中的 API 匯出至 OpenAPI 檔案。

 在 API Gateway 主控台的**階段**窗格中，選擇**階段動作**、**匯出**。

![\[使用 API Gateway 主控台匯出 REST API\]](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/export-new-console.png)


指定 **API 規格類型**、**格式**和**延伸模組**，以下載 API 的 OpenAPI 定義。