Skip to content

Commit 521b7f8

Browse files
committed
APIGW SQS Lambda - Serverless Framework
1 parent 124402d commit 521b7f8

File tree

7 files changed

+347
-0
lines changed

7 files changed

+347
-0
lines changed
+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# Amazon API Gateway HTTP API to AWS Simple Queue Service (SQS) to Lambda
2+
3+
This pattern creates an Amazon API Gateway HTTP API with a `send` route that send message to a SQS queue. The Amazon API Gateway HTTP API has basic CORS configured. Upon receiving message, SQS will trigger a Lambda function to process the message. The function will only `print` the message. The function is written in TypeScript.
4+
5+
Learn more about this pattern at Serverless Land Patterns: [https://serverlessland.com/patterns/apigw-http-api-sqs-lambda-sls](https://serverlessland.com/patterns/apigw-http-api-sqs-lambda-sls).
6+
7+
Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example.
8+
9+
## Requirements
10+
11+
* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources.
12+
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured
13+
* [Git CLI](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) installed
14+
* [NodeJS](https://nodejs.org/en/download/) (LTS version) installed
15+
* [Serverless Framework CLI](https://www.serverless.com/framework/docs/getting-started) installed
16+
17+
## Deployment Instructions
18+
19+
1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
20+
21+
``` sh
22+
git clone https://github.com/aws-samples/serverless-patterns
23+
```
24+
25+
1. Change directory to the pattern directory:
26+
27+
``` sh
28+
cd serverless-patterns/apigw-http-api-sqs-lambda-sls
29+
```
30+
31+
1. From the command line, use npm to install the development dependencies:
32+
33+
``` sh
34+
npm install
35+
```
36+
37+
1. From the command line, use Serverless Framework to deploy the AWS resources for the pattern as specified in the serverless.yml file:
38+
39+
``` sh
40+
serverless deploy --verbose
41+
```
42+
43+
The above command will deploy resources to `us-east-1` region by default. You can override the target region with `--region <region>` CLI option, e.g.
44+
45+
``` sh
46+
serverless deploy --verbose --region us-west-2
47+
```
48+
49+
1. Note the `ApiEndpoint` output from the Serverless Framework deployment process. You will use this value for testing.
50+
51+
## How it works
52+
53+
The API Gateway handles the incoming API requests and sends the `$request.body.MessageBody` as a message to an SQS queue. A Lambda function is triggered with the posted message.
54+
55+
## Testing
56+
57+
### Sending a new test message to API Gateway endpoint
58+
59+
To test the endpoint first send data using the following command. Be sure to update the endpoint with endpoint of your stack.
60+
61+
``` sh
62+
curl --location --request POST 'ApiEndpoint output value' --header 'Content-Type: application/json' \
63+
--data-raw '{
64+
"MessageBody":"hello"
65+
}'
66+
```
67+
68+
### Expected output
69+
70+
```xml
71+
<?xml version="1.0"?><SendMessageResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/">
72+
<SendMessageResult>
73+
<MessageId>xxxxxx</MessageId>
74+
<MD5OfMessageBody>xxxxxx</MD5OfMessageBody>
75+
</SendMessageResult>
76+
<ResponseMetadata>
77+
<RequestId>xxxx</RequestId>
78+
</ResponseMetadata>
79+
</SendMessageResponse>
80+
```
81+
82+
### CloudWatch logs
83+
84+
Open AWS CloudWatch Console and navigate to [/aws/lambda/apigw-http-api-sqs-lambda-sls-prod-logEvent](https://console.aws.amazon.com/cloudwatch/home#logsV2:log-groups/log-group/$252Faws$252Flambda$252Fapigw-http-api-sqs-lambda-sls-prod-logEvent) log group.
85+
You should be able to see a new Event Stream with the Received Event information, and the number of records received, logged into the stream.
86+
87+
## Cleanup
88+
89+
1. Delete the stack
90+
91+
```sh
92+
serverless remove --verbose
93+
```
94+
95+
1. Confirm the stack has been deleted
96+
97+
```sh
98+
aws cloudformation list-stacks --query "StackSummaries[?contains(StackName,'apigw-http-api-sqs-lambda-sls-prod')].StackStatus"
99+
```
100+
101+
Expected output
102+
103+
```json
104+
[
105+
"DELETE_COMPLETE"
106+
]
107+
```
108+
109+
NOTE: You might need to add `--region <region>` option to AWS CLI command if you AWS CLI default region does not match the one, that you used for the Serverless Framework deployment.
110+
111+
----
112+
Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
113+
114+
SPDX-License-Identifier: MIT-0
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"title": "Using SQS queue to buffer API Gateway HTTP API calls to Lambda"
5+
},
6+
"paths": {
7+
"/": {
8+
"post": {
9+
"responses": {
10+
"default": {
11+
"description": "Successful operation"
12+
}
13+
},
14+
"x-amazon-apigateway-integration": {
15+
"integrationSubtype": "SQS-SendMessage",
16+
"credentials": { "Fn::GetAtt" : [ "MyHttpApiRole", "Arn" ] },
17+
"requestParameters": {
18+
"MessageBody": "$request.body",
19+
"QueueUrl": { "Ref" : "MySqsQueue" }
20+
},
21+
"payloadFormatVersion": "1.0",
22+
"type": "aws_proxy",
23+
"connectionType": "INTERNET"
24+
}
25+
}
26+
}
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"title": "Amazon API Gateway HTTP API to SQS to Lambda",
3+
"description": "This pattern creates an HTTP API endpoint that send message to SQS and trigger a Lambda function to process the message",
4+
"language": "Node.js, TypeScript",
5+
"level": "100",
6+
"framework": "Serverless Framework",
7+
"introBox": {
8+
"headline": "How it works",
9+
"text": [
10+
"This pattern creates an Amazon API Gateway HTTP API with a <code>send</code> route that send message to a SQS queue.",
11+
"The Amazon API Gateway HTTP API has basic CORS configured. ",
12+
"Upon receiving message, SQS will trigger a Lambda function to process the message.",
13+
"The function will only <code>print</code> the message only. The function written in TypeScript."
14+
]
15+
},
16+
"gitHub": {
17+
"template": {
18+
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/apigw-http-api-sqs-lambda-sls",
19+
"templateURL": "serverless-patterns/apigw-http-api-sqs-lambda-sls",
20+
"projectFolder": "apigw-http-api-sqs-lambda-sls",
21+
"templateFile": "serverless.yml"
22+
}
23+
},
24+
"resources": {
25+
"bullets": [
26+
{
27+
"text": "Using Lambda with Amazon SQS",
28+
"link": "https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html"
29+
},
30+
{
31+
"text": "Amazon API Gateway HTTP Integration subtype reference",
32+
"link": "https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-aws-services-reference.html"
33+
}
34+
]
35+
},
36+
"deploy": {
37+
"text": [
38+
"<code>serverless deploy --verbose</code>"
39+
]
40+
},
41+
"testing": {
42+
"text": [
43+
"See the Github repo for detailed testing instructions."
44+
]
45+
},
46+
"cleanup": {
47+
"text": [
48+
"<code>serverless remove --verbose</code>."
49+
]
50+
},
51+
"authors": [
52+
{
53+
"headline": "Presented by Dmitry Gulin, Modernization Architect, AWS",
54+
"name": "Dmitry Gulin",
55+
"bio": "Dmitry is a modernization architect for Professional Services at Amazon Web Services based in the US.",
56+
"imageURL": "https://www.gravatar.com/avatar/223055bd132d244f6a96c3aef7453a5a?s=200"
57+
}
58+
]
59+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "apigw-http-api-sqs-lambda-sls",
3+
"version": "1.0.0",
4+
"license": "MIT-0",
5+
"type": "module",
6+
"devDependencies": {
7+
"@types/aws-lambda": "^8.10.93",
8+
"serverless-plugin-typescript": "^2.1.1",
9+
"typescript": "^4.6.2"
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
service: apigw-http-api-sqs-lambda-sls
2+
frameworkVersion: '^3' # require serverless v3 or later
3+
4+
plugins:
5+
- serverless-plugin-typescript # enable TypeScript support for Lambda functions
6+
7+
provider:
8+
name: aws
9+
10+
# common configuration for all Lambda functions in this stack
11+
runtime: nodejs14.x
12+
architecture: arm64 # use Graviton for running all Lambda functions
13+
14+
# use --region option value or the default - us-east-1
15+
region: ${opt:region, "us-east-1"}
16+
17+
# override the default stage (dev), although we are not using it in the script below
18+
stage: ${opt:stage, "prod"}
19+
20+
# optional, Lambda function's memory size in MB, default is 1024
21+
memorySize: 256
22+
23+
# Lambda function triggered with events from the default EventBridge topic
24+
functions:
25+
logEvent:
26+
handler: src/handler.logEvent
27+
memorySize: 256 # optional, in MB, default is 1024
28+
events:
29+
- sqs:
30+
arn: !GetAtt MySqsQueue.Arn
31+
32+
resources:
33+
# Override the default description
34+
Description: API Gateway HTTP API to SQS, triggering a Lambda function (Serverless Framework).
35+
36+
Resources:
37+
# Define SQS queue
38+
MySqsQueue:
39+
Type: AWS::SQS::Queue
40+
41+
# Create an API Gateway HTTP API
42+
MyHttpApi:
43+
Type: AWS::ApiGatewayV2::Api
44+
Properties:
45+
Body: ${file(./api.json)}
46+
47+
# Create the default stage and configure it to automatically deploy
48+
MyHttpApiStage:
49+
Type: AWS::ApiGatewayV2::Stage
50+
Properties:
51+
ApiId: !Ref MyHttpApi
52+
# we use default stage, instead of the stage name for simplicity.
53+
# Use ${sls:stage} to get the stage name.
54+
StageName: '$default'
55+
AutoDeploy: true
56+
57+
# Create the role for API Gateway access to SQS
58+
MyHttpApiRole:
59+
Type: "AWS::IAM::Role"
60+
Properties:
61+
AssumeRolePolicyDocument:
62+
Version: "2012-10-17"
63+
Statement:
64+
- Effect: "Allow"
65+
Principal:
66+
Service: "apigateway.amazonaws.com"
67+
Action:
68+
- "sts:AssumeRole"
69+
Policies:
70+
- PolicyName: ApiDirectWriteEventBridge
71+
PolicyDocument:
72+
Version: '2012-10-17'
73+
Statement:
74+
Action:
75+
- sqs:SendMessage
76+
Effect: Allow
77+
Resource:
78+
- !GetAtt MySqsQueue.Arn
79+
80+
Outputs:
81+
ApiEndpoint:
82+
Description: "HTTP API endpoint URL"
83+
Value: !Sub "https://${MyHttpApi}.execute-api.${AWS::Region}.amazonaws.com"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: MIT-0
3+
// //
4+
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
5+
// software and associated documentation files (the "Software"), to deal in the Software
6+
// without restriction, including without limitation the rights to use, copy, modify,
7+
// merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
8+
// permit persons to whom the Software is furnished to do so.
9+
// //
10+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
11+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
12+
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
13+
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
14+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
15+
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16+
17+
import { SQSHandler } from 'aws-lambda';
18+
19+
export const logEvent: SQSHandler = async (event) => {
20+
console.log(`Received event: ${JSON.stringify(event)}`);
21+
console.log(`Number of records received: ${event.Records.length}`); // strongly typed access to event records collection
22+
23+
return;
24+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"compilerOptions": {
3+
/* Language and Environment */
4+
"target": "ES2021", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
5+
"lib": [
6+
"ES2021"
7+
], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
8+
9+
/* Modules */
10+
"module": "ES2022", /* Specify what module code is generated. */
11+
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
12+
13+
/* JavaScript Support */
14+
"allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
15+
"checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
16+
17+
/* Emit */
18+
"preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
19+
20+
/* Interop Constraints */
21+
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
22+
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
23+
24+
/* Type Checking */
25+
"strict": true, /* Enable all strict type-checking options. */
26+
"strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
27+
}
28+
}

0 commit comments

Comments
 (0)