DEV Community

Muhammad Umair Ashraf
Muhammad Umair Ashraf

Posted on

Building REST APIs on AWS with API Gateway, Lambda, and DynamoDB

Modern applications depend on APIs to exchange data. A web application retrieves products, a mobile app submits orders, and an internal dashboard fetches operational information.

REST APIs provide a standard way for these applications to communicate over HTTP.

On AWS, you can build a serverless REST API using Amazon API Gateway, AWS Lambda, and Amazon DynamoDB. This approach reduces infrastructure management while giving you managed services for API routing, application logic, and data storage.

In this tutorial, we'll explore the architecture and build a simple product endpoint using Python.

1. What Is a REST API?

A REST API exposes resources through URLs and uses HTTP methods to perform operations.

Imagine you're building a product catalog API:

Method Endpoint Purpose
GET /products List products
GET /products/101 Retrieve one product
POST /products Create a product
PUT /products/101 Replace a product
PATCH /products/101 Update selected fields
DELETE /products/101 Delete a product

A response might look like this:

{
  "id": "101",
  "name": "Cloud Fundamentals Guide",
  "category": "Education",
  "available": true
}
Enter fullscreen mode Exit fullscreen mode

A good REST API uses consistent resource names, appropriate HTTP methods, meaningful status codes, input validation, and predictable response formats.

2. The AWS Architecture

Our example uses four primary services:

  • Amazon API Gateway: Receives HTTP requests and routes them to the backend.
  • AWS Lambda: Executes the application logic.
  • Amazon DynamoDB: Stores product records.
  • Amazon CloudWatch: Collects logs and metrics to help troubleshoot problems.

The request flow is:

Client → API Gateway → Lambda → DynamoDB

The response travels back to the client through API Gateway.

IAM controls the permissions that allow Lambda to access DynamoDB and allow API Gateway to invoke Lambda.

This separation makes the application easier to maintain and scale without managing API servers.

3. Create a Lambda Function

Let's begin with a simple endpoint that returns a sample product.

In the AWS Lambda console, create a function named GetProductFunction using a supported Python runtime.

Add the following code:

import json

def lambda_handler(event, context):
    product = {
        "id": "101",
        "name": "Cloud Fundamentals Guide",
        "category": "Education",
        "available": True
    }

    return {
        "statusCode": 200,
        "headers": {
            "Content-Type": "application/json"
        },
        "body": json.dumps(product)
    }
Enter fullscreen mode Exit fullscreen mode

This function returns a JSON response with an HTTP status code of 200.

For now, the product is hard-coded. That keeps the first example focused on the API request and response flow.

4. Configure Amazon API Gateway

Next, expose the Lambda function through an API endpoint.

  1. Open the Amazon API Gateway console.
  2. Choose Create API.
  3. Select REST API and choose Build.
  4. Name the API ProductManagementAPI.
  5. Create a resource named /products.
  6. Add a GET method.
  7. Configure the method to invoke GetProductFunction.
  8. Save the configuration.

Make sure API Gateway has permission to invoke the Lambda function. Verify the function's resource-based policy if you encounter an invocation error.

Deploy the API

Deploy the API to a stage named dev.

The invoke URL will look similar to this:

https://{api-id}.execute-api.{region}.amazonaws.com/dev/products
Enter fullscreen mode Exit fullscreen mode

Replace {api-id} and {region} with the values from your API.

Test the endpoint

You can use curl to send an HTTP request:

curl -i \
  "https://{api-id}.execute-api.{region}.amazonaws.com/dev/products"
Enter fullscreen mode Exit fullscreen mode

If the integration is configured correctly, the response should contain 200 OK and the product JSON.

You've now created a basic serverless API endpoint on AWS.

Official walkthrough: Using AWS Lambda with Amazon API Gateway.

5. Connect the API to DynamoDB

Hard-coded data is useful for a first test, but real applications need persistent storage.

Create a DynamoDB table named Products with a string partition key named id.

Now configure a GET resource at /products/{id} and connect it to a Lambda function like this:

import json
import os
import boto3

dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(os.environ["PRODUCTS_TABLE"])

def lambda_handler(event, context):
    path_parameters = event.get("pathParameters") or {}
    product_id = path_parameters.get("id")

    if not product_id:
        return {
            "statusCode": 400,
            "headers": {"Content-Type": "application/json"},
            "body": json.dumps({
                "message": "Product ID is required"
            })
        }

    try:
        response = table.get_item(
            Key={"id": product_id}
        )

        product = response.get("Item")

        if product is None:
            return {
                "statusCode": 404,
                "headers": {"Content-Type": "application/json"},
                "body": json.dumps({
                    "message": "Product not found"
                })
            }

        return {
            "statusCode": 200,
            "headers": {"Content-Type": "application/json"},
            "body": json.dumps(product)
        }

    except Exception:
        print("Product lookup failed")

        return {
            "statusCode": 500,
            "headers": {"Content-Type": "application/json"},
            "body": json.dumps({
                "message": "Internal server error"
            })
        }
Enter fullscreen mode Exit fullscreen mode

Before testing this version:

  • Set the Lambda environment variable PRODUCTS_TABLE to Products.
  • Give the Lambda execution role dynamodb:GetItem permission on the specific table.
  • Ensure the table's partition key is the string attribute id.
  • Deploy the updated Lambda function and API configuration.

The function returns 404 when a product doesn't exist and avoids exposing internal exception details to the caller.

For production use, add structured logging, tests, and appropriate exception classification. Avoid logging sensitive information.

6. REST API or HTTP API?

Amazon API Gateway offers both REST APIs and HTTP APIs.

REST API is worth considering when you need features such as usage plans, API keys, configurable request validation, or supported AWS WAF integration.

HTTP API can be a good fit for simpler applications that need HTTP routing and backend integrations without the full REST API feature set.

Compare the current feature set and pricing before deciding.

Documentation: Amazon API Gateway Developer Guide.

7. Secure Your API

A working API isn't necessarily a secure API. Build security into the design from the beginning.

Authentication and authorization

Depending on your application, API Gateway can use IAM authorization, Amazon Cognito user pools, or Lambda authorizers.

Authentication identifies the caller. Authorization determines which operations and resources that caller may access.

Least-privilege permissions

A Lambda function that reads products should not have unrestricted access to every AWS resource.

Grant only the permissions required for its task. Use separate permissions for functions that create, update, or delete data where appropriate.

Input validation

Validate path parameters, query strings, request bodies, data types, and allowed values. Reject invalid requests before they reach sensitive application logic.

Throttling and abuse protection

Configure throttling limits appropriate for the workload. AWS WAF can provide additional filtering for supported API Gateway REST API configurations.

Protect sensitive information

Use HTTPS, avoid putting credentials in URLs, keep secrets out of source code, and review logging policies to prevent accidental exposure of tokens or personal information.

8. Monitor and Troubleshoot

Amazon CloudWatch provides logs and metrics that help you understand API behavior.

Pay attention to these signals:

Signal Possible cause
4XX responses Invalid requests, missing resources, or authorization problems
5XX responses Backend errors or integration failures
High latency Slow Lambda execution or downstream operations
Lambda errors Application exceptions
DynamoDB throttling Capacity constraints or access-pattern problems

These metrics help narrow down issues, but they don't always identify the root cause. Correlate API Gateway metrics with Lambda logs and DynamoDB metrics to investigate failures.

For production systems, consider structured logging, request IDs, CloudWatch alarms, and appropriate log retention.

9. Manage Costs and Scaling

Serverless services reduce infrastructure management, but they still incur costs.

Your bill may include API requests, Lambda execution duration, DynamoDB usage, CloudWatch logs, and optional security services.

A few practical ways to manage costs:

  • Choose the API type based on actual requirements.
  • Optimize Lambda execution duration through testing.
  • Design DynamoDB keys and indexes around your access patterns.
  • Configure log retention.
  • Monitor usage and establish budgets.
  • Test expected traffic before production deployment.

Review Amazon API Gateway pricing and the pricing for other services in your architecture.

10. Production Readiness Checklist

Before releasing your API, check the following:

  • [ ] Use consistent resource names and HTTP methods.
  • [ ] Validate incoming requests.
  • [ ] Return meaningful HTTP status codes.
  • [ ] Configure authentication and authorization.
  • [ ] Apply least-privilege IAM permissions.
  • [ ] Set appropriate throttling and abuse protection.
  • [ ] Configure logs, metrics, and alarms.
  • [ ] Test invalid requests and backend failures.
  • [ ] Plan deployment stages and API versioning.
  • [ ] Review cost estimates and test realistic traffic.

Final Thoughts

Building a REST API on AWS involves more than creating an endpoint. It requires a thoughtful combination of routing, application logic, data storage, permissions, monitoring, and operational controls.

Amazon API Gateway, AWS Lambda, and DynamoDB provide a practical foundation for serverless APIs. Start with a simple GET endpoint, connect it to persistent data, and then add the security and monitoring your application requires.

Question for the community: For a new AWS application, would you choose API Gateway REST API or HTTP API? What requirements influence your choice?

Further Reading

AWS #Serverless #Python #APIs

Top comments (0)