Amazon API Gateway
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

教程:在 API Gateway 中创建 REST API 作为 Amazon S3 代理

作为展示如何在 API Gateway 中使用 REST API 以代理 Amazon S3 的示例,本部分将介绍如何创建和配置 REST API 以公开以下 Amazon S3 操作:

注意

要将 API Gateway API 与 Amazon S3 集成,您必须选择一个同时提供 API Gateway 和 Amazon S3 服务的区域。有关区域可用性,请参阅区域和终端节点

您可能需要导入示例 API 作为 Amazon S3 代理,如 作为 Amazon S3 代理的示例 API 的 OpenAPI 定义 中所示。有关如何使用 OpenAPI 定义导入 API 的说明,请参阅 将 REST API 导入 API Gateway 中

要使用 API Gateway 控制台创建 API,您必须先注册一个 AWS 账户。

如果您没有 AWS 账户,请通过以下步骤创建一个账户。

注册 AWS

  1. 打开 http://www.amazonaws.cn/,然后选择 Create an AWS Account

  2. 按照屏幕上的说明进行操作。

为 API 设置 IAM 权限以调用 Amazon S3 操作

要允许 API 调用所需的 Amazon S3 操作,您必须将适当的 IAM 策略附加到 IAM 角色。下一节介绍如何验证并创建 (如有必要) 必需的 IAM 角色和策略。

为了使您的 API 能够查看或列出 Amazon S3 存储桶和对象,您可以在 IAM 角色中使用 IAM 提供的 AmazonS3ReadOnlyAccess 策略。此策略的 ARN 为 arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess,如下所示:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:Get*", "s3:List*" ], "Resource": "*" } ] }

本策略文档表示可以在任意 Amazon S3 资源上调用任何 Amazon S3 Get*List* 操作。

为了使您的 API 能够更新 Amazon S3 存储桶和对象,您可以针对任何 Amazon S3 Put* 操作使用自定义策略,如下所示:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:Put*", "Resource": "*" } ] }

为了使您的 API 能够使用 Amazon S3 Get*List*Put* 操作,您可以将上述只读和仅限 put 操作的策略添加到 IAM 角色。

为了使您的 API 能够调用 Amazon S3 Post* 操作,您必须在 IAM 角色中针对 s3:Post* 操作使用“允许”策略。有关 Amazon S3 操作的完整列表,请参阅在策略中指定 Amazon S3 权限

为了使您的 API 能够创建、查看、更新和删除 Amazon S3 中的存储桶和对象,您可以在 IAM 角色中使用 IAM 提供的 AmazonS3FullAccess 策略。ARN 为 arn:aws:iam::aws:policy/AmazonS3FullAccess

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

已选择需要使用的 IAM 策略,现在创建 IAM 角色并将其附加到策略。产生的 IAM 角色必须包含以下信任策略,以便 API Gateway 在运行时担任该角色。

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

使用 IAM 控制台创建角色时,请选择 Amazon API Gateway 角色类型,以确保自动包含此信任策略。

创建 API 资源来代表 Amazon S3 资源

我们将使用 API 的根 (/) 资源作为经身份验证的调用方的 Amazon S3 存储桶的容器。我们还将创建 FolderItem 资源来分别代表特定的 Amazon S3 存储桶和 Amazon S3 对象。调用方将按照作为请求 URL 一部分的路径参数形式指定文件夹名称和对象键。

注意

在访问其对象键包含 / 或任何其他特殊字符的对象时,字符需要进行 URL 编码。例如,test/test.txt 应编码为 test%2Ftest.txt

创建公开 Amazon S3 服务功能的 API 资源

  1. 在 API Gateway 控制台中,创建名为 MyS3 的 API。此 API 的根资源 (/) 表示 Amazon S3 服务。

  2. 在 API 的根资源中,创建一个名为 Folder (文件夹) 的子资源并将所需的 Resource Path (资源路径) 设置为 /{folder}

  3. 对于 API 的文件夹资源,创建一个项目子资源。将所需的 Resource Path (资源路径) 设置为 /{item}

    
                                    在 API Gateway 中创建 API 作为 Amazon S3 代理

公开 API 方法以列出调用方的 Amazon S3 存储桶

在获取调用方的 Amazon S3 存储桶列表的过程中,涉及针对 Amazon S3 调用 GET 服务操作。在 API 的根资源 (/) 上,创建 GET 方法。按如下所示,配置 GET 方法以与 Amazon S3 集成。

创建和初始化 API 的 GET / 方法

  1. 资源面板右上角的 操作下拉菜单中,在根节点 (/) 上选择 Create method (创建方法)

  2. 在 HTTP 动词的下拉列表中选择 GET,然后选择对勾图标以开始创建方法。

    
                        创建用于与 Amazon S3 集成的方法
  3. / - GET - Setup 窗格中,为 Integration type (集成类型) 选择 AWS Service (AWS 服务)

  4. 从列表中,为 AWS Region 选择区域 (例如,us-west-2)。

  5. AWS Service (AWS 服务),选择 S3

  6. 对于 AWS Subdomain (AWS 子域),将其保留为空。

  7. HTTP method (HTTP 方法),选择 GET

  8. 对于 Action Type (操作类型),选择 Use path override (使用路径覆盖)。利用路径覆盖,API Gateway 可将客户端请求作为对应的 Amazon S3 REST API 路径样式请求转发到 Amazon S3,其中 Amazon S3 资源用 s3-host-name/bucket/key 模式的资源路径表示。API Gateway 设置 s3-host-name 并将客户端指定的 bucketkey 从客户端传递到 Amazon S3。

  9. (可选)在 Path override (路径覆盖) 中键入 /

  10. 复制之前创建的 IAM 角色的 ARN(来自 IAM 控制台),并将其粘贴到 Execution role 中。

  11. 将任何其他设置保留为默认值。

  12. 选择保存以完成此方法的设置。

此设置会将前端 GET https://your-api-host/stage/ 请求与后端 GET https://your-s3-host/ 集成。

注意

进行初始设置后,您可以在方法的 Integration Request (集成请求) 页面中修改这些设置。

为了控制哪些用户可以调用此 API 方法,我们启用了方法授权标记并将其设置为 AWS_IAM

使 IAM 能够控制对 GET / 方法的访问权限

  1. Method Execution (方法执行),选择 Method Request (方法请求)

  2. 选择 Authorization (授权) 旁的铅笔图标

  3. 从下拉列表中,选择 AWS_IAM

  4. 选择对勾图标以保存设置。

    
                声明方法响应类型

为使我们的 API 能够正确地向调用方返回成功响应和异常,我们在 Method Response (方法响应) 中声明 200、400 和 500 响应。我们针对 200 响应使用默认映射,以便将未在此处声明的状态代码的后端响应作为 200 响应返回给调用方。

声明 GET / 方法的响应类型

  1. Method Execution (方法执行) 窗格,选中 Method Response (方法响应) 框。默认情况下,API Gateway 将声明 200 响应。

  2. 选择 Add response (添加响应),在输入文本框中输入 400,然后选择勾选标记以完成声明。

  3. 重复以上步骤以声明 500 响应类型。最终设置如下所示:

    
                声明方法响应类型

因为来自 Amazon S3 的成功集成响应会返回存储桶列表作为 XML 负载,并且来自 API Gateway 的默认方法响应会返回 JSON 负载,所以我们必须将后端 Content-Type 标头参数值映射到对应前端。或者,当响应正文实际上为 XML 字符串时,客户端将接收内容类型的 application/json。以下步骤将演示如何对其进行设置。此外,我们还希望向客户端展示其他标头参数,如 Date 和 Content-Length。

设置用于 GET / 方法的响应标头映射

  1. 在 API Gateway 控制台中,选择 Method Response (方法响应)。针对 200 响应类型添加 Content-Type (内容 - 类型) 标头。

    
                声明方法响应标头
  2. Integration Response (集成响应) 中,对于 Content-Type (内容 - 类型),键入方法响应的 integration.response.header.Content-Type

    
                将集成响应标头映射到方法响应标头

    借助上述标头映射,API Gateway 会将后端的 Date 标头转换为客户端的 Timestamp 标头。

  3. 仍然在 Integration Response (集成响应) 中,选择 Add integration response (添加集成响应),在 HTTP status regex (HTTP 状态正则表达式) 文本框中为剩余的方法响应状态键入相应的正则表达式。重复此步骤,直至涵盖所有的方法响应状态。

    
                设置集成响应状态代码

作为一个良好做法,我们来测试到目前为止已配置的 API。

在 API 根资源上测试 GET 方法

  1. 返回到 Method Execution (方法执行),从客户端框中选择测试

  2. GET / - Method Test 窗格中选择测试。下面显示了一个示例结果。

    
                测试 API 根 GET 存储桶结果

注意

要使用 API Gateway 控制台测试作为 Amazon S3 代理的 API,请确保目标 S3 存储桶来自与 API 区域不同的区域。否则,您可能会收到 500 内部服务器错误响应。此限制不适用于任何已部署的 API。

公开 API 方法以访问 Amazon S3 存储桶

为了使用 Amazon S3 存储桶,我们在 /{folder} 资源上公开 GET、PUT 和 DELETE 方法以列出存储桶中的对象、创建新存储桶和删除现有存储桶。相关说明类似于公开 API 方法以列出调用方的 Amazon S3 存储桶中所述的说明。在下面的讨论中,我们将概述常规任务并重点介绍相关差异。

在 Folder 资源上公开 GET、PUT 和 DELETE 方法

  1. 资源树的 /{folder} 节点上,创建 DELETE、GET 和 PUT 方法,一次创建一个。

  2. 设置每个创建的方法与其相应 Amazon S3 终端节点的初始集成。下面的屏幕截图说明了 PUT /{folder} 方法的这一设置。对于 DELETE /{folder}GET /{folder} 方法,分别使用 DELETEGET 替换 HTTP method (HTTP 方法)PUT 值。

    
                          设置 PUT /{folder} 方法

    请注意,我们在 Amazon S3 终端节点 URL 中使用 {bucket} 路径参数来指定存储桶。我们需要将方法请求的 {folder} 路径参数映射到集成请求的 {bucket} 路径参数。

  3. 要将 {folder} 映射到 {bucket},请执行以下操作:

    1. 依次选择 Method Execution (方法执行)Integration Request (集成请求)

    2. 展开 URL Path Parameters (URL 路径参数),然后选择 Add path (添加路径)

    3. 名称列中键入 bucket,在 Mapped from (映射来源) 列中键入 method.request.path.folder。选择对勾图标以保存映射。

      
                              设置 PUT /{folder} 方法
  4. Method Request (方法请求) 中,将 Content-Type 添加到 HTTP Request Headers (HTTP 请求标头) 部分。

    
                          设置 PUT /{folder} 方法

    这主要用于测试,以及使用 API Gateway 控制台和必须指定 XML 负载的 application/xml 的情况。

  5. Integration Request (方法请求) 中,按照 公开 API 方法以列出调用方的 Amazon S3 存储桶 中的说明设置以下标头映射。

    
                        设置 PUT /{folder} 方法的标头映射

    x-amz-acl 标头用于指定文件夹(或相应 Amazon S3 存储桶)上的访问控制。有关更多信息,请参阅 Amazon S3 PUT 存储桶请求

  6. 要测试 PUT 方法,请在 Method Execution (方法执行) 中的客户端框中选择测试,然后输入以下内容作为测试的输入:

    1. 文件夹中,键入存储桶名称。

    2. 对于 Content-Type (内容 - 类型) 标头,键入 application/xml

    3. Request Body (请求正文) 中,提供存储桶区域作为位置约束,该约束在 XML 片段中声明为请求负载。例如,

      <CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <LocationConstraint>{region}</LocationConstraint> </CreateBucketConfiguration>
      
                              测试 PUT 方法以创建 Amazon S3 存储桶。
  7. 重复上述步骤,在 API 的 /{folder} 资源上创建并配置 GET 和 DELETE 方法。

上述示例说明了如何在指定区域创建新存储桶,如何查看存储桶中对象的列表,以及如何删除存储桶。其他 Amazon S3 存储桶操作允许您使用存储桶的元数据或属性。例如,您可以设置 API 以调用 Amazon S3 的 PUT /?notification 操作,从而设置存储桶通知;或者调用 PUT /?acl,从而设置存储桶上的访问控制列表,等等。API 设置基本类似,除了必须将适当的查询参数附加到 Amazon S3 终端节点 URL 的情况。在运行时,您必须向方法请求提供适当的 XML 负载。关于 Amazon S3 存储桶上对另外两个 GET 和 DELETE 操作的支持,情况同样如此。有关存储桶上可能的 &S3; 操作的更多信息,请参阅存储桶上的 Amazon S3 操作

公开 API 方法以访问存储桶中的 Amazon S3 对象

Amazon S3 支持执行 GET、DELETE、HEAD、OPTIONS、POST 和 PUT 操作以访问和管理给定存储桶中的对象。有关支持操作的完整列表,请参阅对象上的 Amazon S3 操作

在本教程中,我们分别通过 PUT /{folder}/{item}GET /{folder}/{item}HEAD /{folder}/{item}DELETE /{folder}/{item} 的 API 方法公开了 PUT Object 操作、GET Object 操作、DELETE ObjectHEAD Object

/{folder}/{item} 上的 PUT、GET 和 DELETE 方法的 API 设置类似于 /{folder} 上的设置,如公开 API 方法以访问 Amazon S3 存储桶中所述。一个主要区别在于,对象相关请求路径具有 {item} 的额外路径参数,此路径参数必须映射到 {object} 的集成请求路径参数。


                  将 /{folder}/{item} 资源上的 PUT 方法请求与 Amazon S3 集成

GET 和 DELETE 方法也是如此。

举例说明,以下屏幕截图显示了使用 API Gateway 控制台在 {folder}/{item} 资源上测试 GET 方法时的输出。该请求正确返回 ("Welcome to README.txt") 的纯文本作为给定 Amazon S3 存储桶 (apig-demo) 中指定文件 (README.txt) 的内容。


                  测试 API Folder/Item GET 存储桶结果

要下载或上传二进制文件 (在 API Gateway 中被视为 utf-8 编码的 JSON 内容之外的任何项),需要额外的 API 设置。概述如下所示:

从 S3 下载或上传二进制文件

  1. 将受影响文件的介质类型注册到 API 的 binaryMediaTypes。您可以在控制台中执行此操作:

    1. 为 API 选择 Binary Support (二进制支持)(从 API Gateway 主导航面板中),

    2. 选择 Edit

    3. 键入所需的介质类型(例如,对于 Binary media types (二进制介质类型),键入 image/png)。

    4. 选择 Add binary media type (添加二进制介质类型) 以保存设置。

  2. Content-Type (用于上传) 和/或 Accept (用于下载) 标头添加到方法请求,以要求客户端指定所需的二进制介质类型并将其映射到集成请求。

  3. 在集成请求(用于上传)和集成响应(用于下载)中,将 Content Handling (内容处理) 设置为 Passthrough。确保未为受影响的内容类型定义任何映射模板。有关更多信息,请参阅集成传递行为选择 VTL 映射模板

负载大小限制为 10 MB。请参阅 配置和运行 REST API 的 API Gateway 限制

确保 Amazon S3 上的文件具有作为文件的元数据添加的正确内容类型。对于可流式传输的介质内容,可能还需将 Content-Disposition:inline 添加到元数据。

有关 API Gateway 中的二进制文件支持的更多信息,请参阅 API Gateway 中的内容类型转换

使用 REST API 客户端调用 API

为了提供端到端教程,我们现在演示如何使用支持 AWS IAM 授权的 Postman 调用 API。

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

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

  2. 启动 Postman。

  3. 选择 Authorization (授权),然后选择 AWS Signature。分别在 AccessKeySecretKey 输入字段中输入您的 IAM 用户的访问密钥 ID 和秘密访问密钥。在 AWS Region 文本框中输入您的 API 部署到的 AWS 区域。在 Service Name (服务名称) 输入字段中键入 execute-api

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

  4. 要在 {region} 区域内将名为 apig-demo-5 的存储桶添加到您的 Amazon S3 账户,请执行以下操作:

    注意

    请确保存储桶名称具有全局唯一性。

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

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

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

      <CreateBucketConfiguration> <LocationConstraint>{region}</LocationConstraint> </CreateBucketConfiguration>
    4. 选择发送以提交请求。如果成功,您应该会收到一个负载为空的 200 OK 响应。

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

    PUT /S3/apig-demo-5/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 响应。

  6. 要获取我们刚刚添加到 Readme.txt 存储桶的 apig-demo-5 文件的内容,请发出类似于以下的 GET 请求:

    GET /S3/apig-demo-5/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! 响应。

  7. 要列出 apig-demo-5 存储桶中的项目,请提交以下请求:

    GET /S3/apig-demo-5 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_TO_BINARY。