如何将 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": "*"
}