如何将 API Gateway 用作其他 AWS 服务的代理?

上次更新时间:2020 年 4 月 16 日

我想要将 Amazon API Gateway 用作其他 AWS 服务的代理。如何将其他服务与 API Gateway 集成?

简短描述

AWS 服务 API 本质上是可向其发出 HTTPS 请求的 REST API。您可以将许多 AWS 服务与 API Gateway 集成,但设置和映射因特定的服务 API 而异。

要将其他服务与 API Gateway 集成,请构建从 API Gateway 到服务 API 的 HTTPS 请求,以便正确映射所有请求参数。

本文介绍了用于将 Amazon Simple Notification Service (Amazon SNS) 发布 API 与 API Gateway 集成的示例设置。您可以将该示例用作集成其他服务的大纲。

解决方法

设置所需的工具和资源

配置您的环境并创建使用案例所需的所有 AWS 资源。对于 Amazon SNS 示例设置,请执行以下操作:

  1. 安装 AWS 命令行界面 (AWS CLI)
  2. 创建 Amazon SNS 主题。请记下该主题的 Amazon 资源名称 (ARN)。您在下一步和后续设置中需要此信息。
  3. 创建主题订阅
  4. 创建 AWS 服务代理执行角色。请记下角色的 ARN,在后续设置中需要使用它。此 AWS Identity and Access Management (IAM) 角色将向 API Gateway 授予以下权限,即作为受信任实体来承担服务并执行要集成的 API 操作。对于 Amazon SNS 示例设置,允许操作 sns:Publish。有关更多信息,请参阅用于调用 API 的 API Gateway 权限模型
  5. 使用测试资源创建 API Gateway REST API。有关更多信息和示例,请参阅 Amazon API Gateway 教程
    注意:(可选)您可以使用以下示例 OpenAPI 2.0 (Swagger) 定义导入 REST API。此选项可预先配置 Amazon SNS 示例设置的相关设置,以便您稍后可以跳过大部分 API Gateway 控制台配置步骤。请务必将 arn:aws:iam::account-id:role/apigateway-sns-role 替换为您的 IAM 角色的 ARN。将 region 替换为要在其中创建 REST API 的 AWS 区域。
{
  "swagger": "2.0",
  "info": {
    "version": "2019-10-09T14:10:24Z",
    "title": "aws-service-integration"
  },
  "basePath": "/dev",
  "schemes": [
    "https"
  ],
  "paths": {
    "/test": {
      "post": {
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "Message",
            "in": "query",
            "required": true,
            "type": "string"
          },
          {
            "name": "topicArn",
            "in": "query",
            "required": true,
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "200 response",
            "schema": {
              "$ref": "#/definitions/Empty"
            }
          }
        },
        "x-amazon-apigateway-integration": {
          "credentials": "arn:aws:iam::account-id:role/apigateway-sns-role",
          "uri": "arn:aws:apigateway:region:sns:action/Publish",
          "responses": {
            "default": {
              "statusCode": "200"
            }
          },
          "requestParameters": {
            "integration.request.querystring.TopicArn": "method.request.querystring.topicArn",
            "integration.request.querystring.Message": "method.request.querystring.Message"
          },
          "passthroughBehavior": "when_no_match",
          "httpMethod": "POST",
          "type": "aws"
        }
      }
    }
  },
  "definitions": {
    "Empty": {
      "type": "object",
      "title": "Empty Schema"
    }
  }
}

获取示例 HTTPS 请求

来自要集成的服务 API 的示例 HTTPS 请求可以帮助您在 API Gateway 中正确映射请求参数。要获取示例 HTTPS 请求,请执行以下操作之一:

  • 在 AWS 文档中查找它

检查 API 文档中的示例。对于 Amazon SNS 发布 API,您可以参阅服务 API 参考以获取示例请求

https://sns.us-west-2.amazonaws.com/?Action=Publish
&TargetArn=arn%3Aaws%3Asns%3Aus-west-2%3A803981987763%3Aendpoint%2FAPNS_SANDBOX%2Fpushapp%2F98e9ced9-f136-3893-9d60-776547eafebb
&Message=%7B%22default%22%3A%22This+is+the+default+Message%22%2C%22APNS_SANDBOX%22%3A%22%7B+%5C%22aps%5C%22+%3A+%7B+%5C%22alert%5C%22+%3A+%5C%22You+have+got+email.%5C%22%2C+%5C%22badge%5C%22+%3A+9%2C%5C%22sound%5C%22+%3A%5C%22default%5C%22%7D%7D%22%7D
&Version=2010-03-31
&AUTHPARAMS
  • 通过 API 调用生成它

使用 AWS CLI 来调用服务 API,然后分析输出。为要集成的服务 API 确定相应的 AWS CLI 命令,然后使用 --debug 选项运行测试请求。

提示:检查 AWS CLI 命令参考以查找相应的 AWS CLI 命令。

对于 Amazon SNS 示例设置,请运行以下命令:

注意:请将 arn:aws:sns:us-east-1:123456789012:test 替换为您的 Amazon SNS 主题的 ARN。

$ aws sns publish --topic-arn arn:aws:sns:us-east-1:123456789012:test --message "hi" --debug

命令输出包含 HTTPS 请求和传递的标头。以下是查找内容的示例:

2018-11-22 11:56:39,647 - MainThread - botocore.client - DEBUG - Registering retry handlers for service: sns
2018-11-22 11:56:39,648 - MainThread - botocore.hooks - DEBUG - Event before-parameter-build.sns.Publish: calling handler <function generate_idempotent_uuid at 0x11093d320>
2018-11-22 11:56:39,649 - MainThread - botocore.endpoint - DEBUG - Making request for OperationModel(name=Publish) (verify_ssl=True) with params: {'body': {'Action': u'Publish', u'Message': u'hello', 'Version': u'2010-03-31', u'TopicArn': u'arn:aws:sns:us-east-1:123456789012:test'}, 'url': u'https://sns.us-east-1.amazonaws.com/', 'headers': {'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8', 'User-Agent': 'aws-cli/1.15.74 Python/2.7.14 Darwin/16.7.0 botocore/1.9.23'}, 'context': {'auth_type': None, 'client_region': 'us-east-1', 'has_streaming_input': False, 'client_config': <botocore.config.Config object at 0x1118437d0>}, 'query_string': '', 'url_path': '/', 'method': u'POST'}
2018-11-22 11:56:39,650 - MainThread - botocore.hooks - DEBUG - Event request-created.sns.Publish: calling handler <bound method RequestSigner.handler of <botocore.signers.RequestSigner object at 0x111843750>>
2018-11-22 11:56:39,650 - MainThread - botocore.hooks - DEBUG - Event choose-signer.sns.Publish: calling handler <function set_operation_specific_signer at 0x11093d230>
2018-11-22 11:56:39,650 - MainThread - botocore.auth - DEBUG - Calculating signature using v4 auth.
2018-11-22 11:56:39,651 - MainThread - botocore.auth - DEBUG - CanonicalRequest:
POST
/

content-type:application/x-www-form-urlencoded; charset=utf-8
host:sns.us-east-1.amazonaws.com
x-amz-date:20181122T062639Z

content-type;host;x-amz-date

在此示例中,请求将作为 POST HTTP 方法发送。

为您的 API Gateway API 创建方法

  1. API Gateway 控制台API 窗格中,选择您的 API 的名称。
  2. 资源窗格中,选择资源。对于 Amazon SNS 示例设置,选择您创建的测试资源。
  3. 选择操作,然后选择创建方法
  4. 在下拉列表中,选择服务 API 在示例 HTTPS 请求中使用的方法。(对于 Amazon SNS 示例设置,请选择 POST。) 然后,选择复选标记图标。
  5. 设置窗格中,执行以下操作:
    对于集成类型,选择 AWS 服务
    对于 AWS 区域,选择与要集成的服务 API 相关联的资源的 AWS 区域。对于 Amazon SNS 示例设置,选择您的 SNS 主题的区域。
    对于 AWS 服务,选择要与 API Gateway 集成的服务。例如,Simple Notification Service (SNS)
    (可选)对于 AWS 子域,输入 AWS 服务使用的子域。请查看服务文档以确认子域的可用性。对于 Amazon SNS 示例设置,将它留空。
    对于 HTTP 方法,选择与要集成的 AWS 服务 API 相对应的方法。对于 Amazon SNS 示例设置,选择 POST
    对于操作类型,如果要集成的服务 API 是受支持的操作,请选择使用操作名称。(请查看服务 API 参考以获取受支持操作的列表。对于 Amazon SNS,请参阅 API 参考中的操作。) 对于操作,输入服务 API 的名称。对于 Amazon SNS 示例设置,请输入发布
    或者,对于操作类型,如果 AWS 服务 API 在请求中需要资源路径,请选择使用路径覆盖。例如,对于 Amazon Polly ListLexicons API,为路径覆盖(可选)输入 /v1/lexicons
    对于执行角色,输入您创建的 IAM 角色的 ARN。
    (可选)对于内容处理使用默认超时,请根据使用案例的需要进行更改。对于 Amazon SNS 示例设置,请不要更改这些设置。
  6. 选择保存

为方法请求创建参数

确定要集成的服务 API 的必需和可选请求参数。要确定这些参数,请参考您之前获得的示例 HTTPS 请求,或参阅服务 API 的 API 参考。例如,参阅发布

  1. API Gateway 控制台中,在 API Gateway API 方法的方法执行窗格上,选择方法请求
  2. (可选)在方法请求窗格上,对于请求验证器,如果要验证查询字符串参数(以及请求正文和标头),请选择一个请求验证器。
  3. 展开 URL 查询字符串参数
  4. 选择添加查询字符串
  5. 对于名称,输入要集成的服务 API 的请求参数名称。
  6. 选择复选标记图标(创建新的查询字符串)。
  7. 如果该参数是必需参数,请选中必需下的复选框。
  8. 为要包含的所有请求参数重复步骤 4-7。对于 Amazon SNS 示例设置,创建一个名为 TopicArn 的参数和另一个名为 Message 的参数。

有关更多信息,请参阅使用 API Gateway 控制台设置方法

注意:对于某些服务 API,除了必需参数以外,还必须在集成请求中发送必需的标头和正文。如果要集成的服务 API 需要这些信息,请在集成请求窗格的 HTTP 请求标头请求正文下创建它们。

例如,如果要集成 Amazon Rekognition ListCollections API,请创建标头 X-Amz-Target: RekognitionService.ListCollections。该请求如下所示:

  POST https://rekognition.us-west-2.amazonaws.com/ HTTP/1.1
    Host: rekognition.us-west-2.amazonaws.com
    Accept-Encoding: identity
    Content-Length: 2
    X-Amz-Target: RekognitionService.ListCollections
    X-Amz-Date: 20170105T155800Z
    User-Agent: aws-cli/1.11.25 Python/2.7.9 Windows/8 botocore/1.4.82
    Content-Type: application/x-amz-json-1.1
    Authorization: AWS4-HMAC-SHA256 Credential=XXXXXXXX/20170105/us-west-2/rekognition/aws4_request,
      SignedHeaders=content-type;host;x-amz-date;x-amz-target, Signature=XXXXXXXX

    {}

另一个例子是,如果要集成 Amazon Simple Queue Service (Amazon SQS) SendMessage API,则可以使用映射表达式 method.request.body.JSONPath_EXPRESSION映射请求正文。(将 JSONPath_EXPRESSION 替换为请求正文的 JSON 字段的 JSONPath 表达式。) 在此示例中,请求如下所示:

{'url_path': '/', 'query_string': '', 'method': 'POST',
'headers': {'Content-Type': 'application/x-www-form-urlencoded; 
charset=utf-8', 'User-Agent': 'aws-cli/1.16.81 Python/3.6.5 Darwin/18.7.0 botocore/1.12.183'}, 
'body': {'Action': 'SendMessage', 'Version': '2012-11-05', 'QueueUrl': 'https://sqs.ap-southeast-2.amazonaws.com/123456789012/test01', 'MessageBody': 'Hello'}, 
'url': 'https://ap-southeast-2.queue.amazonaws.com/', 'context': {'client_region': 'ap-southeast-2', 'client_config': <botocore.config.Config object at 0x106862da0>, 'has_streaming_input': False, 'auth_type': None}}

为集成请求创建参数

将您为方法请求创建的参数映射到集成请求参数。

  1. API Gateway 控制台中,返回 API Gateway API 方法的方法执行窗格,然后选择集成请求
  2. 集成请求窗格中,展开 URL 查询字符串参数
  3. 选择添加查询字符串
  4. 对于名称,输入要集成的服务 API 的请求参数名称。
    注意:名称区分大小写,并且必须完全按服务 API 的预期显示。
  5. 对于映射来源,输入 method.request.querystring.param_name,将 param_name 替换为您为方法请求创建的相应参数的名称。例如,method.request.querystring.TopicArn
  6. 选择复选标记图标(创建)。
  7. 重复步骤 3-6,为集成请求创建与为方法请求创建的每个参数相对应的参数。

注意:如果您已为方法请求创建必需的标头和正文,则也将它们映射到集成请求。可在集成请求窗格的 HTTP 标头映射模板下创建它们。

有关更多信息,请参阅使用 API Gateway 控制台设置 API 集成请求

(可选)检查您的集成配置

要确认集成设置符合你的预期,您可以运行 AWS CLI get-integration 命令来检查配置。例如:

$ aws apigateway get-integration --rest-api-id 1234123412 --resource-id y9h6rt --http-method POST

对于 Amazon SNS 示例设置,输出如下所示:

{
    "integrationResponses": {
        "200": {
            "responseTemplates": {
                "application/json": null
            },
            "statusCode": "200"
        }
    },
    "passthroughBehavior": "WHEN_NO_MATCH",
    "timeoutInMillis": 29000,
    "uri": "arn:aws:apigateway:us-east-2:sns:action/Publish",
    "httpMethod": "POST",
    "cacheNamespace": "y9h6rt",
    "credentials": "arn:aws:iam::1234567890:role/apigateway-sns-role",
    "type": "AWS",
    "requestParameters": {
        "integration.request.querystring.TopicArn": "method.request.querystring.topicArn",
        "integration.request.querystring.Message": "method.request.querystring.Message"
    },
    "cacheKeyParameters": []
}

测试您的设置

  1. API Gateway 控制台中,返回 API Gateway API 方法的方法执行窗格,然后选择测试
  2. 方法测试窗格中,执行以下操作:
    对于查询字符串,输入包含请求参数及其值的查询字符串。对于 Amazon SNS 示例设置,输入 TopicArn= arn:aws:sns:us-east-1:123456789012:test&Message="Hello",将 arn:aws:sns:us-east-1:123456789012:test 替换为您的 Amazon SNS 主题的 ARN。
    对于标头请求正文,如果您已为设置创建它们,请输入标头名称和请求正文 JSON。
    选择测试。响应将显示在方法测试窗格中。如果响应成功,您会看到状态:200。对于 Amazon SNS 示例设置,成功响应在响应正文中包含 MessageId
    有关更多信息,请参阅使用 API Gateway 控制台测试 REST API 方法
  3. 部署您的 REST API
  4. 使用您喜欢的任何工具测试您的 API。