How do I integrate an API Gateway REST API with Amazon SQS and resolve common errors?
I want to integrate an Amazon API Gateway REST API with Amazon Simple Queue Service (Amazon SQS). I also want to troubleshoot integration errors. What steps do I take?
Resolution
Users configure API Gateway REST APIs so that they work with Amazon SQS to create an integrated solution. This article provides steps to integrate API Gateway with Amazon SQS and information to troubleshoot common setup errors.
Set up REST API and an Amazon SQS integration
To integrate an API Gateway REST API with Amazon SQS, follow these steps:
1. Create an SQS queue.
2. Create an AWS Identity and Access Management (IAM) role, and then attach an Amazon SQS policy with a
SendMessage
permission. This policy allows messages from the API to be published to Amazon SQS. In the policy, replace
example-region
with your AWS Region,
example-account-id
with your AWS account ID, and
example-sqs-queue-name
with your SQS queue name.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
"arn:aws:sqs:example-region:example-account-id:example-sqs-queue-name"
],
"Action": [
"sqs:SendMessage"
]
}
]
}
3. Create a REST API in API Gateway.
4. In the API Gateway console, create an Amazon SQS integration for your newly created REST API.
-
Optionally, create a REST API resource or a REST API method.
-
Create a POST method.
For
Integration type
, choose
AWS Service
.
For
AWS Region
, choose your AWS Region.
For
AWS Service
, choose
Simple Queue Service (SQS)
.
For
AWS Subdomain
, enter
Optional
.
For
HTTP method
, choose
POST
.
For
Action Type
, choose
Use path override
.
For
Path override (optional)
, enter
example-account-id/example-sqs-queue-name
where you replace
example-account-id
with your AWS account ID and
example-sqs-queue-name
with your SQS queue name. For example, 1234567890/MySQSStandardQueue.
For
Execution role
, enter the ARN of the IAM role created in
step 2
.
For
Content Handling
, choose the option that fits your setup.
Clear or select
Default Timeout
. Choose the option that fits your setup.
Save the new POST method.
-
Continue entering your REST API integration information.
Choose the POST method
Integration Request
.
Expand
HTTP Headers
.
Choose
Add header
.
For
Name
, enter
Content-Type
.
For
Mapped from
, enter
'application/x-www-form-urlencoded'
and choose
Create
.
Expand
Mapping Templates
.
For
Request body passthrough
, select the option that fits your requirements.
Choose Add mapping template
.
For
Content-Type
, enter
application/json
and choose
Create
.
For the template, enter
Action=SendMessage&MessageBody=$input.body
4. Deploy the configured REST API.
5. Test the setup by sending the following request to API Gateway. Replace
example-api-id
with your API ID,
example-region
with your AWS Region,
example-stage
with your testing stage name, and
example-resource
with your resource name.
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"
}'
When your integration is successful, your response looks similar to the following:
{
"SendMessageResponse": {
"ResponseMetadata": {
"RequestId": "f879fb11-e736-52c0-bd29-a0f2d09ad90d"
},
"SendMessageResult": {
"MD5OfMessageAttributes": null,
"MD5OfMessageBody": "3fc759ac1733366f98ec4270c788fcd1",
"MD5OfMessageSystemAttributes": null,
"MessageId": "4c360c3c-08f4-4392-bc14-8b0c88e314a2",
"SequenceNumber": null
}
}
}
Resolving common errors
UnknownOperationException error
An
UnknownOperationException
error occurs when a user fails to configure the
Content-Type
as
"application/x-www-form-urlencoded"
in the integration request HTTP header. The
UnknownOperationException
error also occurs when the SendMessage action isn’t added to the integration request mapping template.
AccessDenied error
The following is an example of an AccessDenied error:
{
"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"
}
An
AccessDenied
error occurs when the API integration execution role doesn’t have the
sqs:SendMessage
permission set to send messages to the SQS queue. The
AccessDenied
error can also occur when special characters such as "&" and "%" are passed in the request body payload. The special characters must be encoded to pass. Add the $util.urlEncode() function in the mapping template to convert the request body from a string to an encoded format. The following is an example mapping template:
Action=SendMessage&MessageBody=$util.urlEncode($input.body)
The following example includes the permissions needed to send messages to the SQS queue. Replace
example-region
with your AWS Region,
example-account-id
with your AWS account ID, and
example-sqs-queue-name
with your SQS queue name.
{
"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 error
The following are two examples of
KMS.AccessDeniedException
errors:
{
"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"
}
A
KMS.AccessDeniedException
error occurs when the API integration execution role can’t perform operations through AWS Key Management Service (AWS KMS). Permission must be configured to perform operations on the AWS KMS keys that are attached to the Amazon SQS server-side encrypted queue.
The following example includes the permissions needed to perform operations on the KMS keys attached to the SQS queue. Replace
example-account-id
with your AWS account ID, and
example-api-gw-integration-execution-role
with your execution role name.
{
"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": "*"
}
Submit feedback
Do you need billing or technical support?
Contact AWS Support