Docs
/
AWS Cloud
Chapter 9
09 — API Gateway
What is API Gateway?
Managed service to create, deploy, and manage REST, HTTP, and WebSocket APIs at any scale.
Client → API Gateway → Lambda / EC2 / Any HTTP endpoint
│
├── Authentication
├── Rate Limiting
├── Request Validation
├── Caching
└── CORS
API Types
| Type | Protocol | Best For | Cost |
|---|---|---|---|
| HTTP API | HTTP | Simple Lambda proxy, low cost | ~$1/million requests |
| REST API | HTTP | Full features (caching, WAF, validation) | ~$3.50/million |
| WebSocket API | WebSocket | Real-time (chat, notifications) | ~$1/million messages |
> Use HTTP API unless you need REST API-specific features (caching, request validation, resource policies).
REST API Example
# SAM template
Resources:
Api:
Type: AWS::Serverless::Api
Properties:
StageName: prod
Cors:
AllowOrigin: "'https://myapp.com'"
AllowMethods: "'GET,POST,PUT,DELETE,OPTIONS'"
AllowHeaders: "'Content-Type,Authorization'"
GetUsersFunction:
Type: AWS::Serverless::Function
Properties:
Handler: handlers/users.getAll
Events:
GetUsers:
Type: Api
Properties:
RestApiId: !Ref Api
Path: /users
Method: GET
CreateUserFunction:
Type: AWS::Serverless::Function
Properties:
Handler: handlers/users.create
Events:
CreateUser:
Type: Api
Properties:
RestApiId: !Ref Api
Path: /users
Method: POST
Stages & Deployment
API Gateway stages:
/dev → points to dev Lambda aliases
/staging → points to staging aliases
/prod → points to prod aliases
Each stage has its own URL:
https://abc123.execute-api.us-east-1.amazonaws.com/dev
https://abc123.execute-api.us-east-1.amazonaws.com/prod
Custom domain:
https://api.myapp.com → maps to prod stage
Authorizers
| Type | How It Works |
|---|---|
| Cognito | Validates JWT from Cognito User Pool |
| Lambda Authorizer | Custom auth logic (API keys, custom tokens) |
| IAM | AWS SigV4 signing (service-to-service) |
// Lambda Authorizer
export const authorizer = async (event: any) => {
const token = event.authorizationToken; // "Bearer xxx"
const decoded = verifyJwt(token.replace('Bearer ', ''));
return {
principalId: decoded.sub,
policyDocument: {
Version: '2012-10-17',
Statement: [{
Action: 'execute-api:Invoke',
Effect: decoded ? 'Allow' : 'Deny',
Resource: event.methodArn,
}],
},
context: { userId: decoded.sub, role: decoded.role },
};
};
Throttling & Rate Limiting
Account-level: 10,000 requests/sec (default)
Stage-level: Can set per-stage limits
Method-level: Can set per-route limits
Usage Plans:
Basic: 100 requests/day, 10/sec burst
Pro: 10,000 requests/day, 100/sec burst
API Keys:
Tied to usage plans for per-client throttling
Request Validation
{
"type": "object",
"required": ["name", "email"],
"properties": {
"name": { "type": "string", "minLength": 1 },
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0 }
}
}
Rejects invalid requests before invoking Lambda — saves cost.
CORS Configuration
// In Lambda response (HTTP API auto-handles if configured)
return {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': 'https://myapp.com',
'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE',
'Access-Control-Allow-Headers': 'Content-Type,Authorization',
},
body: JSON.stringify(data),
};
Key Takeaways
- HTTP API for most use cases (cheaper, simpler); REST API for advanced features
- Use Cognito Authorizer for user-facing APIs, Lambda Authorizer for custom auth
- Enable request validation to reject bad requests before hitting Lambda
- Configure usage plans + API keys for per-client rate limiting
- Use custom domains with Route 53 for production APIs
- Always configure CORS for browser-based clients