Use Lambda Function URL To Write a Serverless App Backed by DynamoDB
This is a Go Lambda function that's packaged and deployed using AWS SAM.
Join the DZone community and get the full member experience.
Join For FreeLambda Function URL is a relatively new feature (at the time of writing this blog) that provides a dedicated HTTP(S) endpoint for your Lambda function. It is really useful when all you need is a single endpoint for your function (e.g. to serve as a webhook) and doesn't want to set up and configure an API Gateway. Looks like I can't seem to get enough of it! I have written a couple of blog posts on this topic that includes a practical example of using it to build a serverless backend and then deploying that solution using AWS CDK.
This is yet another blog post (it's a short one!) that demonstrates how you can use Lambda Function URL to write a simple application backed by DynamoDB. You will be able to invoke an API endpoint exposed by the Lambda Function URL, which in turn will execute operations (GetItem
, PutItem
, Scan
) on DynamoDB. The function is written in Go using the DynamoDB package in AWS Go SDK and AWS Serverless Application Model (SAM) is used to quickly build and deploy the solution.
The code is available on GitHub for your reference
Let's get right to it! Before you move on, make sure you have the following ready:
Pre-requisites
- Create an AWS account if you do not already have one and log in. Sufficient permissions are needed by the IAM user that you use to make necessary AWS service calls and manage the AWS resources.
- AWS CLI installed and configured
- Go (
1.16
or above) installed - AWS Serverless Application Model (AWS SAM) installed
- Git Installed
Deployment
Start by cloning the Github repo and change to the right directory:
git clone https://github.com/abhirockzz/lambda-functionurl-dynamodb-sam-go
cd lambda-functionurl-dynamodb-sam-go
Use AWS SAM to build the app:
sam build
Now you're ready to deploy the application:
sam deploy --guided
When prompted, enter the required information such as stack name, etc. See the example below:
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Not found
Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]:
AWS Region [us-east-1]:
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]: y
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]: y
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [y/N]: n
DemoFunction Function Url may not have authorization defined, Is this okay? [y/N]: y
Save arguments to configuration file [Y/n]:
SAM configuration file [samconfig.toml]:
SAM configuration environment [default]:
Once you have run
sam deploy --guided
mode once and saved arguments to a configuration file (samconfig.toml), you can usesam deploy
in future to use these defaults.
If successful, you should now have the following ready:
- Lambda Function with an HTTP(S) URL
- A DynamoDB table (called
users
) - IAM Role with the minimum required permissions for Lambda as well as DynamoDB (
PutItem
,GetItem
, andScan
)
Note the output from the SAM deployment process. This contains the HTTP URL endpoint for your function required for testing
Test the Application
Testing the integration involves sending HTTP requests to the Lambda Function URL. This example used the curl CLI, but you can also use other options.
Export the Lambda Function URL endpoint as an environment variable. E.g. export LAMBDA_FUNCTION_URL_ENDPOINT=https://qfmpu2n74ik7m2m3ipv3m6yw5a0qiwmp.lambda-url.us-east-1.on.aws/
export LAMBDA_FUNCTION_URL_ENDPOINT=<SAM deployment output>
Invoke the endpoint to create new entries in the DynamoDB table:
curl -i -X POST -H "Content-Type: application/json" -d '{"email":"user1@foo.com", "username":"user-1"}' $LAMBDA_FUNCTION_URL_ENDPOINT
curl -i -X POST -H "Content-Type: application/json" -d '{"email":"user2@foo.com", "username":"user-2"}' $LAMBDA_FUNCTION_URL_ENDPOINT
You should get an HTTP 201 Created
response in both cases. This indicates that the items have been added to the users
table in DynamoDB.
Let's retrieve the info for the record we just created (we do that by adding a query
parameter (email) to the URL):
curl -i $LAMBDA_FUNCTION_URL_ENDPOINT?email=user2@foo.com
To retrieve all the items that you just added:
curl -i $LAMBDA_FUNCTION_URL_ENDPOINT
Try to search for an item that you haven't yet added:
curl -i $LAMBDA_FUNCTION_URL_ENDPOINT?email=notthere@foo.com
You will get back a HTTP 404 Not Found
response in this case.
Finally, try to insert a duplicate record:
curl -i -X POST -d '{"email":"user2@foo.com", "username":"user-2"}' $LAMBDA_FUNCTION_URL_ENDPOINT
The Lambda function returns an HTTP 409 Conflict
in this case since a Condition Expression (attribute_not_exists(email)
) prevents an existing item (with the same email
) from being overwritten by the PutItem
call.
That's it! You have tried all the operations exposed by the Lambda function.
Cleanup
Once you're done, please delete the stack:
sam delete --stack-name STACK_NAME
Confirm the stack has been deleted
aws cloudformation list-stacks --query "StackSummaries[?contains(StackName,'STACK_NAME')].StackStatus"
Wrap Up!
This was a short (but hopefully useful) tutorial! You can use this to quickly bootstrap a Serverless app with a DynamoDB backend with functionality exposed by a Lambda Function URL.
Happy coding!
Opinions expressed by DZone contributors are their own.
Comments