The AWS SDK for JavaScript V3 API Reference Guide describes in detail all the API operations for the AWS SDK for JavaScript version 3 (V3).
Invoking Lambda with API Gateway
You can invoke a Lambda function by using Amazon API Gateway, which is an AWS service for creating, publishing, maintaining, monitoring, and securing REST, HTTP, and WebSocket APIs at scale. API developers can create APIs that access AWS or other web services, as well as data stored in the AWS Cloud. As an API Gateway developer, you can create APIs for use in your own client applications. For more information, see What is Amazon API Gateway.
AWS Lambda is a compute service that enables you to run code without provisioning or managing servers. You can create Lambda functions in various programming languages. For more information about AWS Lambda, see What is AWS Lambda.
In this example, you create a Lambda function by using the Lambda JavaScript runtime API. This example invokes different AWS services to perform a specific use case. For example, assume that an organization sends a mobile text message to its employees that congratulates them at the one year anniversary date, as shown in this illustration.
The example should take about 20 minutes to complete.
This example shows you how to use JavaScript logic to create a solution that performs this use case. For example, you'll learn how to read a database to determine which employees have reached the one year anniversary date, how to process the data, and send out a text message all by using a Lambda function. Then you’ll learn how to use API Gateway to invoke this AWS Lambda function by using a Rest endpoint. For example, you can invoke the Lambda function by using this curl command:
curl -XGET "https://xxxxqjko1o3.execute-api.us-east-1.amazonaws.com/cronstage/employee"
This AWS tutorial uses an Amazon DynamoDB table named Employee that contains these fields.
id - the primary key for the table.
firstName - employee’s first name.
phone - employee’s phone number.
startDate - employee’s start date.
Important
Cost to complete: The AWS services included in this document are included in the AWS Free Tier. However, be sure to terminate all of the resources after you have completed this example to ensure that you are not charged.
To build the app:
Prerequisite tasks
To set up and run this example, you must first complete these tasks:
-
Set up the project environment to run these Node TypeScript examples, and install the required AWS SDK for JavaScript and third-party modules. Follow the instructions on GitHub
. -
Create a shared configurations file with your user credentials. For more information about providing a shared credentials file, see Shared config and credentials files in the AWS SDKs and Tools Reference Guide.
Create the AWS resources
This tutorial requires the following resources:
-
An Amazon DynamoDB table named
Employee
with a key namedId
and the fields shown in the previous illustration. Make sure you enter the correct data, including a valid mobile phone that you want to test this use case with. For more information, see Create a Table. -
An IAM role with attached permissions to execute Lambda functions.
-
An Amazon S3 bucket to host Lambda function.
You can create these resources manually, but we recommend provisioning these resources using the AWS CloudFormation as described in this tutorial.
Create the AWS resources using AWS CloudFormation
AWS CloudFormation enables you to create and provision AWS infrastructure deployments predictably and repeatedly. For more information about AWS CloudFormation, see the AWS CloudFormation User Guide.
To create the AWS CloudFormation stack using the AWS CLI:
Install and configure the AWS CLI following the instructions in the AWS CLI User Guide.
Create a file named
setup.yaml
in the root directory of your project folder, and copy the content here on GitHubinto it. Note
The AWS CloudFormation template was generated using the AWS CDK available here on GitHub
. For more information about the AWS CDK, see the AWS Cloud Development Kit (AWS CDK) Developer Guide. Run the following command from the command line, replacing
STACK_NAME
with a unique name for the stack.Important
The stack name must be unique within an AWS Region and AWS account. You can specify up to 128 characters, and numbers and hyphens are allowed.
aws cloudformation create-stack --stack-name STACK_NAME --template-body file://setup.yaml --capabilities CAPABILITY_IAM
For more information on the
create-stack
command parameters, see the AWS CLI Command Reference guide, and the AWS CloudFormation User Guide.-
Next, populate the table by following the procedure Populating the table.
Populating the table
To populate the table, first create a directory named libs
, and in it create
a file named dynamoClient.js
, and paste the content below into it.
const { DynamoDBClient } = require ( "@aws-sdk/client-dynamodb" ); // Set the AWS Region. const REGION = "REGION"; // e.g. "us-east-1" // Create an Amazon Lambda service client object. const dynamoClient = new DynamoDBClient({region:REGION}); module.exports = { dynamoClient };
This code is available
here on GitHub
Next, create a file named populate-table.js
in the root directory of your
project folder, and copy the content
here on GitHubphone
property with a valid mobile phone number in the E.164 format, and the value for the
startDate
with today's date.
Run the following command from the command line.
node populate-table.js
const { BatchWriteItemCommand } = require ( "aws-sdk/client-dynamodb" ); const {dynamoClient} = require ( "./libs/dynamoClient" ); // Set the parameters. export const params = { RequestItems: { Employees: [ { PutRequest: { Item: { id: { N: "1" }, firstName: { S: "Bob" }, phone: { N: "155555555555654" }, startDate: { S: "2019-12-20" }, }, }, }, { PutRequest: { Item: { id: { N: "2" }, firstName: { S: "Xing" }, phone: { N: "155555555555653" }, startDate: { S: "2019-12-17" }, }, }, }, { PutRequest: { Item: { id: { N: "55" }, firstName: { S: "Harriette" }, phone: { N: "155555555555652" }, startDate: { S: "2019-12-19" }, }, }, }, ], }, }; export const run = async () => { try { const data = await dbclient.send(new BatchWriteItemCommand(params)); console.log("Success", data); } catch (err) { console.log("Error", err); } }; run();
This code is available
here on GitHub
Creating the AWS Lambda function
Configuring the SDK
In the libs
directory, create files named snsClient.js
and lambdaClient.js
, and paste
the content below into these files, respectively.
const { SNSClient } = require ( "@aws-sdk/client-sns" ); // Set the AWS Region. const REGION = "REGION"; //e.g. "us-east-1" // Create an Amazon SNS service client object. const snsClient = new SNSClient({ region: REGION }); module.exports = { snsClient };
Replace REGION
with the AWS Region. This code is available
here on GitHub
const { LambdaClient } = require ( "@aws-sdk/client-lambda" ); // Set the AWS Region. const REGION = "REGION"; //e.g. "us-east-1" // Create an Amazon Lambda service client object. const lambdaClient = new LambdaClient({ region: REGION }); module.exports = { lambdaClient };
Replace REGION
with the AWS Region. This code is available
here on GitHub
First, import the required AWS SDK for JavaScript (v3) modules and commands. Then calculate today's date and assign it to a parameter.
Third, create the parameters for the ScanCommand
. Replace TABLE_NAME
with the name of the table you created in the
Create the AWS resources section of this example.
The following code snippet shows this step. (See Bundling the Lambda function for the full example.)
"use strict"; const { ScanCommand } = require("@aws-sdk/client-dynamodb"); const { PublishCommand } = require("@aws-sdk/client-sns"); const {snsClient} = require ( "./libs/snsClient" ); const {dynamoClient} = require ( "./libs/dynamoClient" ); // Get today's date. const today = new Date(); const dd = String(today.getDate()).padStart(2, "0"); const mm = String(today.getMonth() + 1).padStart(2, "0"); //January is 0! const yyyy = today.getFullYear(); const date = yyyy + "-" + mm + "-" + dd; // Set the parameters for the ScanCommand method. const params = { // Specify which items in the results are returned. FilterExpression: "startDate = :topic", // Define the expression attribute value, which are substitutes for the values you want to compare. ExpressionAttributeValues: { ":topic": { S: date }, }, // Set the projection expression, which are the attributes that you want. ProjectionExpression: "firstName, phone", TableName: "Employees", };
Scanning the DynamoDB table
First, create an async/await function called sendText
to publish a text message using the Amazon SNS PublishCommand
. Then, add a try
block
pattern that scans the DynamoDB table for employees with their work anniversary today, and then calls the sendText
function to send these employees a text message. If an error
occurs the catch
block is called.
The following code snippet shows this step. (See Bundling the Lambda function for the full example.)
// Helper function to send message using Amazon SNS. exports.handler = async () => { // Helper function to send message using Amazon SNS. async function sendText(textParams) { try { await snsClient.send(new PublishCommand(textParams)); console.log("Message sent"); } catch (err) { console.log("Error, message not sent ", err); } } try { // Scan the table to identify employees with work anniversary today. const data = await dynamoClient.send(new ScanCommand(params)); data.Items.forEach(function (element) { const textParams = { PhoneNumber: element.phone.N, Message: "Hi " + element.firstName.S + "; congratulations on your work anniversary!", }; // Send message using Amazon SNS. sendText(textParams); }); } catch (err) { console.log("Error, could not scan table ", err); } };
Bundling the Lambda function
This topic describes how to bundle the mylambdafunction.ts
and the required AWS SDK for JavaScript modules for this example into a
bundled file called index.js
.
If you haven't already, follow the Prerequisite tasks for this example to install webpack.
Note
For information about webpack, see Bundle applications with webpack.
Run the following in the command line to bundle the JavaScript for this example into a file called
<index.js>
:webpack mylambdafunction.ts --mode development --target node --devtool false --output-library-target umd -o index.js
Important
Notice the output is named
index.js
. This is because Lambda functions must have anindex.js
handler to work.Compress the bundled output file,
index.js
, into a ZIP file namedmylambdafunction.zip
.Upload
mylambdafunction.zip
to the Amazon S3 bucket you created in the Create the AWS resources topic of this tutorial.
Deploy the Lambda function
In the root of your project, create a lambda-function-setup.ts
file, and paste the content below into it.
Replace BUCKET_NAME
with the name of the Amazon S3 bucket you uploaded the ZIP version of your Lambda function to. Replace
ZIP_FILE_NAME
with the name of name the ZIP version of your Lambda function. Replace ROLE
with the Amazon Resource Number (ARN) of the IAM role
you created in the Create the AWS resources topic of this tutorial.
Replace LAMBDA_FUNCTION_NAME
with a name for the Lambda function.
// Load the required Lambda client and commands. const { CreateFunctionCommand } = require ( "@aws-sdk/client-lambda" ); const { lambdaClient} = require ( "./libs/lambdaClient.js ); // Set the parameters. const params = { Code: { S3Bucket: "BUCKET_NAME", // BUCKET_NAME S3Key: "ZIP_FILE_NAME", // ZIP_FILE_NAME }, FunctionName: "LAMBDA_FUNCTION_NAME", Handler: "index.handler", Role: "IAM_ROLE_ARN", // IAM_ROLE_ARN; e.g., arn:aws:iam::650138640062:role/v3-lambda-tutorial-lambda-role Runtime: "nodejs12.x", Description: "Scans a DynamoDB table of employee details and using Amazon Simple Notification Services (Amazon SNS) to " + "send employees an email on each anniversary of their start-date.", }; const run = async () => { try { const data = await lambdaClient.send(new CreateFunctionCommand(params)); console.log("Success", data); // successful response } catch (err) { console.log("Error", err); // an error occurred } }; run();
Enter the following at the command line to deploy the Lambda function.
node lambda-function-setup.ts
This code example is available here on GitHub
Configure API Gateway to invoke the Lambda function
To build the app:
Create the rest API
You can use the API Gateway console to create a rest endpoint for the Lambda function. Once done, you are able to invoke the Lambda function using a restful call.
Sign in to the Amazon API Gateway console
. Under Rest API, choose Build.
Select New API.
Specify Employee as the API name and provide a description.
Choose Create API.
Choose Resources under the Employee section.
In the name field, specify employees.
Choose Create Resources.
From the Actions dropdown, choose Create Resources.
Choose /employees, select Create Method from the Actions, then select GET from the drop-down menu below /employees. Choose the checkmark icon.
Choose Lambda function and enter mylambdafunction as the Lambda function name. Choose Save .
Test the API Gateway method
At this point in the tutorial, you can test the API Gateway method that invokes the mylambdafunction Lambda function. To test the method, choose Test, as shown in the following illustration.
Once the Lambda function is invoked, you can view the log file to see a successful message.
Deploy the API Gateway method
After the test is successful, you can deploy the method from the Amazon API Gateway console
Choose Get.
From the Actions dropdown, select Deploy API.
Fill in the Deploy API form and choose Deploy.
Choose Save Changes.
Choose Get again and notice that the URL changes. This is the invocation URL that you can use to invoke the Lambda function.
Delete the resources
Congratulations! You have invoked a Lambda function through Amazon API Gateway using the AWS SDK for JavaScript. As stated at the beginning of this tutorial, be sure to terminate all of the resources you create while going through this tutorial to ensure that you’re not charged. You can do this by deleting the AWS CloudFormation stack you created in the Create the AWS resources topic of this tutorial, as follows:
Open the Stacks page, and select the stack.
Choose Delete.