Blog Posts: Latest Trends and Insights in Technologies | Clarion Technologies

A Guide to Serverless App Development with AWS Lambda

Written by Vinit Sharma - Technical Architect | Apr 2, 2024 10:17:27 AM

If you're tired of server-based management and want a step-by-step guide on building a serverless app with AWS lambda, you've come to the right place.

AWS Lambda streamlines digital consumer experiences and eliminates the technical complexities associated with managing servers and behind-the-scenes elements. The best part is you only pay for what you use, and it changes the way you run code forever.

Here is everything you need to know about it to start creating AWS Lambda projects, build serverless apps, and more.

What Is AWS Lambda Service?

AWS Lambda is an integral component of Amazon Web Services (AWS). It offers an event-driven and serverless computing platform that enables programmers to execute code without provisioning or managing servers.

AWS Lambda Service officially provides custom runtime support and works with programming languages like Java, Go, Ruby, Node.JS, and Python. Developers invoke lambda function URLs using the AWS Lambda APIs.

Using the AWS Lambda Layers service, developers can manage and share standard components across AWS Lambda functions. 

 

Why Do We Use AWS Lambda?

We use AWS Lambda for many reasons:

  • AWS Lambda handles all administrative tasks and lets developers focus on writing code that ensures a smooth customer experience.
  • It is a cost-effective technology for running various cloud operations. AWS Lamba follows a pay-per-request pricing model and can scale up or down its services on demand.
  • It lets us call services such as Amazon S3 and DynamoDB and allows us to access stateful data.
  • It integrates seamlessly with the entire AWS ecosystem and works with chatbots, data analytics tools, website hosting and app development services, database management, streaming, etc.

Languages AWS Lambda Supports

AWS Lambda natively supports Java, Go, PowerShell, Node.JS, Ruby, Python, and C#.

There are currently over 200 AWS services, and Lambdas can automatically run code in response to event triggers from multiple sources, both within and outside its ecosystem.

Build a Serverless App with AWS Lambda

 In this guide, you will build a serverless application using AWS that allows users to send unicorn ride requests from the Wild Rydes fleet. Let’s get started.

Host a Static Website

  1. The AWS Amplify Console will host all your static website content. It will store HTML, CSS, and JavaScript files, and end users will access the website using the public URL. A custom domain will be needed to host the website. 
  1. Select a region from the dropdown menu in the upper right-hand corner of the AWS Management Console.
  1. Create a Git repository to manage the source code for the module. You can use CodeCommit to store the application code and install AWS CLI via the terminal window.
  1. Open the AWS CodeCommit Console and click on Create Repository.
  1. Type wildrydes-site for the repo name and hit Create
  1. Use the IAM console to set up Git credentials and the IAM user profile.
  1. Creating access keys in the IAM > Security Credentials tab would be best. Download the access keys after creating them and save them in a secure location.
  1. Generate HTTPS Gits credentials for AWS CodeCommit.
  1. Type AWS configure in the terminal window to install AWS CLI.
  1. Enter AWS Access Key ID and Secret Access Key
  1. For the default region, choose the region where you created your CodeCommit repository and set it to that. 
  1. Keep the Default output format empty and hit enter. 

You will get the following output in your terminal window:

% aws configure

AWS Access Key ID [****************]: #####################

AWS Secret Access Key [****************]: ###################

Default region name [us-east-1]: us-east-1

Default output format [None]:

  1. Set up git config credential helper via the terminal window:

git config --global credential.helper '!aws code commit credential-helper $@'

git config --global credential.UseHttpPath true

  1. Go back to the AWS CodeCommit Console and choose the wildrydes-site repository.
  1. Copy the HTTPS URL by selecting Clone HTTPS from the Clone URL dropdown menu.
  1. Run git clone from the terminal window and paste the repository's HTTPS URL.

You will get the following output:

$ git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/wildrydes-site

Cloning into ‘wildrydes-site’...

$ git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/wildrydes-site

Cloning into ‘wildrydes-site’...

Username for 'https://git-codecommit.us-east-1.amazonaws.com/v1/repos/wildrydes-site': Enter the HTTPS Git credentials for the AWS CodeCommit username you generated

Password for ‘https://username@git-codecommit.us-east-1.amazonaws.com/v1/repos/wildrydes-site': Enter the HTTPS Git credentials for the AWS CodeCommit password you generated

warning: You appear to have cloned an empty repository.

 

  1. Once you create a Git repository, the next step is to populate it with content. You can copy the site content from an existing, publicly accessible S3 bucket and add it to your chosen repository.

You can use the following command for this:

cd wildrydes-site

aws s3 cp s3://wildrydes-us-east-1/WebApplication/1_StaticWebHosting/website ./ --recursive

Here is what you’ll see in your terminal window now:

$ git add .

$ git commit -m "new files"

$ git push

Counting objects: 95, done.

Compressing objects: 100% (94/94), done.

Writing objects: 100% (95/95), 9.44 MiB | 14.87 MiB/s, done.

Total 95 (delta 2), reused 0 (delta 0)

To https://git-codecommit.us-east-1.amazonaws.com/v1/repos/wildrydes-site

* [new branch] master -> master

Turn On Web Hosting with the AWS Amplify Console

Once you have created and populated the repo, you can enable web hosting with the AWS Amplify Console. Launch the AWS Amplify Console and choose Get Started.

Click on AWS CodeCommit and hit continue on the Get Started with Amplify Hosting page.

Select wildrydes-site and give AWS Amplify authorization access to your GitHub account.

Under the Branch dropdown, select Master and click Next.

In the Build settings page, choose Allow AWS Amplify to automatically deploy all files hosted in your project root directory and hit Next.

Select Save and Deploy on the Review page.

Pick a site thumbnail for your wildrydes-site page and get ready for it to go live. 

Modify Your Site

To modify your static website, navigate to the index.html file on your local machine and open it in a text editor of your choice.

You can modify the title and save the file directly

Add, commit, and push changes to your GitHub repo, and the AWS Amplify Console will reflect updates automatically

After Amplify completes re-deployment, you can re-open the wildrydes-site page and observe the changes.

Now that you have created your static website, you can add feature branch deployments, set up custom domains, and enable password protection!

Manage Users and Build a Serverless Backend

You must create an Amazon Incognito user pool and integrate an app to manage users. You will have to update the website config file and validate your implementation. Refer to this guide here.

To build a serverless backend, follow these steps:

Create an Amazon DynamoDB Table

Set an IAM role for your Lambda function

Handle new requests by creating a Lambda function. Use the AWS Lambda console for this.

Deploy Application using AWS Lambda.

To deploy serverless application, implement a Lambda function that invokes every time a user requests a unicorn using the Amazon API Gateway.

You can keep the Default Author from the Scratch card selected when creating the new function. Set Node.js 16.x or previous versions for the Runtime (newer ones won’t work) and select WildRydes Lambda from the existing role

In the CodeSource section, you can copy-paste the following code in index.js and replace it with the contents of the requestUnicorn.js file:

const randomBytes = require('crypto').randomBytes;

const AWS = require('aws-sdk');

const ddb = new AWS.DynamoDB.DocumentClient();

const fleet = [

   {

       Name: 'Angel',

       Color: 'White',

       Gender: 'Female',

   },

   {

       Name: 'Gil',

       Color: 'White',

       Gender: 'Male',

   },

   {

       Name: 'Rocinante',

       Color: 'Yellow',

       Gender: 'Female',

   },

];

exports.handler = (event, context, callback) => {

   if (!event.requestContext.authorizer) {

     errorResponse('Authorization not configured', context.awsRequestId, callback);

     return;

   }

   const rideId = toUrlString(randomBytes(16));

   console.log('Received event (', rideId, '): ', event);

   // Because we're using a Cognito User Pools authorizer, all of the claims

   // included in the authentication token are provided in the request context.

   // This includes the username as well as other attributes.

   const username = event.requestContext.authorizer.claims['cognito:username'];

   // The body field of the event in a proxy integration is a raw string.

   // In order to extract meaningful values, we need to first parse this string

   // into an object. A more robust implementation might inspect the Content-Type

   // header first and use a different parsing strategy based on that value.

   const requestBody = JSON.parse(event.body);

   const pickupLocation = requestBody.PickupLocation;

   const unicorn = findUnicorn(pickupLocation);

   recordRide(rideId, username, unicorn).then(() => {

       // You can use the callback function to provide a return value from your Node.js

       // Lambda functions. The first parameter is used for failed invocations. The

       // second parameter specifies the result data of the invocation.

       // Because an API Gateway proxy integration calls this Lambda function

       //The result object must use the following structure.

       callback(null, {

           statusCode: 201,

           body: JSON.stringify({

               RideId: rideId,

               Unicorn: unicorn,

               Eta: '30 seconds',

               Rider: username,

           }),

           headers: {

               'Access-Control-Allow-Origin': '*',

           },

       });

   }).catch((err) => {

       console.error(err);

 

       // If there is an error during processing, catch it and return

        // from the Lambda function successfully. Specify a 500 HTTP status

       // code and provide an error message in the body. This will provide a

       // more meaningful error response to the end client.

       errorResponse(err.message, context.awsRequestId, callback)

   });

};

 

// This is where you would implement logic to find the optimal unicorn for

// this ride (possibly invoking another Lambda function as a microservice.)

// For simplicity, we'll pick a unicorn at random.

function findUnicorn(pickupLocation) {

   console.log('Finding unicorn for ', pickupLocation.Latitude, ', ', pickupLocation.Longitude);

   return fleet[Math.floor(Math.random() * fleet.length)];

}

 

function recordRide(rideId, username, unicorn) {

   return ddb.put({

       TableName: 'Rides',

       Item: {

           RideId: rideId,

           User: username,

           Unicorn: unicorn,

           RequestTime: new Date().toISOString(),

       },

   }).promise();

}

 

function toUrlString(buffer) {

   return buffer.toString('base64')

       .replace(/\+/g, '-')

       .replace(/\//g, '_')

       .replace(/=/g, '');

}

 

function errorResponse(errorMessage, awsRequestId, callback) {

callback(null, {

   statusCode: 500,

   body: JSON.stringify({

     Error: errorMessage,

     Reference: awsRequestId,

   }),

   headers: {

     'Access-Control-Allow-Origin': '*',

   },

});

}

 

 

Select Deploy.

 

Use the AWS Lambda Console to test your function. Choose Test and select Configure test event.

Enter TestRequestEvent and paste the following code in the Event JSON section:

 

{

   "path": "/ride",

   "httpMethod": "POST",

   "headers": {

       "Accept": "*/*",

       "Authorization": "eyJraWQiOiJLTzRVMWZs",

       "content-type": "application/json; charset=UTF-8"

   },

   "queryStringParameters": null,

   "pathParameters": null,

   "requestContext": {

       "authorizer": {

           "claims": {

               "cognito:username": "the_username"

            }

       }

   },

   "body": "{\"PickupLocation\":{\"Latitude\":47.6174755835663,\"Longitude\":-122.28837066650185}}"

}

 

 

An “Executing function:succeeded” message should be displayed when the test is successful. You should get the following output:

 

{

   "statusCode": 201,

   "body": "{\"RideId\":\"SvLnijIAtg6inAFUBRT+Fg==\",\"Unicorn\":{\"Name\":\"Rocinante\",\"Color\":\"Yellow\",\"Gender\":\"Female\"},\"Eta\":\"30 seconds\"}",

   "headers": {

       "Access-Control-Allow-Origin": "*"

   }

}

Test the Serverless Application

After deployment, you can write custom unit tests and different test cases to test your AWS serverless application. Use cURL or PostMan to send requests to API endpoints and verify responses. Perform load testing on your app and evaluate it to identify performance issues and bottlenecks.

You can set up monitoring and logging using the AWS CloudWatch: Configure CloudWatch and check the usage metrics of your Lambda functions for further insights.

Activate auto-scaling and remember to iterate your serverless Application by collecting user feedback.

It will help you manage increased traffic and ensure robust security, performance, and scalability.

Serverless technologies: Integrating AWS Lambda and Azure Functions

You can use Azure Functions Core tools to create and execute a local functions project. Then, use Visual Studio Code to build and debug the project. You can deploy the full migration function to Azure directly after that. This is how you host serverless functions in Azure from AWS Lambda.

Conclusion

Remember that building a serverless app with AWS Lambda is an iterative process. You can encrypt sensitive data using services like AWS Key Management Service and AWS Certificate Manager. Use the Amazon Simple Queue Service (SQS) and Amazon Simple Notification Service (SNS) to handle errors and retries.

If you need further assistance, connect with us; we will gladly help.

FAQs

  1. Is AWS S3 serverless?

Yes, AWS S3 is serverless. It is a fully elastic file system for builders that offers high scalability, shared storage, and cost-optimization benefits.

 

  1. What are the top AWS serverless services?

The top AWS serverless services are AWS Lambda, AWS Fargate, Amazon Aurora, and AWS DynamoDB.

 

  1. How do I deploy an AWS API?

You must sign in to the API Gateway console to deploy an AWS API. Navigate to the Resources pane and choose Deploy API. You can also create and set a new Stage name there.

 

  1. What is the AWS toolkit?

The AWS toolkit is an open-source plugin for the Visual Studio Code that enables developers with easy debugging and deployment capabilities for Amazon Web Services applications.