Skip to main content

Amazon API Gateway

Core concept: API Gateway is the fully managed "front door" for APIs β€” it routes HTTP requests to Lambda, EC2, HTTP backends, or AWS services directly. It handles traffic management, CORS, authorization, throttling, and API versioning.


What Is API Gateway?

Reverse Proxy vs. Load Balancer vs. API Gateway

API Gateways are often confused with general-purpose reverse proxies and load balancers. To see a detailed comparison of their differences, feature matrices, and how they coexist in production, see the Reverse Proxy vs. Load Balancer vs. API Gateway Guide.

API Gateway acts as a reverse proxy between your clients (web, mobile, IoT) and your backend services. Think of it as a receptionist at an office building β€” it checks credentials, routes visitors to the right floor, and manages how many visitors can enter at once.

Why Use API Gateway?

Without API GatewayWith API Gateway
Manage own load balancerFully managed scaling
Build auth from scratchBuilt-in Cognito/IAM/Lambda auth
No throttlingPer-client rate limiting
No cachingBuilt-in response caching
No API versioningStage-based versioning
No request validationSchema validation

Endpoint Types (REST API)

TypeDescriptionBest For
Edge-Optimized (Default)Routed through CloudFront edge networkGeographically distributed clients
RegionalDirect access in same regionSame-region clients, custom CDN setups
PrivateVPC-only via Interface VPC EndpointInternal microservices

API Types

TypeUse CaseFeaturesCost
REST APIFull-featured RESTCaching, WAF, usage plans, VTL transforms, Edge/PrivateHigher
HTTP APISimple, low-latencyJWT auth, OIDC, auto-deploy, CORS~70% cheaper
WebSocket APIReal-time (chat, dashboards)Connection management, statefulPer message

REST vs HTTP API Decision Matrix

NeedREST APIHTTP API
Usage plans / API keysβœ…βŒ
Response cachingβœ…βŒ
Resource policies / WAFβœ…βŒ
Request/response transformation (VTL)βœ…βŒ
Cognito JWT auth / OIDCβœ…βœ…
Private integrations (VPC Link)βœ… (NLB)βœ… (ALB, NLB, Cloud Map)
Lowest costβŒβœ…
Fastest performanceβŒβœ…
Exam Decision

If the question mentions usage plans, API keys, caching, WAF, or VTL β†’ REST API If the question asks for simplest or cheapest β†’ HTTP API


Integration Types

Lambda Proxy vs Non-Proxy

FeatureLambda ProxyLambda Non-Proxy (Custom)
RequestEntire raw HTTP request passed to LambdaAPI Gateway extracts/formats parameters
ResponseLambda MUST return {statusCode, body, headers}Lambda returns anything; APIGW formats it
Transformation❌ Not possible at APIGW levelβœ… Uses VTL mapping templates
SetupMinimalHigh (requires mapping templates)
Error if wrong format502 Bad GatewayAPI Gateway handles

Mapping Templates (VTL)

Used in Non-Proxy integrations to transform request/response:

## Request mapping: Rename JSON field for legacy backend
#set($inputRoot = $input.path('$'))
{
"customer_name": "$inputRoot.name",
"customer_email": "$inputRoot.email",
"request_id": "$context.requestId"
}

Direct AWS Service Integration

Skip Lambda entirely β€” call AWS services directly:

# API Gateway β†’ SQS (no Lambda needed!)
Integration:
Type: AWS
IntegrationHttpMethod: POST
Uri: !Sub "arn:aws:apigateway:${AWS::Region}:sqs:path/${AWS::AccountId}/${Queue.QueueName}"
Credentials: !GetAtt ApiGatewayRole.Arn
RequestParameters:
integration.request.header.Content-Type: "'application/x-www-form-urlencoded'"
RequestTemplates:
application/json: "Action=SendMessage&MessageBody=$input.body"

Other direct integrations: DynamoDB, Kinesis, Step Functions, S3

API Gateway β†’ VPC Link β†’ NLB/ALB β†’ Private EC2/ECS/Fargate
  • REST APIs: Connect via Network Load Balancer (NLB)
  • HTTP APIs: Connect via ALB, NLB, or AWS Cloud Map
  • Uses AWS PrivateLink β€” traffic never leaves AWS network

Authorizers

1. Cognito User Pool Authorizer

Client β†’ Login to Cognito β†’ Receives JWT token
Client β†’ API Gateway (Authorization: Bearer <JWT>) β†’ Cognito validates β†’ Allow/Deny
  • Built-in, no Lambda needed
  • Validates JWT signature and expiration
  • Cannot inspect payload or custom logic

2. Lambda Authorizer (Custom)

Client β†’ API Gateway β†’ Lambda Authorizer β†’ Returns IAM Policy
↓
{Allow/Deny, Context}

Two subtypes:

  • Token-based: Receives Bearer token header
  • Request-based: Receives full request context (headers, query params, path)
// Lambda Authorizer returns IAM policy
public class AuthorizerHandler implements RequestHandler<Map<String, Object>, Map<String, Object>> {
public Map<String, Object> handleRequest(Map<String, Object> event, Context context) {
String token = (String) event.get("authorizationToken");

// Validate token (JWT, API key, custom logic)
boolean isValid = validateToken(token);
String userId = extractUserId(token);

return Map.of(
"principalId", userId,
"policyDocument", Map.of(
"Version", "2012-10-17",
"Statement", List.of(Map.of(
"Action", "execute-api:Invoke",
"Effect", isValid ? "Allow" : "Deny",
"Resource", event.get("methodArn")
))
),
"context", Map.of(
"userId", userId,
"plan", "premium" // Available in $context.authorizer.plan
)
);
}
}

Caching: Results cached by TTL (0–3600s). Set TTL=0 for dynamic permissions.

3. IAM (SigV4)

  • Client signs request with AWS credentials (Signature V4)
  • Ideal for service-to-service communication
  • Combine with Resource Policies for cross-account or IP restrictions

4. Mutual TLS (mTLS)

  • Client presents X.509 certificate to authenticate
  • Requires Custom Domain Name
  • Trust store (CA cert PEM file) uploaded to S3
  • Used for B2B, banking, IoT

Authorizer Comparison

AuthorizerUse CaseCustom LogicCaching
CognitoUser pools, social login❌Built-in
LambdaCustom validation, 3rd-party tokensβœ…0–3600s TTL
IAMAWS service-to-service❌N/A
mTLSB2B, banking, IoT❌N/A

Deployment Stages & Stage Variables

API β†’ [dev stage] β†’ https://xyz.execute-api.us-east-1.amazonaws.com/dev
β†’ [staging] β†’ https://xyz.execute-api.us-east-1.amazonaws.com/staging
β†’ [prod stage] β†’ https://xyz.execute-api.us-east-1.amazonaws.com/prod
  • Changes require deployment to a stage to take effect
  • Stage variables = environment variables for API Gateway

Stage Variables + Lambda Aliases

dev stage: lambdaAlias = "dev" β†’ Lambda:dev ($LATEST)
prod stage: lambdaAlias = "prod" β†’ Lambda:prod (version 5)

Integration URI: arn:aws:lambda:...:my-function:${stageVariables.lambdaAlias}

Must grant invoke permission for EACH alias

API Gateway needs lambda:InvokeFunction permission on each specific Lambda alias referenced by stage variables.

Canary Deployments

prod stage β†’ 95% β†’ stable deployment
β†’ 5% β†’ canary deployment (testing new changes)

CORS

If a browser at domain-a.com calls API Gateway at domain-b.com:

  1. Browser sends preflight OPTIONS request
  2. API Gateway responds with CORS headers
  3. Browser allows/blocks the actual request

For Lambda Proxy integration, your Lambda function MUST return CORS headers:

return new APIGatewayProxyResponseEvent()
.withStatusCode(200)
.withHeaders(Map.of(
"Access-Control-Allow-Origin", "https://myapp.example.com",
"Access-Control-Allow-Headers", "Content-Type,Authorization",
"Access-Control-Allow-Methods", "GET,POST,OPTIONS"
))
.withBody(responseBody);

For Non-Proxy integration, configure CORS via Mock Integration on the OPTIONS method.


Caching, Throttling & Usage Plans

Caching (REST API Only)

PropertyValue
TTL0.5 – 3600 seconds (default 300s)
Size0.5 GB – 237 GB
Cache keyMethod + path + query params + headers
InvalidationCache-Control: max-age=0 header
PermissionRequires execute-api:InvalidateCache IAM permission
EncryptionCan be encrypted at rest

Throttling

LimitValue
Account limit10,000 RPS with burst of 5,000
Per-stage/methodConfigurable
Error429 Too Many Requests

Usage Plans & API Keys

Usage Plan "Basic":
Rate: 100 RPS
Burst: 200
Quota: 10,000 requests/month
β†’ Assigned to API Key "customer-A-key"

Usage Plan "Premium":
Rate: 1000 RPS
Burst: 2000
Quota: Unlimited
β†’ Assigned to API Key "customer-B-key"

WebSocket API

Connection Lifecycle

Client β†’ $connect β†’ Lambda (save connectionId to DynamoDB)
Client β†’ $default β†’ Lambda (process messages)
Client β†’ $disconnect β†’ Lambda (remove connectionId from DynamoDB)
Client β†’ customRoute β†’ Lambda (custom action)

Send Message to Client

// Server pushes message to a specific connected client
ApiGatewayManagementApiClient apiClient = ApiGatewayManagementApiClient.builder()
.endpointOverride(URI.create("https://abc123.execute-api.us-east-1.amazonaws.com/prod"))
.build();

apiClient.postToConnection(PostToConnectionRequest.builder()
.connectionId("AbCdEfG=")
.data(SdkBytes.fromUtf8String("{\"message\": \"Hello from server!\"}"))
.build());

Request Validation

API Gateway can validate requests before invoking the backend:

{
"type": "object",
"required": ["name", "email"],
"properties": {
"name": { "type": "string", "minLength": 1, "maxLength": 100 },
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0, "maximum": 150 }
}
}

Returns 400 Bad Request if validation fails β€” no Lambda invocation (saves cost!).


Common Error Codes

CodeMeaningExam Context
400Bad RequestFailed request validation
403ForbiddenWAF blocked, missing API key, authorizer denied
429Too Many RequestsThrottling limit exceeded
502Bad GatewayLambda response format wrong (proxy integration)
503Service UnavailableBackend down or Lambda out of concurrency
504Gateway TimeoutLambda >29s (API Gateway hard limit)
502 vs 504 β€” Exam Classic!
  • 502 = Lambda returned wrong format (missing statusCode/body)
  • 504 = Lambda took longer than 29 seconds (API Gateway timeout limit, NOT Lambda's 15 min limit)

Best Practices

  1. Use HTTP API when you don't need REST-specific features β€” 70% cheaper
  2. Cache responses to reduce Lambda invocations and latency
  3. Enable request validation to reject bad requests before invoking backend
  4. Use stage variables for environment-specific configuration
  5. Direct service integrations when Lambda is just a pass-through
  6. Lambda Authorizer caching β€” set appropriate TTL to reduce auth calls
  7. Custom domains for professional, versioned APIs

DVA-C02 Exam Tips

API Gateway Exam Cheat Sheet
  1. 502 = Lambda proxy response format wrong. 504 = timeout >29s
  2. Usage plans + API keys = per-customer throttling/quotas (REST only)
  3. Stage variables route stages to different Lambda aliases
  4. HTTP API = cheapest, simplest. REST API = full-featured
  5. Lambda Proxy = Lambda must return {statusCode, body, headers}
  6. VTL mapping templates = Non-Proxy integration only
  7. CORS in proxy mode = Lambda must return CORS headers
  8. Canary deployment = gradual traffic shift to new API deployment
  9. Cache invalidation needs execute-api:InvalidateCache permission
  10. WebSocket = $connect, $disconnect, $default routes

Practice Questions

Q1. Throttle API per customer and charge by usage tier. What feature?

A) Stage Variables
B) Lambda Reserved Concurrency
C) Usage Plans with API Keys
D) Cognito User Pools

βœ… Answer & Explanation

C β€” Usage Plans define throttle rates and quotas per API Key per customer.


Q2. Cached API but admins need to bypass cache. How?

A) Lambda Authorizer skips cache
B) Separate cached/uncached stages
C) Cache-Control: max-age=0 header with IAM permission
D) Disable caching for admin routes

βœ… Answer & Explanation

C β€” Clients with execute-api:InvalidateCache permission can send Cache-Control: max-age=0.


Q3. Lambda Proxy returns 502 but Lambda logs show success. Cause?

A) Lambda timeout
B) Lambda returned wrong response format
C) Missing API key
D) Missing invoke permission

βœ… Answer & Explanation

B β€” Lambda Proxy requires {statusCode, body, headers}. Raw string or wrong format β†’ 502. Timeout β†’ 504.


Q4. Route dev stage to Lambda $LATEST and prod to v1 alias. Least effort?

A) Two API Gateways
B) Hardcode ARN per stage
C) Stage Variables referencing Lambda alias in Integration URI
D) Mapping template

βœ… Answer & Explanation

C β€” Stage variable lambdaAlias in the URI ${stageVariables.lambdaAlias} resolves per stage.


Q5. API must call a private ALB in VPC. Which integration?

A) Lambda Proxy
B) VPC Link (HTTP API β†’ ALB)
C) Direct HTTP integration
D) Mock integration

βœ… Answer & Explanation

B β€” VPC Links connect API Gateway to private resources via PrivateLink. HTTP API supports ALB/NLB; REST API supports NLB only.


Interview Questions

  1. How would you design per-tenant rate limiting and monetization while keeping a migration path from REST to HTTP API?
  2. When would you choose VPC Link private integrations over direct Lambda?
  3. How do you handle sporadic 502 from Lambda proxy integration?

Resources

πŸ“–
Track Page Progress0 / 635 Read
Knowledge Base Completion0%