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 (Senior Level)โ€‹

  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โ€‹