Over 10 years we help companies reach their financial and branding goals. Engitech is a values-driven technology agency dedicated.

Gallery

Contacts

Bhubaneswar, India

info@krescitus.com

+1 -800-456-478-23

Blogs

 In today’s fast-paced development environment, serverless architecture has gained immense popularity due to its flexibility, cost-effectiveness, and ability to scale automatically. With AWS leading the charge in serverless technologies, building a scalable and maintainable application has never been easier. In this blog, we will walk through how to build a serverless application using API Gateway, AWS Lambda (Python), and DynamoDB on AWS, followed by best practices to make your application robust and secure.

What is a Serverless Application?

         Serverless computing refers to a cloud-computing execution model where the cloud provider dynamically manages the infrastructure. Developers simply write the code for the application’s functionality, and the cloud provider (e.g., AWS) takes care of scaling, patching, and managing servers.

Key Benefits of Serverless Applications:

  • No server management: You don’t need to provision, maintain, or scale servers.
  • Scalability: Applications automatically scale with the number of requests.
  • Cost-effective: You only pay for what you use (based on request/compute time).
  • Automatic scaling: AWS automatically scales your application based on traffic.

ARCHITECTURE:

  API Gateway:

  • Acts as the front-end for the API.
  • Routes HTTP requests (e.g., POST, GET, PUT, DELETE) to different AWS Lambda functions based on the defined paths and methods.
  • Handles API versions and stages, enabling multiple environments (e.g., development, production).

AWS Lambda:

  • Each HTTP request from API Gateway triggers a corresponding Lambda function.
  • The Lambda functions perform operations such as:
    • POST: Create a new record in DynamoDB.
    • GET: Retrieve a record from DynamoDB.
    • PUT: Update an existing record in DynamoDB.
    • DELETE: Remove a record from DynamoDB.
  • The Lambda functions are stateless, meaning they execute on demand, scale automatically, and are charged based on execution time.

DynamoDB:

  • A fully managed NoSQL database that stores user information.
  • Each Lambda function interacts with DynamoDB to either create, read, update, or delete data.
  • The table is configured with a primary key (userId) for uniquely identifying records.

1. API Gateway – The Entry Point

What is API Gateway?

AWS API Gateway is a fully managed service that allows developers to create, publish, maintain, monitor, and secure RESTful APIs. It’s the front-end entry point to your serverless application, where incoming HTTP requests are routed to specific AWS Lambda functions based on the HTTP method (GET, POST, etc.) and the endpoint.

Key Features:

  • Scalable and Reliable: Handles thousands of concurrent requests without managing infrastructure.
  • Authorisation & Throttling: Built-in support for securing APIs and managing traffic.
  • Integrated with AWS Lambda: Easily connect API Gateway to your backend Lambda functions.

To know more about API Gateway go through the official documentation: API Gateway Docs

2. AWS Lambda – The Compute Power

What is AWS Lambda?

AWS Lambda is a serverless compute service that lets you run code without provisioning or managing servers. You write your code, upload it to Lambda, and AWS handles the rest, including scaling and fault tolerance. In our application, Lambda is the business logic layer that interacts with DynamoDB to either store or retrieve data.

Key Features:

  • Pay-per-execution: You only pay for the time your code is actually running.
  • Automatic Scaling: AWS Lambda scales automatically depending on the incoming request volume.
  • Multiple Language Support: You can write Lambda functions in Python, JavaScript (Node.js), Java, Go, and more.

To know more about Lambda, go through the official documentation: AWS Lambda Docs

3. Amazon DynamoDB – The NoSQL Database

What is DynamoDB?

Amazon DynamoDB is a fully managed NoSQL database service that provides fast and predictable performance with seamless scalability. It’s used in serverless applications to store and retrieve structured data. DynamoDB automatically handles data replication, security, and performance optimisation.

Key Features:

  • Fast & Scalable: Handles large volumes of requests with millisecond latency.
  • Schema-less: No rigid schema structure, making it easy to store various types of data.
  • Global Tables: Offers multi-region, fully replicated databases for global applications.

To know more about DynamoDB go through the official documentation:  DynamoDB Docs

Architecture Flow: How the Application Works

Let’s walk through the flow of the serverless application from the moment a user interacts with the Angular frontend to the point where data is stored or retrieved from DynamoDB.

Step-by-Step Flow

Step 1: User Sends a Request to API Gateway

  • Flow: A user interacts with the Angular app (e.g., adding or viewing an item). The Angular frontend sends an HTTP request (GET, POST, etc.) to a URL managed by API Gateway.
  • Role of API Gateway:
  • API Gateway receives this request and looks at the method (GET, POST, PUT, etc.) and the resource (e.g., /items or /products).
  • API Gateway then forwards this request to the appropriate Lambda function for processing.
  • Example Use Case: If the user wants to retrieve an item, the API Gateway routes the request to the corresponding Lambda function handling the “GET” request.

Step 2: Lambda Processes the Request

  • Flow: The Lambda function gets triggered by the request coming through API Gateway. It reads the incoming data (for POST/PUT) or parameters (for GET).
  • Role of Lambda:
  • Lambda processes the request by executing your code. In our case, this code is written in Python and might involve interacting with DynamoDB.
  • Depending on the HTTP method, Lambda might fetch data from DynamoDB (for a GET request) or insert/update data in DynamoDB (for a POST/PUT request).
  • Example Use Case: If the user is adding a new item, Lambda reads the request payload, processes the data, and stores it in DynamoDB.

Step 3: Interacting with DynamoDB

  • Flow: AWS Lambda interacts with Amazon DynamoDB to either fetch or insert data.
  • Role of DynamoDB:
  • DynamoDB stores your application data. You can think of it as a highly scalable and fast NoSQL database.
  • Lambda uses the AWS SDK (in Python, it’s boto3) to call DynamoDB APIs to insert (via put_item) or retrieve (via get_item) data.
  • Example Use Case: In a POST request, Lambda inserts a new item into DynamoDB using the put_item method. For GET requests, it fetches data based on a key (e.g., itemId).

Step 4: API Gateway Sends the Response Back to the User

  • Flow: After Lambda completes processing the request, it returns a response to API Gateway, which then sends it back to the Angular app.
  • Role of API Gateway:
  • API Gateway receives the output from the Lambda function (could be a success message, retrieved data, or an error).
  • It formats this response (if necessary) and sends it back to the frontend Angular application.
  • Example Use Case: If a GET request was processed, the API Gateway sends back the retrieved item data from DynamoDB to the Angular frontend.
  • Documentation: API Gateway Response Integration

WORKFLOW:

User makes an HTTP request:

  • The user (or client) makes an HTTP request (e.g., POST, GET, PUT, DELETE) to the API.
  • The request is routed through API Gateway to the appropriate Lambda function.

API Gateway triggers AWS Lambda:

  • API Gateway triggers the corresponding AWS Lambda function based on the HTTP method and resource (endpoint).
  • It passes along the request data (body, path parameters) to the Lambda function.

Lambda function executes business logic:

  • The Lambda function receives the request and processes the data.
  • Depending on the request, it interacts with DynamoDB to perform CRUD operations (create, read, update, delete).

DynamoDB interaction:

  • The Lambda function uses the AWS SDK (boto3 in Python) to interact with DynamoDB, either storing new data, fetching existing records, updating records, or deleting records.

Lambda returns a response to the API Gateway:

  • After interacting with DynamoDB, the Lambda function returns a response (success or error) to API Gateway.

API Gateway sends the response back to the client:

  • API Gateway receives the response from the Lambda function and forwards it back to the user or client.

Understanding the Workflow of a Serverless Application

 Imagine you’re building an e-commerce platform where users can view and add products using an Angular frontend. The underlying architecture leverages API Gateway, AWS Lambda, and DynamoDB to keep the application serverless. Let’s break down the entire flow in a real-world scenario.

Step 1: User Interaction with the Angular Frontend

When the user interacts with your Angular application—let’s say they want to add a new product to the store—they will fill out a form containing details like the product name, description, and price. Once the form is complete, the user clicks the Submit button.

This action triggers an HTTP request (for example, a POST request) that the Angular app sends to a specific URL. This URL is not just any web address; it points to an API Gateway endpoint. At this point, the frontend is unaware of what happens next. It simply makes the request and waits for a response.

Step 2: API Gateway Receives the HTTP Request

Once the Angular app sends the HTTP request, API Gateway takes over. Think of API Gateway as the middleman who knows exactly where to send the incoming request.

API Gateway will examine the type of request (in this case, a POST) and the resource being accessed (e.g., /products). Based on these factors, it knows that the next step is to trigger a Lambda function. The real power of API Gateway lies in this orchestration, as it routes various types of requests (like GET, POST, PUT, etc.) to specific backend services.

The beauty here is that you don’t have to manage any servers for this. API Gateway scales automatically, whether one user is adding a product or thousands of users are making requests simultaneously.

Step 3: Lambda Function is Triggered

Once API Gateway receives the request, it invokes the corresponding AWS Lambda function that you’ve written to handle this specific operation. Lambda acts as the backend logic of your application.

Let’s break down what happens inside Lambda:

  • Input Parsing: The Lambda function receives the request payload sent by the Angular frontend, which contains product details like the name, description, and price.
  • Business Logic: Now, it’s up to Lambda to process this data. Maybe your logic includes validating the fields or ensuring that the product price isn’t negative.
  • Interaction with DynamoDB: Once the data is validated, Lambda is responsible for inserting the product details into DynamoDB, your NoSQL database.

Here’s an example of what the Lambda code might do:

  • It uses the AWS SDK (specifically, boto3 in Python) to make an API call to DynamoDB.
  • A put_item request is made to insert the new product into the database.
  • This is all done without worrying about server configurations or scaling. AWS manages it automatically.

The actual data storage happens in DynamoDB, but from the perspective of the Angular app, this is all just backend magic. At the end of this step, the product details are securely stored in DynamoDB.

 

Step 4: DynamoDB Stores the Data

DynamoDB plays the role of your highly scalable database. In a traditional application, you would have to manage a database server, worry about scaling it as traffic grows, and configure backups. With DynamoDB, AWS does all of that for you.

Here’s what happens when Lambda communicates with DynamoDB:

  • Data Insertion: DynamoDB receives the put_item request from Lambda. It processes the request to store the product details.
  • Fast Response Time: DynamoDB is designed for low-latency performance, so the data insertion happens almost instantly, no matter how many users are interacting with your app at the same time.

If multiple users are adding products simultaneously, DynamoDB handles these requests without any performance degradation. It’s one of the reasons why it’s ideal for serverless applications, which often see unpredictable traffic spikes.

Step 5: Lambda Returns the Response

Once DynamoDB successfully stores the product data, it sends a confirmation back to the Lambda function. The Lambda function’s job is almost complete at this point.

However, there’s one last thing to do: send a response back to API Gateway, which in turn sends it back to the Angular frontend.

  • Success Response: If the product was added successfully, Lambda prepares a success message, which could include details like the product ID or a confirmation that the operation was successful.
  • Error Handling: If something went wrong (e.g., invalid data or a database error), Lambda returns an error message instead. API Gateway then relays this error back to the Angular app.

By the end of this step, the frontend has received a response. If everything went well, the app can notify the user that their product was successfully added to the store.

 

Step 6: Angular Frontend Updates the UI

Finally, once the Angular app receives the response from API Gateway, it updates the user interface accordingly:

  • If the product was added successfully, it might display a success message or refresh the product list to show the newly added item.
  • If an error occurred, it could display an error message and give the user a chance to correct the issue (e.g., missing or invalid product details).

At this point, the entire serverless workflow is complete, and the user has successfully interacted with the system without any awareness of the complex backend infrastructure.

STEP BY STEP PROCESS:

Create a DynamoDB Table

  1. Go to the DynamoDB console.
  2. Click Create Table.
    • Table Name: Users (or any name relevant to your use case).
    • Primary Key: userId (String).
  3. Click Create Table.

 

Create a Lambda Function (Python)

 

        Write Lambda Function Code→

 

import json

import boto3

from boto3.dynamodb.conditions import Key

 

# Initialize DynamoDB

dynamodb = boto3.resource(‘dynamodb’)

table = dynamodb.Table(‘Users’)

 

def lambda_handler(event, context):

    method = event[‘httpMethod’]

    

    if method == ‘POST’:

        body = json.loads(event[‘body’])

        user_id = body[‘userId’]

        name = body[‘name’]

        

        # Add user to DynamoDB

        table.put_item(

            Item={

                ‘userId’: user_id,

                ‘name’: name

            }

        )

        

        return {

            ‘statusCode’: 200,

            ‘body’: json.dumps({‘message’: ‘User added successfully!’})

        }

    

    elif method == ‘GET’:

        user_id = event[‘queryStringParameters’][‘userId’]

        

        # Get user from DynamoDB

        response = table.get_item(

            Key={‘userId’: user_id}

        )

        

        if ‘Item’ in response:

            return {

                ‘statusCode’: 200,

                ‘body’: json.dumps(response[‘Item’])

            }

        else:

            return {

                ‘statusCode’: 404,

                ‘body’: json.dumps({‘message’: ‘User not found’})

            }

 

    elif method == ‘PUT’:

        body = json.loads(event[‘body’])

        user_id = body[‘userId’]

        name = body[‘name’]

        

        # Update user in DynamoDB

        table.update_item(

            Key={‘userId’: user_id},

            UpdateExpression=”set #n = :name”,

            ExpressionAttributeValues={‘:name’: name},

            ExpressionAttributeNames={‘#n’: ‘name’},

        )

        

        return {

            ‘statusCode’: 200,

            ‘body’: json.dumps({‘message’: ‘User updated successfully!’})

        }

 

    elif method == ‘DELETE’:

        user_id = event[‘queryStringParameters’][‘userId’]

        

        # Delete user from DynamoDB

        table.delete_item(

            Key={‘userId’: user_id}

        )

        

        return {

            ‘statusCode’: 200,

            ‘body’: json.dumps({‘message’: ‘User deleted successfully!’})

        }

 

    else:

        return {

            ‘statusCode’: 400,

            ‘body’: json.dumps({‘message’: ‘Unsupported method’})

        }

 

Set Lambda Permissions for DynamoDB

  1. In the Lambda console, go to Configuration > Permissions.
  2. Attach the following policy to your Lambda execution role:

 

{

    “Version”: “2012-10-17”,

    “Statement”: [

        {

            “Effect”: “Allow”,

            “Action”: [

                “dynamodb:PutItem”,

                “dynamodb:GetItem”,

 

                “dynamodb:UpdateItem”,

                “dynamodb: DeleteItem”

            ],

            “Resource”: “arn:aws:dynamodb:REGION:ACCOUNT_ID: table/Users”

        }

    ]

}

 

Create an API in API Gateway

 Create an API Gateway REST API

  1. Go to the API Gateway console.
  2. Click Create API.
    • Choose REST API.
    • Click Build.
    • Name your API (e.g., UserManagementAPI).
    • Click Create API.

 Define Resources and Methods

  1. Click Actions > Create Resource.
    • Resource Name: users.
    • Resource Path: /users.
  2. Select the user’s resource and click Actions > Create Method.
    • Choose POST, GET, PUT, and DELETE for the respective Lambda functions.

 Integrate Lambda with API Gateway

    For each method (POST, GET, PUT, DELETE):

  1. Select Lambda Function as the integration type.
  2. Choose your Lambda function (userManagementFunction).
  3. Click Save.

 Enable CORS (Cross-Origin Resource Sharing)

  1. Select your users resource.
  2. Click Actions > Enable CORS.
    • Select the methods (GET, POST, etc.).
    • Click Enable CORS and replace existing CORS headers.

 Deploy the API

  1. Click Actions > Deploy API.
    • Create a new stage (e.g., prod).
  2. Note the Invoke URL — this is the URL for your API.

Best Practices for Building a Serverless App with AWS

Here are some best practices to follow when building serverless apps using API Gateway, Lambda, and DynamoDB:

1. Use CORS Configuration in API Gateway

  • What is CORS? CORS (Cross-Origin Resource Sharing) is required if your Angular app and API Gateway are hosted on different domains.
  • Why Important? Browsers block requests coming from different origins unless explicitly allowed.
  • Solution: Enable CORS on API Gateway for all necessary methods.
  • Documentation: Configuring CORS for API Gateway

2. Efficient Lambda Function Design

  • Tip: Keep Lambda functions focused on a single task. This reduces cold start time and improves maintainability.
  • Best Practice: Reuse Lambda layers for shared code or dependencies.
  • Documentation: Optimising Lambda Performance

3. DynamoDB Table Design

  • Tip: Design your table based on access patterns. DynamoDB performs best when queries are predictable.
  • Best Practice: Use Global Secondary Indexes (GSIs) to support additional query patterns.
  • Documentation: Best Practices for DynamoDB

4. Use CloudWatch for Monitoring

  • Tip: Set up CloudWatch to monitor your Lambda functions and API Gateway.
  • Why Important? CloudWatch provides logs and metrics, helping you debug errors and optimise performance.
  • Documentation: CloudWatch Logs for Lambda

 

Conclusion

In this blog, we’ve walked through the architecture, services, and step-by-step process of building a serverless application on AWS using API Gateway, Lambda (Python), and DynamoDB. By breaking it down into simple, digestible pieces, we hope you now have a clear understanding of how these services work together.

By following the best practices, you can ensure your serverless application is scalable, cost-effective, and easy to maintain. Ready to build? Get started with the AWS documentation links provided to deepen your knowledge and start deploying your own serverless apps!

Happy building!