如何将 API Gateway REST API 与 Amazon SQS 集成并解决常见错误?

上次更新日期:2022 年 11 月 23 日

我想将 Amazon API Gateway REST API 与 Amazon Simple Queue Service (Amazon SQS) 集成。我还想排查集成错误。我该采取什么步骤?

解决方法

用户配置 API Gateway REST API,以便它们与 Amazon SQS 一起创建集成解决方案。本文提供了将 API Gateway 与 Amazon SQS 集成的步骤以及排查常见设置错误的信息。

设置 REST API 和 Amazon SQS 集成

要将 API Gateway REST API 与 Amazon SQS 集成,请按照以下步骤操作:

1.    创建 SQS 队列

2.    创建 AWS Identity and Access Management (IAM) 角色,然后附加具有 SendMessage 权限的 Amazon SQS 策略。此策略允许将 API 的消息发布到 Amazon SQS。在策略中,将 example-region 替换为 AWS 区域,将 example-account-id 替换为 AWS 账户 ID,将 example-sqs-queue-name 替换为您的 SQS 队列名称。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Resource": [
        "arn:aws:sqs:example-region:example-account-id:example-sqs-queue-name"
      ],
      "Action": [
        "sqs:SendMessage"
      ]
    }
  ]
}

3.    在 API Gateway 中创建 REST API

4.    在 API Gateway 控制台中,为新创建的 REST API 创建 Amazon SQS 集成。

  • 或者,创建 REST API 资源REST API 方法
  • 创建 POST 方法
    对于集成类型,选择 AWS 服务
    对于 AWS 区域,选择您的 AWS 区域。
    对于 AWS 服务,选择 Simple Storage Service (S3)
    对于 AWS 子域,输入可选
    对于 HTTP 方法,选择 POST
    对于操作类型,选择使用路径覆盖
    对于路径覆盖(可选),输入 example-account-id/example-sqs-queue-name,其中将 example-account-id 替换为 AWS 账户 ID,将 example-sqs-queue-nam 替换为 SQS 队列名称。例如,1234567890/mysqsStandardQueue。
    对于执行角色,在第 2 步输入您创建的 IAM 角色的 ARN。
    对于内容处理,选择适合您设置的选项。
    清除或选择默认超时。选择适合您设置的选项。
    保存新的 POST 方法。
  • 继续输入您的 REST API 集成信息。
    选择 POST 方法集成请求
    展开 HTTP 标头
    选择添加标头
    对于名称,输入内容-类型
    对于映射来源,输入 'application/x-www-form-urlencoded',然后选择创建
    展开映射模板
    对于请求正文传递,选择符合您要求的选项。
    选择添加映射模板
    对于内容-类型,输入 application/json,然后选择创建
    对于模板,输入 Action=SendMessage&MessageBody=$input.body

4.    部署配置的 REST API

5.    通过向 API Gateway 发送以下请求来测试设置。将 example-api-id 替换为 API ID,将 example-region 替换为 AWS 区域,将 example-stage 替换为测试阶段名称,将 example-resource 替换为资源名称。

curl --location --request POST 'https://example-api-id.execute-api.example-region.amazonaws.com/example-stage/example-resource' \
    --header 'Content-Type: application/json' \
    --data-raw '{
        "message": "Hello World"
    }'

集成成功后,反映如下所示:

{
    "SendMessageResponse": {
        "ResponseMetadata": {
            "RequestId": "f879fb11-e736-52c0-bd29-a0f2d09ad90d"
        },
        "SendMessageResult": {
            "MD5OfMessageAttributes": null,
            "MD5OfMessageBody": "3fc759ac1733366f98ec4270c788fcd1",
            "MD5OfMessageSystemAttributes": null,
            "MessageId": "4c360c3c-08f4-4392-bc14-8b0c88e314a2",
            "SequenceNumber": null
        }
    }
}

解决常见错误

UnknownOperationException 错误

当用户未能在集成请求 HTTP 标头中将内容-类型配置为 "application/x-www-form-urlencoded" 时,就会出现 unknownoOperationException 错误。如果未将 SendMessage 操作添加到集成请求映射模板中,也会出现 UnknownOperationException 错误。

AccessDenied 错误

以下是 AccessDenied 错误示例:

{
  "Error": {
    "Code": "AccessDenied",
    "Message": "Access to the resource https://sqs.example-region.amazonaws.com/example-account-id/example-sqs-queue-name is denied.",
    "Type": "Sender"
  },
  "RequestId": "92aea8b7-47f1-5bd4-b3c4-f3d0688d3809"
}

当 API 集成执行角色没有设置向 SQS 队列发送消息的 sqs:SendMessage 权限时,就会出现 AccessDenied 错误。在请求正文负载中传递 "&" 和 "%" 等特殊字符时,也会发生 AccessDenied 错误。必须对特殊字符进行编码才能通过。在映射模板中添加 $util.urlEncode() 函数,将请求正文从字符串转换为编码格式。以下是映射模板示例:

Action=SendMessage&MessageBody=$util.urlEncode($input.body)

以下示例包括向 SQS 队列发送消息所需的权限。将 example-region 替换为 AWS 区域,将 example-account-id 替换为 AWS 账户 ID,将 example-sqs-queue-name 替换为 SQS 队列名称。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Resource": [
        "arn:aws:sqs:example-region:example-account-id:example-sqs-queue-name"
      ],
      "Action": [
        "sqs:SendMessage"
      ]
    }
  ]
}

KMS.AccessDeniedException 错误

以下是 KMS.AccessDeniedException 错误的两个示例:

{
  "Error": {
    "Code": "KMS.AccessDeniedException",
    "Message": "User: arn:aws:sts::example-account-number:assumed-role/example-sqs-queue-name/BackplaneAssumeRoleSession is not authorized to perform: kms:GenerateDataKey on resource: arn:aws:kms:example-region:example-account-number:key/example-keyId because no identity-based policy allows the kms:GenerateDataKey action (Service: AWSKMS; Status Code: 400; Error Code: AccessDeniedException; Request ID: c58f1eec-6b18-4029-826b-d05d6a715716; Proxy: null)",
    "Type": "Sender"
  },
  "RequestId": "99976a6a-3311-57e9-86e9-310d0654ff80"
}
{
  "Error": {
    "Code": "KMS.AccessDeniedException",
    "Message": "The ciphertext refers to a customer master key that does not exist, does not exist in this region, or you are not allowed to access. (Service: AWSKMS; Status Code: 400; Error Code: AccessDeniedException; Request ID: a8adea02-c246-49d9-8b3d-ff6b6a43b40f; Proxy: null)",
    "Type": "Sender"
  },
  "RequestId": "9565c451-742c-55f3-a1eb-9f3641fd30aa"
}

当 API 集成执行角色无法通过 AWS Key Management Service (AWS KMS) 执行操作时,会发生 KMS.AccessDeniedException 错误。必须配置权限才能对附加到 Amazon SQS 服务器端加密队列的 AWS KMS 密钥执行操作。

以下示例包括对附加到 SQS 队列的 KMS 密匙执行操作所需的权限。将 example-account-id 替换为 AWS 账户 ID,将 example-api-gw-integration-execution-role 替换为执行角色名称。

{
  "Sid": "Allow use of the key",
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::example-account-id:role/example-api-gw-integration-execution-role"
  },
  "Action": [
    "kms:Encrypt",
    "kms:GenerateDataKey*",
    "kms:Decrypt"
  ],
  "Resource": "*"
}

这篇文章对您有帮助吗?


您是否需要账单或技术支持?