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

3 分钟阅读
0

我想将 Amazon API Gateway REST API 与 Amazon Simple Queue Service(Amazon SQS)集成,并对集成错误进行故障排除。

解决方法

要创建集成解决方案,请配置 API Gateway REST API 以与 Amazon SQS 配合使用。

设置 REST API 和 Amazon SQS 集成

完成以下步骤:

  1. 创建 SQS 队列
  2. 创建 AWS Identity and Access Management(IAM)角色,然后附加具有 SendMessage 权限的 Amazon SQS 策略。该政策允许您从 API 向 Amazon SQS 发布消息:
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Resource": [
            "arn:aws:sqs:example-region:example-account-id:example-sqs-queue-name"
          ],
          "Action": [
            "sqs:SendMessage"
          ]
        }
      ]
    }
    **注意:**将 example-region 替换为您的 AWS 区域,将 example-account-id 替换为您的 AWS 账户 ID,将 example-sqs-queue-name 替换为您的 SQS 队列名称。
  3. 在 API Gateway 中创建 REST API
  4. API Gateway 控制台中,为您的 REST API 创建 Amazon SQS 集成。
  5. (可选)创建 REST API 资源或 REST API 方法
    资源界面,选择创建方法
    对于方法类型,选择 POST
    对于集成类型,选择 AWS 服务
    对于 AWS 区域,选择您的区域。
    对于 AWS 服务,选择 Simple Queue Service(SQS)
    (可选)对于 AWS 子域,输入 AWS 服务使用的子域。查看 AWS 产品文档,确认子域是否可用。对于 Amazon SQS 示例设置,请将其留空。
    对于 HTTP 方法,选择 POST
    对于操作类型,选择使用路径覆盖
    对于路径覆盖(可选),请按以下格式输入您的账户 ID 和 SQS 队列名称:example-account-id/example-sqs-queue-name。例如: 1234567890/MySQSStandardQueue
    对于执行角色,输入 IAM 角色的 ARN。
    默认超时中,为您的设置选择一个选项。
    继续输入您的 REST API 集成信息。
    选择 POST 方法集成请求
    选择编辑
    对于请求正文传递,请选择符合您要求的选项。
    展开 URL 请求标头参数
    选择添加请求标头参数
    名称中,输入 Content-Type
    对于映射自,输入 'application/x-www-form-urlencoded'
    展开映射模板
    选择添加映射模板
    对于 Content-Type,输入 application/json
    对于模板,输入 Action=SendMessage&MessageBody=$input.body,然后选择保存
  6. 部署 REST API
  7. 要测试这个设置,请向 API Gateway 发送以下请求:
    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"
      }'
    **注意:**将 example-api-id 替换为您的 API ID,将 example-region 替换为您的区域,将 example-stage 替换为您的测试阶段名称,将 example-resource 替换为您的资源名称。
    成功集成后,您将看到如下所示的回复:
    {
      "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 标头中将 Content-Type 配置为 "application/x-www-form-urlencoded" 时,会出现 UnknownOperationException 错误。当您没有将 SendMessage 操作添加到集成请求映射模板时,也会出现 UnknownOperationException 错误。要解决此错误,请确保 Content-Type 格式正确,并在映射模板中包含 SendMessage 操作。

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 队列发送消息所需的权限:

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

**注意:**将 example-region 替换为您的区域,将 example-account-id 替换为您的账户 ID,将 example-sqs-queue-name 替换为您的 SQS 队列名称。

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 密钥执行操作所需的权限:

{
  "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": "*"
}

**注意:**将 example-account-id 替换为您的账户 ID,将 example-api-gw-integration-execution-role 替换为您的执行角色名称。

相关信息

使用 HTTP 自定义集成创建 API

AWS 官方
AWS 官方已更新 7 个月前