Skip to content

AWS API Gateway — Complete Guide

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you'll learn about AWS API Gateway. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

AWS API Gateway is a fully managed service that makes it easy to create, publish, maintain, monitor, and secure APIs at any scale, integrating with Lambda, DynamoDB, and other AWS services.

What You'll Learn

By the end of this lesson, you will create REST and HTTP APIs, integrate with Lambda, configure stages and usage plans, and implement caching and throttling.

Why It Matters

AWS API Gateway eliminates infrastructure management. You define your API and the gateway handles scaling, SSL, authentication, and throttling automatically.

Real-World Use

A Serverless application uses API Gateway in front of Lambda functions for CRUD operations, with Cognito user pools for authentication and usage plans for tiered access.

AWS API Gateway Concepts

flowchart TD
    Client --> APIGW[AWS API Gateway]
    APIGW -->|REST API| Lambda[Lambda Function]
    APIGW -->|HTTP API| Service[HTTP Service]
    APIGW -->|Websocket| WS[WebSocket Handler]
    APIGW --> Cache[Cache Layer]
    APIGW --> Throttle[Throttling]
    APIGW --> Usage[Usage Plans]

API Gateway Configuration

# aws_apigw.py
import json
from typing import Any, Dict, List, Optional

class AWSAPIGatewayConfig:
    def __init__(self, api_name: str, protocol: str = "REST"):
        self.api_name = api_name
        self.protocol = protocol
        self.resources: List[Dict] = []
        self.stages: Dict[str, dict] = {}
        self.usage_plans: List[Dict] = []

    def add_resource(self, path: str, method: str,
                     integration_type: str = "AWS_PROXY",
                     integration_uri: str = "",
                     auth_type: Optional[str] = None):
        self.resources.append({
            "path": path,
            "method": method,
            "integration_type": integration_type,
            "integration_uri": integration_uri,
            "auth_type": auth_type,
        })

    def add_stage(self, name: str, throttle_rate: float = 10000.0,
                  throttle_burst: int = 5000, cache_enabled: bool = False):
        self.stages[name] = {
            "throttling_rate": throttle_rate,
            "throttling_burst": throttle_burst,
            "cache_enabled": cache_enabled,
        }

    def add_usage_plan(self, name: str, quota: int = 1000,
                       throttle_rate: float = 100.0,
                       throttle_burst: int = 50):
        self.usage_plans.append({
            "name": name,
            "quota": quota,
            "throttle_rate": throttle_rate,
            "throttle_burst": throttle_burst,
        })

    def summary(self) -> dict:
        methods = sum(len([m for m in self.resources if m["method"] == method])
                     for method in ["GET", "POST", "PUT", "DELETE"])
        return {
            "api": self.api_name,
            "protocol": self.protocol,
            "endpoints": len(self.resources),
            "stages": list(self.stages.keys()),
            "usage_plans": [p["name"] for p in self.usage_plans],
        }

gw = AWSAPIGatewayConfig("Product API", "REST")
gw.add_resource("/products", "GET", "AWS_PROXY",
                "arn:aws:lambda:us-east-1:123456789012:function:listProducts")
gw.add_resource("/products", "POST", "AWS_PROXY",
                "arn:aws:lambda:us-east-1:123456789012:function:createProduct")
gw.add_resource("/products/{id}", "GET", "AWS_PROXY",
                "arn:aws:lambda:us-east-1:123456789012:function:getProduct")
gw.add_resource("/products/{id}", "DELETE", "AWS_PROXY",
                "arn:aws:lambda:us-east-1:123456789012:function:deleteProduct")
gw.add_stage("prod", throttle_rate=10000, throttle_burst=5000, cache_enabled=True)
gw.add_stage("dev", throttle_rate=1000, throttle_burst=500)
gw.add_usage_plan("free", quota=1000, throttle_rate=10)
gw.add_usage_plan("pro", quota=100000, throttle_rate=100)

summary = gw.summary()
print(json.dumps(summary, indent=2))
print(f"\nResources:")
for r in gw.resources:
    print(f"  {r['method']:7s} {r['path']:20s} -> {r['integration_uri'][:50]}...")

Expected output:

{
  "api": "Product API",
  "protocol": "REST",
  "endpoints": 4,
  "stages": [
    "prod",
    "dev"
  ],
  "usage_plans": [
    "free",
    "pro"
  ]
}

Lambda Integration

# lambda_integration.py
import json
from typing import Any, Dict, Optional

class LambdaIntegration:
    def build_request(self, http_method: str, path: str,
                      headers: Dict, body: Optional[Dict],
                      path_params: Optional[Dict] = None,
                      query_params: Optional[Dict] = None) -> Dict:
        return {
            "httpMethod": http_method,
            "path": path,
            "headers": headers,
            "queryStringParameters": query_params or {},
            "pathParameters": path_params or {},
            "body": json.dumps(body) if body else None,
            "requestContext": {
                "stage": "prod",
                "requestId": "req-12345",
            },
        }

    def parse_response(self, response: Dict) -> Dict:
        return {
            "statusCode": response.get("statusCode", 200),
            "headers": {
                "Content-Type": "application/json",
                "Access-Control-Allow-Origin": "*",
                **response.get("headers", {}),
            },
            "body": response.get("body", "{}"),
        }

integration = LambdaIntegration()
event = integration.build_request("GET", "/products/42",
    {"Authorization": "Bearer token123"},
    None, {"id": "42"}, {"include_details": "true"})
print(json.dumps(event, indent=2))

Expected output shows the Lambda event structure with httpMethod, path, headers, pathParameters, queryStringParameters.

Common Mistakes

1. Lambda Timeouts

API Gateway has a 29-second timeout. Lambda functions taking longer return 504 errors. Use async processing for long-running tasks.

2. No CORS Configuration

CORS headers must be configured in API Gateway AND returned by the Lambda. Missing CORS causes browser errors.

3. Usage Plan Without API Keys

Usage plans require API keys to track usage. Generate and distribute keys to clients.

4. Overlooking Throttling Defaults

Default throttling is 10,000 rps with 5,000 burst. For production, adjust based on expected traffic.

5. Not Enabling CloudWatch Logs

Without logging, debugging API errors is difficult. Enable execution logging and error logging.

Practice Questions

1. What is the difference between REST API and HTTP API in API Gateway?

REST API has more features (usage plans, API keys, WAF). HTTP API is simpler, cheaper, and faster with limited features.

2. How does API Gateway integrate with Lambda?

API Gateway acts as a trigger for Lambda. The Lambda receives an event with HTTP details and returns a response with status code and body.

3. What is a stage in API Gateway?

A stage is a snapshot of the API configuration (endpoints, throttling, caching) deployed to a URL like https://api.example.com/prod.

4. How do usage plans work?

Usage plans set throttling and quota limits per API key. Clients with different plans get different rate limits.

Challenge

Design an AWS API Gateway setup for a serverless e-commerce API with products, orders, and users endpoints, each integrating with Lambda, with stages for dev/staging/prod and usage plans for free/pro/enterprise tiers.

FAQ

Can AWS API Gateway handle WebSockets?

Yes. API Gateway supports WebSocket APIs with routes for $connect, $disconnect, and $default with Lambda or HTTP integration.

How does API Gateway caching work?

API Gateway caches responses per endpoint with configurable TTL (30s-1h). Cache size ranges from 0.5GB to 237GB.

What is the cost of API Gateway?

REST API costs $3.50 per million requests plus data transfer. HTTP API costs $1.00 per million requests.

Can API Gateway validate requests?

Yes. API Gateway supports request validation against JSON Schema models, checking required fields and types before reaching the backend.

How does API Gateway handle authentication?

It supports Cognito User Pools, IAM authorization, Lambda authorizers, and custom JWT validation.

Mini Project: API Gateway Simulator

# apigw_sim.py
import json
import time
from typing import Any, Dict, Optional

class APIGatewaySimulator:
    def __init__(self):
        self.endpoints: Dict[str, dict] = {}
        self.stage = "prod"

    def add_endpoint(self, method: str, path: str, handler):
        key = f"{method}:{path}"
        self.endpoints[key] = {"handler": handler, "calls": 0}

    def handle_request(self, method: str, path: str,
                       headers: Dict, body: Any = None) -> Dict:
        key = f"{method}:{path}"
        matched = None

        for ep_key, config in self.endpoints.items():
            ep_method, ep_path = ep_key.split(":", 1)
            if ep_method == method and self._match_path(ep_path, path):
                matched = config
                break

        if not matched:
            return {"statusCode": 404, "body": json.dumps({"error": "Not found"})}

        matched["calls"] += 1
        return matched["handler"](method, path, headers, body)

    def _match_path(self, pattern: str, path: str) -> bool:
        return path.startswith(pattern.rstrip("*"))

sim = APIGatewaySimulator()

def list_products(method, path, headers, body):
    return {"statusCode": 200, "body": json.dumps([{"id": 1, "name": "Widget"}])}

def create_product(method, path, headers, body):
    return {"statusCode": 201, "body": json.dumps({"created": True})}

sim.add_endpoint("GET", "/products", list_products)
sim.add_endpoint("POST", "/products", create_product)

r1 = sim.handle_request("GET", "/products", {})
r2 = sim.handle_request("POST", "/products", {}, {"name": "Gadget"})
r3 = sim.handle_request("GET", "/orders", {})

print(f"GET /products: {r1['statusCode']}")
print(f"POST /products: {r2['statusCode']}")
print(f"GET /orders: {r3['statusCode']}")

Expected output:

GET /products: 200
POST /products: 201
GET /orders: 404

What's Next

You understand AWS API Gateway. Next, learn about Azure API Management, then explore GraphQL gateway.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro