AWS API Gateway — Complete Guide
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
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