

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

# 教學：建立 REST API 做為 Amazon S3 代理
<a name="integrating-api-with-aws-services-s3"></a>

例如，若要示範如何在 API Gateway 中使用 REST API 來代理處理 Amazon S3，本節說明如何建立和設定 REST API 來公開下列 Amazon S3 操作：
+ 在 API 根資源上公開 GET，以[列出發起人的所有 Amazon S3 儲存貯體](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html)。
+ 在 Folder 資源上公開 GET，以[檢視 Amazon S3 儲存貯體中的所有物件清單](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html)。
+ 在 Folder/Item 資源上公開 GET，以[檢視或下載 Amazon S3 儲存貯體中的物件](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html)。

 建議您匯入範例 API 作為 Amazon S3 代理，如[做為 Amazon S3 代理之範例 API 的 OpenAPI 定義](api-as-s3-proxy-export-swagger-with-extensions.md)中所示。此範例包含更多已公開的方法。如需如何使用 OpenAPI 定義匯入 API 的說明，請參閱[在 API Gateway 中使用 OpenAPI 開發 REST API](api-gateway-import-api.md)。

**注意**  
 若要整合 API Gateway API 與 Amazon S3，您必須選擇可使用 API Gateway API 與 Amazon S3 服務的區域。如需區域可用性，請參閱 [Amazon API Gateway 端點和配額](https://docs.aws.amazon.com/general/latest/gr/apigateway.html)。

**Topics**
+ [設定 API 叫用 Amazon S3 動作的 IAM 許可](#api-as-s3-proxy-iam-permissions)
+ [建立 API 資源以代表 Amazon S3 資源](#api-as-s3-proxy-create-resources)
+ [公開 API 方法來列出發起人的 Amazon S3 儲存貯體](#api-root-get-as-s3-get-service)
+ [公開 API 方法來存取 Amazon S3 儲存貯體](#api-folder-operations-as-s3-bucket-actions)
+ [公開 API 方法來存取儲存貯體中的 Amazon S3 物件](#api-items-in-folder-as-s3-objects-in-bucket)
+ [做為 Amazon S3 代理之範例 API 的 OpenAPI 定義](api-as-s3-proxy-export-swagger-with-extensions.md)
+ [使用 REST API 用戶端呼叫 API](api-as-s3-proxy-test-using-postman.md)

## 設定 API 叫用 Amazon S3 動作的 IAM 許可
<a name="api-as-s3-proxy-iam-permissions"></a>

 若要允許 API 調用 Amazon S3 動作，您必須將適當的 IAM 政策附加至 IAM 角色。在此步驟中，您會建立新的 IAM 角色。

**建立 AWS 服務代理執行角色**

1. 登入 AWS 管理主控台 ，並在 https：//[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) 開啟 IAM 主控台。

1. 選擇**角色**。

1. 選擇建**立角色**。

1.  在**選取信任的實體類型**下選擇 **AWS 服務**，然後選取 **API Gateway** 並選取**允許 API Gateway 將日誌推送到 CloudWatch Logs**。

1.  選擇**下一步**，然後選擇**下一步**。

1. 針對**角色名稱**，輸入 **APIGatewayS3ProxyPolicy**，然後選擇**建立角色**。

1. 在**角色**清單中，選擇您剛剛建立的角色。您可能需要捲動或使用搜尋列來尋找該角色。

1. 針對選取的角色，選取 **許可** 索引標籤。

1. 在下拉式清單中，選擇 **連接政策**。

1. 在搜尋列中輸入 **AmazonS3FullAccess**，並選擇**新增許可**。
**注意**  
本教學課程為了簡單起見，使用受管理政策。最佳實務是，您應建立自己的 IAM 政策以授予所需的最低許可。

1. 記下新建的**角色 ARN**，以在稍後使用。

## 建立 API 資源以代表 Amazon S3 資源
<a name="api-as-s3-proxy-create-resources"></a>

您使用 API 的根 (`/`) 資源做為已驗證發起人之 Amazon S3 儲存貯體的容器。您也會建立 `Folder` 和 `Item` 資源，分別代表特定 Amazon S3 儲存貯體和特定 Amazon S3 物件。發起人會將資料夾名稱和物件金鑰指定為請求 URL 一部分的路徑參數。

**注意**  
當所存取物件的物件金鑰包含 `/` 或任何其他特殊字元時，該字元必須以 URL 編碼。例如，`test/test.txt` 應編碼為 `test%2Ftest.txt`。

**建立可公開 Amazon S3 服務功能的 API 資源**

1.  在 AWS 區域 建立 Amazon S3 儲存貯體的相同 中，建立名為 **MyS3** 的 API。這個 API 的根資源 (**/**) 代表 Amazon S3 服務。在此步驟中，您會另外建立兩個資源 **/{folder}** 和 **/{item}**。

1. 選擇**建立資源**。

1. 讓**代理資源**保持關閉。

1. 針對**資源路徑**，選取 `/`。

1. 針對**資源名稱**，輸入 **{folder}**。

1. 讓 **CORS (跨來源資源分享)** 保持未核取狀態。

1. 選擇**建立資源**。

1. 選取 **/{folder}** 資源，然後選擇**建立資源**。

1. 使用上述步驟建立名為 **{item}** 的 **/{folder}** 子資源。

   您的最終 API 應會如下所示：

      
![在 API Gateway 中建立 API 作為 Amazon S3 代理](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/aws_proxy_s3_create_api-resources_new_console.png)

## 公開 API 方法來列出發起人的 Amazon S3 儲存貯體
<a name="api-root-get-as-s3-get-service"></a>

取得發起人的 Amazon S3 儲存貯體清單包含在 Amazon S3 上呼叫 [GET 服務](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html)動作。在 API 的根資源 (**/**) 上，建立 GET 方法。設定 GET 方法以與 Amazon S3 整合，如下所示。

**建立和初始化 API 的 `GET /` 方法**

1. 選取 **/** 資源，然後選擇**建立方法**。

1. 針對方法類型，選取 **GET**。

1. 針對**整合類型**，選取 **AWS 服務**。

1. 針對 **AWS 區域**，選取您建立 Amazon S3 儲存貯 AWS 區域 體的 。

1. 針對 **AWS 服務**，選取 **Amazon Simple Storage Service**。

1. 讓 **AWS 子網域**保持空白。

1. 針對 **HTTP 方法**，選取 **GET**。

1. 針對**動作類型**，選取**使用路徑覆寫**。

   使用路徑覆寫，API Gateway 會將用戶端請求轉送給 Amazon S3 以作為對應的 [Amazon S3 REST API 路徑樣式請求](https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAPI.html)；其中，Amazon S3 資源是以 `s3-host-name/bucket/key` 模式的資源路徑表示。API Gateway 會設定 `s3-host-name`，並將用戶端指定的 `bucket` 和 `key` 從用戶端傳遞給 Amazon S3。

1. 針對**路徑覆寫**，輸入 **/**。

1. 針對**執行角色**，輸入 **APIGatewayS3ProxyPolicy** 的角色 ARN。

1. 選擇**方法請求設定**。

   您可以使用方法請求設定來控制誰可以呼叫此 API 方法。

1. 針對**授權**，從下拉式功能表中選取 `AWS_IAM`。

      
![宣告方法回應類型](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/aws_proxy_s3_setup_method_request_authorization_new_console.png)

1. 選擇**建立方法**。

此設定會整合前端 `GET https://{{your-api-host}}/{{stage}}/` 請求與後端 `GET https://{{your-s3-host}}/`。

 為了讓您的 API 將成功回應和例外狀況正確地傳回給發起人，請在**方法回應**中宣告 200、400 和 500 回應。您使用 200 回應做為預設映射；因此，會將未在這裡宣告的狀態碼後端回應當成 200 回應傳回給發起人。

**宣告 `GET /` 方法的回應類型**

1.  在**方法回應**索引標籤上的**回應 200** 下，選擇**編輯**。

1. 選擇**新增標頭**，然後執行下列動作：

   1. 針對**標頭名稱**，輸入 **Content-Type**。

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

   重複這些步驟以建立 **Timestamp** 標頭和 **Content-Length** 標頭。

1. 選擇**儲存**。

1. 在**方法回應**索引標籤上的**方法回應**下，選擇**建立回應**。

1. 針對 **HTTP 狀態碼**，輸入 **400**。

   您未針對此回應設定任何標頭。

1. 選擇**儲存**。

1. 重複以下步驟以建立 500 回應。

   您未針對此回應設定任何標頭。

因為來自 Amazon S3 的成功整合回應傳回儲存貯體清單做為 XML 承載，而來自 API Gateway 的預設方法回應傳回 JSON 承載，所以您必須將後端 Content-Type 標頭參數值映射至前端相應實物。否則，回應內文實際上是 XML 字串時，用戶端將會收到內容類型的 `application/json`。下列程序示範如何設定此項目。此外，您也想要向用戶端顯示其他標頭參數 (例如 Date 和 Content-Length)。

**設定 GET / 方法的回應標頭對應**

1. 在**整合回應**索引標籤上，於**預設 - 回應**下，選擇**編輯**。

1. 針對 **Content-Length** 標頭，輸入 **integration.response.header.Content-Length** 作為對應值。

1. 針對 **Content-Type** 標頭，輸入 **integration.response.header.Content-Type** 作為對應值。

1. 針對**時間戳記**標頭，輸入 **integration.response.header.Date** 作為對應值。

1. 選擇**儲存**。結果應類似以下內容：

      
![將整合回應標頭對應至方法回應標頭](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/aws_proxy_s3_setup_integration_response_headers_new_console.png)

1. 在**整合回應**索引標籤上的**整合回應**下，選擇**建立回應**。

1. 對於 **HTTP 狀態 regex**，輸入 **4\\d{2}**。這會將所有 4xx HTTP 回應狀態碼對應到方法回應。

1. 針對**方法回應狀態碼**，選取 **400**。

1. 選擇**建立**。

1. 重複下列步驟，為 500 方法回應建立整合回應。對於 **HTTP 狀態 regex**，輸入 **5\\d{2}**。

您最好測試到目前為止已設定的 API。

**測試 `GET /` 方法**

1. 選擇**測試**標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

1. 選擇**測試**。結果應如下圖所示：

      
![測試 API 根 GET 儲存貯體結果](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/aws_proxy_s3_test_root_get_result_new_console.png)

## 公開 API 方法來存取 Amazon S3 儲存貯體
<a name="api-folder-operations-as-s3-bucket-actions"></a>

為了使用 Amazon S3 儲存貯體，您在/{folder} 資源上公開 `GET` 方法，以列出儲存貯體中的物件。這些說明與「[公開 API 方法來列出發起人的 Amazon S3 儲存貯體](#api-root-get-as-s3-get-service)」中所述的說明類似。如需更多方法，您可以在此處 ([做為 Amazon S3 代理之範例 API 的 OpenAPI 定義](api-as-s3-proxy-export-swagger-with-extensions.md)) 匯入範例 API。

**在資料夾資源上公開 GET 方法**

1. 選取 **/{folder}** 資源，然後選擇**建立方法**。

1. 針對方法類型，選取 **GET**。

1. 針對**整合類型**，選取 **AWS 服務**。

1. 針對 **AWS 區域**，選取您建立 Amazon S3 儲存貯 AWS 區域 體的 。

1. 針對 **AWS 服務**，選取 **Amazon Simple Storage Service**。

1. 讓 **AWS 子網域**保持空白。

1. 針對 **HTTP 方法**，選取 **GET**。

1. 針對**動作類型**，選取**使用路徑覆寫**。

1. 針對**路徑覆寫**，輸入 **{bucket}**。

1. 針對**執行角色**，輸入 **APIGatewayS3ProxyPolicy** 的角色 ARN。

1. 選擇**建立方法**。

您在 Amazon S3 端點 URL 中設定 `{folder}` 路徑參數。您需要將方法請求的 `{folder}` 路徑參數對應至整合請求的 `{bucket}` 路徑參數。

**將 `{folder}` 對應至 `{bucket}`**

1.  在**整合請求**索引標籤上，於**整合請求設定**下，選擇**編輯**。

1. 選擇 **URL 路徑參數**，然後選擇**新增路徑參數**。

1. 對於**名稱**，輸入 **bucket**。

1. 對於**映射自**，輸入 **method.request.path.folder**。

1. 選擇**儲存**。

現在，測試您的 API。

**測試 `/{folder} GET` 方法。**

1. 選擇**測試**標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

1. 在**路徑**下，針對**資料夾**，輸入儲存貯體的名稱。

1. 選擇**測試**。

   測試結果將包含儲存貯體中的物件清單。

      
![測試 GET 方法來建立 Amazon S3 儲存貯體。](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/aws_proxy_s3_test_api_folder_get_new_console.png)

## 公開 API 方法來存取儲存貯體中的 Amazon S3 物件
<a name="api-items-in-folder-as-s3-objects-in-bucket"></a>

Amazon S3 支援 GET、DELETE、HEAD、OPTIONS、POST 和 PUT 動作來存取和管理特定儲存貯體中的物件。在本教學課程中，您會在 `{folder}/{item}` 資源上公開 `GET` 方法，以從儲存貯體取得映像。如需 `{folder}/{item}` 資源的更多應用，請參閱範例 API ([做為 Amazon S3 代理之範例 API 的 OpenAPI 定義](api-as-s3-proxy-export-swagger-with-extensions.md))。

**在項目資源上公開 GET 方法**

1. 選取 **/{item}** 資源，然後選擇**建立方法**。

1. 針對方法類型，選取 **GET**。

1. 針對**整合類型**，選取 **AWS 服務**。

1. 針對 **AWS 區域**，選取您建立 Amazon S3 儲存貯 AWS 區域 體的 。

1. 針對 **AWS 服務**，選取 **Amazon Simple Storage Service**。

1. 讓 **AWS 子網域**保持空白。

1. 針對 **HTTP 方法**，選取 **GET**。

1. 針對**動作類型**，選取**使用路徑覆寫**。

1. 針對**路徑覆寫**，輸入 **{bucket}/{object}**。

1. 針對**執行角色**，輸入 **APIGatewayS3ProxyPolicy** 的角色 ARN。

1. 選擇**建立方法**。

您在 Amazon S3 端點 URL 中設定 `{folder}` 和 `{item}` 路徑參數。您需要將方法請求的 路徑參數映射至整合請求的路徑參數。

請於本步驟執行以下操作：
+ 將方法請求的 `{folder}` 路徑參數對應至整合請求的 `{bucket}` 路徑參數。
+ 將方法請求的 `{item}` 路徑參數對應至整合請求的 `{object}` 路徑參數。

**將 `{folder}` 對應至 `{bucket}` 並將 `{item}` 對應至 `{object}`**

1.  在**整合請求**索引標籤上，於**整合請求設定**下，選擇**編輯**。

1. 選擇 **URL 路徑參數**。

1. 選擇**新增路徑參數**。

1. 對於**名稱**，輸入 **bucket**。

1. 對於**映射自**，輸入 **method.request.path.folder**。

1. 選擇**新增路徑參數**。

1. 對於**名稱**，輸入 **object**。

1. 對於**映射自**，輸入 **method.request.path.item**。

1. 選擇**儲存**。

**測試 `/{folder}/{object} GET` 方法。**

1. 選擇**測試**標籤。您可能需要選擇向右箭頭按鈕才能顯示此索引標籤。

1. 在**路徑**下，針對**資料夾**，輸入儲存貯體的名稱。

1. 在**路徑**下，針對**項目**，輸入項目的名稱。

1. 選擇**測試**。

   回應內文會包含該項目的內容。

      
![測試 GET 方法來建立 Amazon S3 儲存貯體。](http://docs.aws.amazon.com/zh_tw/apigateway/latest/developerguide/images/aws_proxy_s3_test_api_item_get_new_console.png)

   請求會正確地傳回 ("Hello world") 的純文字作為指定 Amazon S3 儲存貯體 (amzn-s3-demo-bucket) 中所指定檔案 (test.txt) 的內容。

 若要下載或上傳二進位檔案，而二進位檔案在 API Gateway 中視為 utf-8 編碼 JSON 內容以外的任何事項，則需要額外的 API 設定。這概述如下：

**從 S3 下載或上傳二進位檔案**

1.  將受影響檔案的媒體類型註冊到 API 的 binaryMediaTypes。您可以在主控台中執行這項操作：

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

   1. 在**二進位媒體類型**下，選擇**管理媒體類型**。

   1. 選擇**新增二進位媒體類型**，然後輸入所需的媒體類型，例如 `image/png`。

   1. 選擇**儲存變更**來儲存設定。

1. 將 `Content-Type` (進行上傳) 和 (或) `Accept` (進行下載) 標頭新增至方法請求，以要求用戶端指定所需的二進位媒體類型，並將其對應至整合請求。

1. 在整合請求 (進行上傳) 和整合回應 (進行下載) 中，將 **Content Handling (內容處理)** 設定為 `Passthrough`。請確定未定義受影響內容類型的對應範本。如需詳細資訊，請參閱[API Gateway 中用於 REST API 的資料轉換](rest-api-data-transformations.md)。

承載大小上限為 10 MB。請參閱[在 API Gateway 中設定和執行 REST API 的配額](api-gateway-execution-service-limits-table.md)。

確定 Amazon S3 上的檔案具有新增為檔案中繼資料的正確內容類型。針對可串流媒體內容，`Content-Disposition:inline` 也可能需要新增至中繼資料。

如需 API Gateway 中二進位支援的詳細資訊，請參閱[API Gateway 中的內容類型轉換](api-gateway-payload-encodings-workflow.md)。