

# 教程：创建 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 和 Amazon S3 服务的区域。有关区域可用性，请参阅 [Amazon API Gateway 端点和配额](https://docs.aws.amazon.com/general/latest/gr/apigateway.html)。

**Topics**
+ [为 API 设置 IAM 权限以调用 Amazon S3 操作](#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 设置 IAM 权限以调用 Amazon S3 操作
<a name="api-as-s3-proxy-iam-permissions"></a>

 要允许 API 调用 Amazon S3 操作，您必须已将适当的 IAM 策略附加到 IAM 角色。在此步骤中，您将创建新 IAM 角色。

**创建 AWS 服务代理执行角色**

1. 登录 AWS 管理控制台，然后使用以下网址打开 IAM 控制台：[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/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.  在创建 Amazon S3 桶的同一 AWS 区域，创建名为 **MyS3** 的 API。此 API 的根资源 (**/**) 表示 Amazon S3 服务。在此步骤中，您将创建另外两个资源：**/\$1folder\$1** 和 **/\$1item\$1**。

1. 选择**创建资源**。

1. 将**代理资源**保持为关闭状态。

1. 对于**资源路径**，选择 `/`。

1. 对于**资源名称**，输入 **\$1folder\$1**。

1. 将 **CORS（跨源资源共享）**保持为未选中。

1. 选择**创建资源**。

1. 选择 **/\$1folder\$1** 资源，然后选择**创建资源**。

1. 使用上述步骤创建 **/\$1folder\$1** 的子资源，名为 **\$1item\$1**。

   最终的 API 应类似以下内容：

      
![\[在 API Gateway 中创建 API 作为 Amazon S3 代理\]](http://docs.aws.amazon.com/zh_cn/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 REST API 路径样式请求](https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTAPI.html)转发到 Amazon S3，其中 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_cn/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. 对于 **Timestamp** 标头，输入 **integration.response.header.Date** 作为映射值。

1. 选择**保存**。结果应类似以下内容：

      
![\[将集成响应标头映射到方法响应标头\]](http://docs.aws.amazon.com/zh_cn/apigateway/latest/developerguide/images/aws_proxy_s3_setup_integration_response_headers_new_console.png)

1. 在**集成响应**选项卡的**集成响应**下，选择**创建响应**。

1. 对于 **HTTP 状态正则表达式**，输入 **4\$1d\$12\$1**。这会将所有 4xx HTTP 响应状态代码映射到方法响应。

1. 对于**方法响应状态代码**，选择 **400**。

1. 选择**创建**。

1. 重复以下步骤，为 500 方法响应创建集成响应。对于 **HTTP 状态正则表达式**，输入 **5\$1d\$12\$1**。

作为一个良好做法，您可以测试到目前为止已配置的 API。

**测试 `GET /` 方法**

1. 选择**测试**选项卡。您可能需要选择右箭头按钮，以显示该选项卡。

1. 选择**测试**。结果应类似下图内容：

      
![\[测试 API 根 GET 存储桶结果\]](http://docs.aws.amazon.com/zh_cn/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 存储桶，您在 /\$1folder\$1 资源上公开 `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. 选择 **/\$1folder\$1** 资源，然后选择**创建方法**。

1. 对于方法类型，选择 **GET**。

1. 对于**集成类型**，选择 **AWS 服务**。

1. 对于 **AWS 区域**，选择您创建 Amazon S3 桶的 AWS 区域。

1. 对于 **AWS 服务**，选择 **Amazon Simple Storage Service**。

1. 将 **AWS 子域**保留为空白。

1. 对于 **HTTP 方法**，选择 **GET**。

1. 对于**操作类型**，选择**使用路径覆盖**。

1. 对于**路径覆盖**，输入 **\$1bucket\$1**。

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_cn/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}` 资源的更多应用，请转至[作为 Amazon S3 代理的示例 API 的 OpenAPI 定义](api-as-s3-proxy-export-swagger-with-extensions.md)参阅示例 API。

**对项目资源公开 GET 方法**

1. 选择 **/\$1item\$1** 资源，然后选择**创建方法**。

1. 对于方法类型，选择 **GET**。

1. 对于**集成类型**，选择 **AWS 服务**。

1. 对于 **AWS 区域**，选择您创建 Amazon S3 桶的 AWS 区域。

1. 对于 **AWS 服务**，选择 **Amazon Simple Storage Service**。

1. 将 **AWS 子域**保留为空白。

1. 对于 **HTTP 方法**，选择 **GET**。

1. 对于**操作类型**，选择**使用路径覆盖**。

1. 对于**路径覆盖**，输入 **\$1bucket\$1/\$1object\$1**。

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_cn/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. 在集成请求（用于上传）和集成响应（用于下载）中，将**内容处理** 设置为 `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)。

# 作为 Amazon S3 代理的示例 API 的 OpenAPI 定义
<a name="api-as-s3-proxy-export-swagger-with-extensions"></a>

以下 OpenAPI 定义描述可用作 Amazon S3 代理的 API。与您在本教程中创建的 API 相比，此 API 包含更多 Amazon S3 操作。此 OpenAPI 定义中公开了以下方法：
+ 在 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 资源上公开 PUT 以[将存储桶添加到 Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html)。
+ 在 Folder 资源上公开 DELETE 以[从 Amazon S3 中删除存储桶](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteBucket.html)。
+ 在 Folder/Item 资源上公开 GET 以[从 Amazon S3 存储桶查看或下载对象](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html)。
+ 在 Folder/Item 资源上公开 PUT 以[将对象上传到 Amazon S3 存储桶](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html)。
+ 在 Folder/Item 资源上公开 HEAD 以[在 Amazon S3 存储桶中获取对象元数据](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html)。
+ 在 Folder/Item 资源上公开 DELETE 以[从 Amazon S3 存储桶中删除对象](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html)。

有关如何使用 OpenAPI 定义导入 API 的说明，请参阅 [在 API Gateway 中使用 OpenAPI 开发 REST API](api-gateway-import-api.md)。

有关如何创建类似 API 的说明，请参阅[教程：创建 REST API 作为 Amazon S3 代理](integrating-api-with-aws-services-s3.md)。

要了解如何使用支持 AWS IAM 授权的 [Postman](https://www.postman.com/) 调用此 API，请参阅[使用 REST API 客户端调用 API](api-as-s3-proxy-test-using-postman.md)。

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

```
{
  "swagger": "2.0",
  "info": {
    "version": "2016-10-13T23:04:43Z",
    "title": "MyS3"
  },
  "host": "9gn28ca086.execute-api.{region}.amazonaws.com",
  "basePath": "/S3",
  "schemes": [
    "https"
  ],
  "paths": {
    "/": {
      "get": {
        "produces": [
          "application/json"
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Content-Length": {
                "type": "string"
              },
              "Timestamp": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type",
                "method.response.header.Content-Length": "integration.response.header.Content-Length",
                "method.response.header.Timestamp": "integration.response.header.Date"
              }
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path//",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "GET",
          "type": "aws"
        }
      }
    },
    "/{folder}": {
      "get": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "folder",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Content-Length": {
                "type": "string"
              },
              "Date": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type",
                "method.response.header.Date": "integration.response.header.Date",
                "method.response.header.Content-Length": "integration.response.header.content-length"
              }
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "requestParameters": {
            "integration.request.path.bucket": "method.request.path.folder"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{bucket}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "GET",
          "type": "aws"
        }
      },
      "put": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "Content-Type",
            "in": "header",
            "required": false,
            "type": "string"
          },
          {
            "name": "folder",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Content-Length": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type",
                "method.response.header.Content-Length": "integration.response.header.Content-Length"
              }
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "requestParameters": {
            "integration.request.path.bucket": "method.request.path.folder",
            "integration.request.header.Content-Type": "method.request.header.Content-Type"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{bucket}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "PUT",
          "type": "aws"
        }
      },
      "delete": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "folder",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Date": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type",
                "method.response.header.Date": "integration.response.header.Date"
              }
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "requestParameters": {
            "integration.request.path.bucket": "method.request.path.folder"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{bucket}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "DELETE",
          "type": "aws"
        }
      }
    },
    "/{folder}/{item}": {
      "get": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "item",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "folder",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "content-type": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.content-type": "integration.response.header.content-type",
                "method.response.header.Content-Type": "integration.response.header.Content-Type"
              }
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "requestParameters": {
            "integration.request.path.object": "method.request.path.item",
            "integration.request.path.bucket": "method.request.path.folder"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "GET",
          "type": "aws"
        }
      },
      "head": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "item",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "folder",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Content-Length": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type",
                "method.response.header.Content-Length": "integration.response.header.Content-Length"
              }
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "requestParameters": {
            "integration.request.path.object": "method.request.path.item",
            "integration.request.path.bucket": "method.request.path.folder"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "HEAD",
          "type": "aws"
        }
      },
      "put": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "Content-Type",
            "in": "header",
            "required": false,
            "type": "string"
          },
          {
            "name": "item",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "folder",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Content-Length": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200",
              "responseParameters": {
                "method.response.header.Content-Type": "integration.response.header.Content-Type",
                "method.response.header.Content-Length": "integration.response.header.Content-Length"
              }
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "requestParameters": {
            "integration.request.path.object": "method.request.path.item",
            "integration.request.path.bucket": "method.request.path.folder",
            "integration.request.header.Content-Type": "method.request.header.Content-Type"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "PUT",
          "type": "aws"
        }
      },
      "delete": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "item",
            "in": "path",
            "required": true,
            "type": "string"
          },
          {
            "name": "folder",
            "in": "path",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            },
            "headers": {
              "Content-Length": {
                "type": "string"
              },
              "Content-Type": {
                "type": "string"
              }
            }
          },
          "400": {
            "description": "400 response"
          },
          "500": {
            "description": "500 response"
          }
        },
        "security": [
          {
            "sigv4": []
          }
        ],
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "responses": {
            "4\\d{2}": {
              "statusCode": "400"
            },
            "default": {
              "statusCode": "200"
            },
            "5\\d{2}": {
              "statusCode": "500"
            }
          },
          "requestParameters": {
            "integration.request.path.object": "method.request.path.item",
            "integration.request.path.bucket": "method.request.path.folder"
          },
          "uri": "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "passthroughBehavior": "when_no_match",
          "httpMethod": "DELETE",
          "type": "aws"
        }
      }
    }
  },
  "securityDefinitions": {
    "sigv4": {
      "type": "apiKey",
      "name": "Authorization",
      "in": "header",
      "x-amazon-apigateway-authtype": "awsSigv4"
    }
  },
  "definitions": {
    "Empty": {
      "type": "object",
      "title": "Empty Schema"
    }
  }
}
```

------
#### [ OpenAPI 3.0 ]

```
{
  "openapi" : "3.0.1",
  "info" : {
    "title" : "MyS3",
    "version" : "2016-10-13T23:04:43Z"
  },
  "servers" : [ {
    "url" : "https://9gn28ca086.execute-api.{region}.amazonaws.com/{basePath}",
    "variables" : {
      "basePath" : {
        "default" : "S3"
      }
    }
  } ],
  "paths" : {
    "/{folder}" : {
      "get" : {
        "parameters" : [ {
          "name" : "folder",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "Content-Length" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Date" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "GET",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path/{bucket}",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.Content-Type" : "integration.response.header.Content-Type",
                "method.response.header.Date" : "integration.response.header.Date",
                "method.response.header.Content-Length" : "integration.response.header.content-length"
              }
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "requestParameters" : {
            "integration.request.path.bucket" : "method.request.path.folder"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      },
      "put" : {
        "parameters" : [ {
          "name" : "Content-Type",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "folder",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "Content-Length" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "PUT",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path/{bucket}",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.Content-Type" : "integration.response.header.Content-Type",
                "method.response.header.Content-Length" : "integration.response.header.Content-Length"
              }
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "requestParameters" : {
            "integration.request.path.bucket" : "method.request.path.folder",
            "integration.request.header.Content-Type" : "method.request.header.Content-Type"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      },
      "delete" : {
        "parameters" : [ {
          "name" : "folder",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "Date" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "DELETE",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path/{bucket}",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.Content-Type" : "integration.response.header.Content-Type",
                "method.response.header.Date" : "integration.response.header.Date"
              }
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "requestParameters" : {
            "integration.request.path.bucket" : "method.request.path.folder"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      }
    },
    "/{folder}/{item}" : {
      "get" : {
        "parameters" : [ {
          "name" : "item",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "folder",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "content-type" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "GET",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.content-type" : "integration.response.header.content-type",
                "method.response.header.Content-Type" : "integration.response.header.Content-Type"
              }
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "requestParameters" : {
            "integration.request.path.object" : "method.request.path.item",
            "integration.request.path.bucket" : "method.request.path.folder"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      },
      "put" : {
        "parameters" : [ {
          "name" : "Content-Type",
          "in" : "header",
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "item",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "folder",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "Content-Length" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "PUT",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.Content-Type" : "integration.response.header.Content-Type",
                "method.response.header.Content-Length" : "integration.response.header.Content-Length"
              }
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "requestParameters" : {
            "integration.request.path.object" : "method.request.path.item",
            "integration.request.path.bucket" : "method.request.path.folder",
            "integration.request.header.Content-Type" : "method.request.header.Content-Type"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      },
      "delete" : {
        "parameters" : [ {
          "name" : "item",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "folder",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "Content-Length" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "DELETE",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200"
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "requestParameters" : {
            "integration.request.path.object" : "method.request.path.item",
            "integration.request.path.bucket" : "method.request.path.folder"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      },
      "head" : {
        "parameters" : [ {
          "name" : "item",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        }, {
          "name" : "folder",
          "in" : "path",
          "required" : true,
          "schema" : {
            "type" : "string"
          }
        } ],
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "Content-Length" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "HEAD",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path/{bucket}/{object}",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.Content-Type" : "integration.response.header.Content-Type",
                "method.response.header.Content-Length" : "integration.response.header.Content-Length"
              }
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "requestParameters" : {
            "integration.request.path.object" : "method.request.path.item",
            "integration.request.path.bucket" : "method.request.path.folder"
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      }
    },
    "/" : {
      "get" : {
        "responses" : {
          "400" : {
            "description" : "400 response",
            "content" : { }
          },
          "500" : {
            "description" : "500 response",
            "content" : { }
          },
          "200" : {
            "description" : "200 response",
            "headers" : {
              "Content-Length" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Timestamp" : {
                "schema" : {
                  "type" : "string"
                }
              },
              "Content-Type" : {
                "schema" : {
                  "type" : "string"
                }
              }
            },
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/Empty"
                }
              }
            }
          }
        },
        "x-amazon-apigateway-integration" : {
          "credentials" : "arn:aws:iam::123456789012:role/apigAwsProxyRole",
          "httpMethod" : "GET",
          "uri" : "arn:aws:apigateway:us-west-2:s3:path//",
          "responses" : {
            "4\\d{2}" : {
              "statusCode" : "400"
            },
            "default" : {
              "statusCode" : "200",
              "responseParameters" : {
                "method.response.header.Content-Type" : "integration.response.header.Content-Type",
                "method.response.header.Content-Length" : "integration.response.header.Content-Length",
                "method.response.header.Timestamp" : "integration.response.header.Date"
              }
            },
            "5\\d{2}" : {
              "statusCode" : "500"
            }
          },
          "passthroughBehavior" : "when_no_match",
          "type" : "aws"
        }
      }
    }
  },
  "components" : {
    "schemas" : {
      "Empty" : {
        "title" : "Empty Schema",
        "type" : "object"
      }
    }
  }
}
```

------

# 使用 REST API 客户端调用 API
<a name="api-as-s3-proxy-test-using-postman"></a>

为了提供端到端教程，我们现在演示如何使用支持AWS IAM 授权的 [Postman](https://www.postman.com/) 调用 API。<a name="api-as-s3-proxy-test-using-postman-steps"></a>

**使用 Postman 调用我们的 Amazon S3 代理 API**

1. 部署或重新部署 API。记下位于**阶段编辑器**顶部的**调用 URL** 旁边显示的 API 的基本 URL。

1. 启动 Postman。

1. 选择**授权**，然后选择 `AWS Signature`。分别在 **AccessKey** 和 **SecretKey** 输入字段中键入 IAM 用户的访问密钥 ID 和秘密访问密钥。在 **AWS 区域**文本框中输入将您的 API 部署到的 AWS 区域。在**服务名称**输入字段中输入 `execute-api`。

   您可以在 IAM 管理控制台的 IAM 用户账户的**安全凭证**选项卡中创建一对密钥。

1. 要在 `amzn-s3-demo-bucket` 区域内将名为 `{region}` 的存储桶添加到您的 Amazon S3 账户，请执行以下操作：

   1. 从下拉方法列表中选择 **PUT** 并键入方法 URL (`https://api-id.execute-api.aws-region.amazonaws.com/stage/folder-name`)

   1. 将 `Content-Type` 标头值设置为 `application/xml`。在设置内容类型之前，您可能需要先删除任何现有标头。

   1. 选择**正文**菜单项并键入以下 XML 片段作为请求正文：

      ```
      <CreateBucketConfiguration> 
        <LocationConstraint>{region}</LocationConstraint> 
      </CreateBucketConfiguration>
      ```

   1. 选择**发送**以提交请求。如果成功，您应该会收到一个负载为空的 `200 OK` 响应。

1. 要将文本文件添加到存储桶，请按照上述说明执行操作。如果您在 URL 中为 **amzn-s3-demo-bucket** 指定存储桶名称 `{folder}`，为 **Readme.txt** 指定文件名 `{item}`，并提供文本字符串 **Hello, World\$1** 作为文件内容（从而使其成为请求负载），则此请求将成为

   ```
   PUT /S3/amzn-s3-demo-bucket/Readme.txt HTTP/1.1
   Host: 9gn28ca086.execute-api.{region}.amazonaws.com
   Content-Type: application/xml
   X-Amz-Date: 20161015T062647Z
   Authorization: AWS4-HMAC-SHA256 Credential=access-key-id/20161015/{region}/execute-api/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date, Signature=ccadb877bdb0d395ca38cc47e18a0d76bb5eaf17007d11e40bf6fb63d28c705b
   Cache-Control: no-cache
   Postman-Token: 6135d315-9cc4-8af8-1757-90871d00847e
   
   Hello, World!
   ```

   如果一切正常，您应该会收到一个负载为空的 `200 OK` 响应。

1. 要获取我们刚刚添加到 `Readme.txt` 存储桶的 `amzn-s3-demo-bucket` 文件的内容，请发出类似于以下的 GET 请求：

   ```
   GET /S3/amzn-s3-demo-bucket/Readme.txt HTTP/1.1
   Host: 9gn28ca086.execute-api.{region}.amazonaws.com
   Content-Type: application/xml
   X-Amz-Date: 20161015T063759Z
   Authorization: AWS4-HMAC-SHA256 Credential=access-key-id/20161015/{region}/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=ba09b72b585acf0e578e6ad02555c00e24b420b59025bc7bb8d3f7aed1471339
   Cache-Control: no-cache
   Postman-Token: d60fcb59-d335-52f7-0025-5bd96928098a
   ```

   如果成功，您应该会收到负载为 `200 OK` 文本字符串的 `Hello, World!` 响应。

1. 要列出 `amzn-s3-demo-bucket` 存储桶中的项目，请提交以下请求：

   ```
   GET /S3/amzn-s3-demo-bucket HTTP/1.1
   Host: 9gn28ca086.execute-api.{region}.amazonaws.com
   Content-Type: application/xml
   X-Amz-Date: 20161015T064324Z
   Authorization: AWS4-HMAC-SHA256 Credential=access-key-id/20161015/{region}/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=4ac9bd4574a14e01568134fd16814534d9951649d3a22b3b0db9f1f5cd4dd0ac
   Cache-Control: no-cache
   Postman-Token: 9c43020a-966f-61e1-81af-4c49ad8d1392
   ```

   如果成功，您应该会收到 `200 OK` 响应且其 XML 负载在指定存储桶中显示单个项目，除非您在提交请求前将更多文件添加到存储桶中。

   ```
   <?xml version="1.0" encoding="UTF-8"?>
   <ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
       <Name>apig-demo-5</Name>
       <Prefix></Prefix>
       <Marker></Marker>
       <MaxKeys>1000</MaxKeys>
       <IsTruncated>false</IsTruncated>
       <Contents>
           <Key>Readme.txt</Key>
           <LastModified>2016-10-15T06:26:48.000Z</LastModified>
           <ETag>"65a8e27d8879283831b664bd8b7f0ad4"</ETag>
           <Size>13</Size>
           <Owner>
               <ID>06e4b09e9d...603addd12ee</ID>
               <DisplayName>user-name</DisplayName>
           </Owner>
           <StorageClass>STANDARD</StorageClass>
       </Contents>
   </ListBucketResult>
   ```

**注意**  
要上传或下载映像，您需要将内容处理设置为 CONVERT\$1TO\$1BINARY。