DEV Community

Abhishek Gupta for AWS

Posted on • Originally published at dzone.com

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

Lambda Function URL is a relatively new feature (at the time of writing this blog) that provides 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 don't want to setup 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 include 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

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
Enter fullscreen mode Exit fullscreen mode

Use AWS SAM to build the app:

sam build
Enter fullscreen mode Exit fullscreen mode

Now you're ready to deploy the application:

sam deploy --guided
Enter fullscreen mode Exit fullscreen mode

When prompted, enter the required information such as stack name etc. See 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]: 
Enter fullscreen mode Exit fullscreen mode

Once you have run sam deploy --guided mode once and saved arguments to a configuration file (samconfig.toml), you can use sam deploy in future to use these defaults.

If successful, you should now have the following ready:

  • Lambda Function with a HTTP(S) URL
  • A DynamoDB table (called users)
  • IAM Role with minimum required permissions for Lambda as well as DynamoDB (PutItem, GetItem, and Scan)

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 an 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.

export LAMBDA_FUNCTION_URL_ENDPOINT=<SAM deployment output>
e.g. export LAMBDA_FUNCTION_URL_ENDPOINT=https://qfmpu2n74ik7m2m3ipv3m6yw5a0qiwmp.lambda-url.us-east-1.on.aws/
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

You should get an HTTP 201 Created response in both the 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
Enter fullscreen mode Exit fullscreen mode

To retrieve all the items that you just added:

curl -i $LAMBDA_FUNCTION_URL_ENDPOINT
Enter fullscreen mode Exit fullscreen mode

Try to search for an item that you haven't yet added:

curl -i $LAMBDA_FUNCTION_URL_ENDPOINT?email=notthere@foo.com
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Confirm the stack has been deleted

aws cloudformation list-stacks --query "StackSummaries[?contains(StackName,'STACK_NAME')].StackStatus"
Enter fullscreen mode Exit fullscreen mode

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!

Discussion (0)