Getting API Gateway to post direct to SQS
Do more with less
In the last post we looked at using CDK to develop a serverless pipeline to deploy code. So now it’s time to iterate and see if we can improve things.
I remember seeing at post from Richard Boyd on Mastering API Gateway in 105 easy steps which is a great read on how powerful API Gateway can be integrating with a laundry list of AWS services out fo the box.
So I figured we could drop one of my Lambda functions and get API Gateway to post direct to SQS. I thought this was going to be simple, but it turns out API Gateway is a bit of a beast and requires some request/response transforms and mappings, but we got there in the end and thought I would share.
This is what the main CDK file looks like now with regards to API Gateway and SQS.
//Create an IAM Role for API Gateway to assume
const apiGatewayRole = new iam.Role(sharedStack, 'ApiGatewayRole', {
assumedBy: new ServicePrincipal('apigateway.amazonaws.com')
});
//Create an empty response model for API Gateway
var model :EmptyModel = {
modelId: "Empty"
};
//Create a method response for API Gateway using the empty model
var methodResponse :MethodResponse = {
statusCode: '200',
responseModels: {'application/json': model}
};
//Add the method options with method response to use in API Method
var methodOptions :MethodOptions = {
methodResponses: [
methodResponse
]
};
//Create intergration response for SQS
var integrationResponse :IntegrationResponse = {
statusCode: '200'
};
//Create integration options for API Method
var integrationOptions :IntegrationOptions = {
credentialsRole: apiGatewayRole,
requestParameters: {
'integration.request.header.Content-Type': "'application/x-www-form-urlencoded'"
},
requestTemplates: {
'application/json': 'Action=SendMessage&QueueUrl=$util.urlEncode("' + sqsQueue.queueUrl + '")&MessageBody=$util.urlEncode($input.body)'
},
integrationResponses: [
integrationResponse
]
};
//Create the SQS Integration
const apiGatewayIntegration = new apigw.AwsIntegration({
service: "sqs",
path: sharedStack.env.account + '/' + sqsQueue.queueName,
integrationHttpMethod: "POST",
options: integrationOptions,
});
//Create the API Gateway
const apiGateway = new apigw.RestApi(sharedStack, "Endpoint");
//Create a API Gateway Resource
const msg = apiGateway.root.addResource('msg');
//Create a Resource Method
msg.addMethod('POST', apiGatewayIntegration, methodOptions);
//Grant API GW IAM Role access to post to SQS
sqsQueue.grantSendMessages(apiGatewayRole);
Check out the full source here
Now I can remove the Lambda function, pipeline and most importantly save some $$$