Deploying a serverless web application on S3, API gateway, lambda, DynamoDB
Published: 2024-07-08 21:11:26

**_Introduction:_**
Deploying a serverless web application using AWS services such as S3, API Gateway, Lambda, and DynamoDB is a streamlined and cost-effective approach for building scalable applications without managing traditional server infrastructure. This setup leverages cloud-native services that handle scaling, security, and availability automatically, allowing developers to focus on application logic rather than infrastructure maintenance.

**_Serverless Architecture_**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sub6md746f7ul6ijol76.jpg)
**_Components of the Serverless Architecture_**

Pre requisites:

- AWS account
- IAM role to lambda: Access dynamoDB

1. _Creating AWS DynamoDB Table:_

Fully managed NoSQL database service to store and retrieve data at scale.

- Create a DynamoDB table by providing a name. (e.g., studentData).

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3xhe7t0bea1s7zw3jrq2.jpg)

- Define Partition key which is used to retrieve or store the data(e.g., studentid)

- sort key is define as secondary key.

- create table
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qtiltmsu01yehlc78lhi.jpg)

2._Creating a Lambda function:_

- Write Lambda functions to handle CRUD operations (GET, PUT, POST, DELETE) on DynamoDB data
_create a function_

- define the function name(getstudent)
- change the runtime to python 3.12
- define role -use existing role.
 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zrbb0mxnm4e6yi5bwx15.jpg)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/axro2vzzvnydye7to19z.jpg)

_write code_
Lambda function (Python) for handling GET requests.

```
import json
import boto3

def lambda_handler(event, context):
    # Initialize a DynamoDB resource object for the specified region
    dynamodb = boto3.resource('dynamodb', region_name='us-east-2')

    # Select the DynamoDB table named 'studentData'
    table = dynamodb.Table('studentData')

    # Scan the table to retrieve all items
    response = table.scan()
    data = response['Items']

    # If there are more items to scan, continue scanning until all items are retrieved
    while 'LastEvaluatedKey' in response:
        response = table.scan(ExclusiveStartKey=response['LastEvaluatedKey'])
        data.extend(response['Items'])

    # Return the retrieved data
    return data
```
- Deploy the above mentioned code

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ttu7gi0fst10g4815lpx.jpg)

- Test the code to invoke the lambda function i.e., lambda function will go to dynamo DB table and retrieve the data.
 

_Lambda function (Python) for POSTING DATA_
- Create a function(E.g., insertStudentData)
- select python 3.12 provide the roles.
- create a function.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9d1oreizav99vuk1z1k8.jpg)
```
# Create a DynamoDB object using the AWS SDK
dynamodb = boto3.resource('dynamodb')
# Use the DynamoDB object to select our table
table = dynamodb.Table('studentData')

# Define the handler function that the Lambda service will use as an entry point
def lambda_handler(event, context):
    # Extract values from the event object we got from the Lambda service and store in variables
    student_id = event['studentid']
    name = event['name']
    student_class = event['class']
    age = event['age']
    
    # Write student data to the DynamoDB table and save the response in a variable
    response = table.put_item(
        Item={
            'studentid': student_id,
            'name': name,
            'class': student_class,
            'age': age
        }
    )
    
    # Return a properly formatted JSON object
    return {
        'statusCode': 200,
        'body': json.dumps('Student data saved successfully!')
    }
```
- Deploy the code
- test the code

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wb4gm4hjzdjxnh9q3qd4.jpg) 

 - student data will be stores in dynamo DB table 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sw89rq9z9hms4yo4kzub.jpg)


**_Create API gateway_**

-Create RESTful APIs to trigger Lambda functions to store or retrieve the datas in Dynamo DB table.

- Create API endpoints (GET, POST, PUT, DELETE) in API Gateway that trigger your Lambda functions.

- provide the API name student
-click API endpoint type - use (edge optimized) as it allow all the user. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cwox5skto0gjkdmto9ro.jpg)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cx7ob7trnp1v7les82o6.jpg)

_Create methods - get and post methods_

**GET method**

- click on create method
- method type - GET
- integration type choose - lambda function
- select lambda function - getStudent
- method GET will be created.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7m0ko483ktxwrbipsayi.jpg)

**POST method**
- method type - POST
- select lambda function - insertStudentData
- click create method

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3hp1gom7d3z6qe37n6hv.jpg)
_Deploy API_
Deploy your API to a stage (e.g., prod) and note down the Invoke URL provided by API Gateway.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5fkg7poytkg4r22ogp8d.jpg)

Paste the URL in API ENDPOINT code.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/arw6pfaontvttanjz5m9.jpg)

```
/ Add your API endpoint here
var API_ENDPOINT = "API_ENDPOINT_PASTE_HERE";

// AJAX POST request to save student data
document.getElementById("savestudent").onclick = function(){
    var inputData = {
        "studentid": $('#studentid').val(),
        "name": $('#name').val(),
        "class": $('#class').val(),
        "age": $('#age').val()
    };
    $.ajax({
        url: API_ENDPOINT,
        type: 'POST',
        data:  JSON.stringify(inputData),
        contentType: 'application/json; charset=utf-8',
        success: function (response) {
            document.getElementById("studentSaved").innerHTML = "Student Data Saved!";
        },
        error: function () {
            alert("Error saving student data.");
        }
    });
}

// AJAX GET request to retrieve all students
document.getElementById("getstudents").onclick = function(){  
    $.ajax({
        url: API_ENDPOINT,
        type: 'GET',
        contentType: 'application/json; charset=utf-8',
        success: function (response) {
            $('#studentTable tr').slice(1).remove();
            jQuery.each(response, function(i, data) {          
                $("#studentTable").append("<tr> \
                    <td>" + data['studentid'] + "</td> \
                    <td>" + data['name'] + "</td> \
                    <td>" + data['class'] + "</td> \
                    <td>" + data['age'] + "</td> \
                    </tr>");
            });
        },
        error: function () {
            alert("Error retrieving student data.");
        }
    });
}
```
If click on get-student data it will invoke the URL and lambda function will be triggered and it will retrieve data from dynamo DB table.

- click resources 
- enable CORS
-Select GET and POST and  click save

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vl53b371s06vl2etlk54.jpg)

**_Setting Up AWS S3_**

Create an S3 Bucket:

Go to the AWS Management Console and navigate to S3.
Click on "Create bucket" and follow the wizard to create a bucket (e.g., your-bucket-name).


_Upload Static Web Content:_

Upload your web application files (index.html,script.js) to the S3 bucket.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gwns7iy9jtguxb15l72u.jpg)

Select the uploaded files and make them public by setting the permissions to allow public read access.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/phvzlxm2y4znly813sha.jpg)

_Enable Static Website Hosting:_

In the bucket properties, navigate to "Static website hosting".
Select "Use this bucket to host a website" and enter index.html as the Index document.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1okryesdjj4ctsf4ab3p.jpg)

Our application is deployed in dynamo DB table!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wltzg1rf3pge89zpf9c.jpg)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3viku6ynoi10yaqwq9ho.jpg)

**_Conclusion_**
Deploying a serverless web application using S3, API Gateway, Lambda, and DynamoDB offers scalability, cost-efficiency, and ease of maintenance. By leveraging these AWS services, developers can focus more on building application logic and less on managing infrastructure. This architecture is ideal for modern web applications that require flexibility, scalability, and seamless integration with backend services like DynamoDB