AWS offers three distinct API Gateway types, and choosing incorrectly leads to either unnecessary costs, missing features, or architectural dead ends. After building dozens of production APIs, this guide provides a decision framework based on real requirements, performance benchmarks, and cost analysis. We will deep-dive into when REST APIs justify their premium, when HTTP APIs are the clear winner, and how WebSocket APIs enable real-time bidirectional communication.
Feature Comparison Matrix
| Feature | REST API | HTTP API | WebSocket API |
|---|---|---|---|
| Pricing (per million) | $3.50 | $1.00 | $1.00 + $0.25/M minutes |
| Latency (p99) | ~29ms | ~10ms | N/A (persistent) |
| Request Validation | ✅ Built-in | ❌ | ❌ |
| API Keys & Usage Plans | ✅ | ❌ | ❌ |
| Caching | ✅ (per stage) | ❌ | N/A |
| WAF Integration | ✅ | ✅ (limited) | ❌ |
| Private Integrations | ✅ VPC Link | ✅ VPC Link | ✅ |
| JWT Authorizers | Lambda only | ✅ Native | Lambda only |
Decision Tree
flowchart TB
Start["API Gateway Needed"] --> Realtime{Real-time bidirectional?}
Realtime -->|Yes| WebSocket["WebSocket API"]
Realtime -->|No| Features{Need caching, API keys, or request validation?}
Features -->|Yes| REST["REST API"]
Features -->|No| JWT{Using OAuth/JWT auth?}
JWT -->|Yes| HTTP["HTTP API (Native JWT)"]
JWT -->|No| Cost{Cost sensitive?}
Cost -->|Yes| HTTP
Cost -->|No| REST
style REST fill:#FFF3E0,stroke:#E65100
style HTTP fill:#C8E6C9,stroke:#2E7D32
style WebSocket fill:#E1F5FE,stroke:#0277BD
REST API: When Features Justify Cost
REST APIs cost 3.5x more than HTTP APIs. This is justified when you need:
Request Validation
REST APIs can validate request bodies against JSON Schema before invoking Lambda:
# SAM template
CreateOrderValidator:
Type: AWS::ApiGateway::RequestValidator
Properties:
RestApiId: !Ref Api
ValidateRequestBody: true
ValidateRequestParameters: true
CreateOrderModel:
Type: AWS::ApiGateway::Model
Properties:
RestApiId: !Ref Api
ContentType: application/json
Schema:
type: object
required: [customerId, items]
properties:
customerId:
type: string
pattern: "^CUST-[0-9]+$"
items:
type: array
minItems: 1
API Caching
Enable caching to reduce Lambda invocations for read-heavy endpoints:
resource "aws_api_gateway_method_settings" "cache" {
rest_api_id = aws_api_gateway_rest_api.main.id
stage_name = aws_api_gateway_stage.prod.stage_name
method_path = "products/GET"
settings {
caching_enabled = true
cache_ttl_in_seconds = 300
}
}
HTTP API: The Default Choice
For most APIs, HTTP API is the right choice. It is cheaper, faster, and has native JWT support.
Native JWT Authorization
HttpApi:
Type: AWS::Serverless::HttpApi
Properties:
Auth:
DefaultAuthorizer: OAuth2Authorizer
Authorizers:
OAuth2Authorizer:
AuthorizationScopes:
- orders.read
- orders.write
JwtConfiguration:
issuer: https://cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxx
audience:
- 1234567890abcdef
The JWT is validated at the API Gateway layer—no Lambda cold start for auth. This alone can reduce p99 latency by 100ms+.
WebSocket API: Real-Time Applications
WebSocket APIs maintain persistent connections, enabling bidirectional real-time communication. Use cases: chat, live dashboards, gaming, IoT telemetry.
# Lambda handler for WebSocket $connect route
def connect_handler(event, context):
connection_id = event['requestContext']['connectionId']
# Store connection in DynamoDB
table.put_item(Item={
'connectionId': connection_id,
'connectedAt': datetime.now().isoformat()
})
return {'statusCode': 200}
# Broadcasting to connected clients
def broadcast(message):
apigw_management = boto3.client('apigatewaymanagementapi',
endpoint_url=f"https://{api_id}.execute-api.{region}.amazonaws.com/{stage}")
connections = table.scan()['Items']
for conn in connections:
try:
apigw_management.post_to_connection(
ConnectionId=conn['connectionId'],
Data=json.dumps(message)
)
except apigw_management.exceptions.GoneException:
# Connection closed, clean up
table.delete_item(Key={'connectionId': conn['connectionId']})
Cost Analysis Example
Scenario: 10 million API requests/month
| API Type | Monthly Cost |
|---|---|
| REST API | $35.00 |
| HTTP API | $10.00 |
| Savings | $25.00/month (71%) |
At scale (1 billion requests), the difference is $25,000/month.
Key Takeaways
- Default to HTTP API unless you specifically need REST features
- Use REST API for caching, request validation, API keys, and usage plans
- Use WebSocket API for real-time bidirectional communication
- HTTP API has native JWT support—no Lambda authorizer needed
- At scale, HTTP API saves 71% compared to REST API
Discover more from C4: Container, Code, Cloud & Context
Subscribe to get the latest posts sent to your email.