API Gateway
API Gateway is the AWS managed front door for HTTP APIs and WebSockets. It handles TLS, throttling, authentication (Cognito / Lambda authorisers / IAM), request validation, transformation, and routes to Lambda / EC2 / VPC links / SQS. Pair with HTTP API (cheap, fast, JWT auth) for most APIs; reach for REST API only when you need its specific features.
HTTP API + Lambda + JWT authoriser + throttling
EXAMPLE
# 1) Create an HTTP API (cheaper + faster than REST API for most cases)
api=$(aws apigatewayv2 create-api \
--name shop-api \
--protocol-type HTTP \
--cors-configuration AllowOrigins=https://app.example.com,AllowMethods=GET,POST,DELETE,AllowHeaders='authorization,content-type' \
--query 'ApiId' --output text)
# 2) Lambda function (just for the demo)
zip handler.zip handler.js
fn_arn=$(aws lambda create-function \
--function-name shop-orders \
--runtime nodejs20.x \
--handler handler.handler \
--role arn:aws:iam::123456789012:role/shop-orders-role \
--zip-file fileb://handler.zip \
--query 'FunctionArn' --output text)
# Allow API Gateway to invoke the function
aws lambda add-permission \
--function-name shop-orders \
--statement-id apigw-invoke \
--action lambda:InvokeFunction \
--principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:ap-southeast-2:123456789012:$api/*/*"
# 3) Wire integration + routes
integration=$(aws apigatewayv2 create-integration \
--api-id $api --integration-type AWS_PROXY \
--integration-uri $fn_arn \
--payload-format-version '2.0' \
--query 'IntegrationId' --output text)
aws apigatewayv2 create-route --api-id $api --route-key 'GET /orders' --target "integrations/$integration"
aws apigatewayv2 create-route --api-id $api --route-key 'POST /orders' --target "integrations/$integration"
aws apigatewayv2 create-route --api-id $api --route-key 'GET /orders/{id}' --target "integrations/$integration"
aws apigatewayv2 create-route --api-id $api --route-key 'DELETE /orders/{id}' --target "integrations/$integration"
# 4) Stage + auto-deploy
aws apigatewayv2 create-stage --api-id $api --stage-name '$default' --auto-deploy
# Endpoint
aws apigatewayv2 get-api --api-id $api --query 'ApiEndpoint'
# -> https://abc123.execute-api.ap-southeast-2.amazonaws.com
# 5) JWT authoriser (Cognito or any OIDC provider)
auth_id=$(aws apigatewayv2 create-authorizer \
--api-id $api \
--authorizer-type JWT \
--identity-source '$request.header.Authorization' \
--jwt-configuration Issuer=https://cognito-idp.ap-southeast-2.amazonaws.com/POOL_ID,Audience=APP_CLIENT_ID \
--name cognito-auth --query 'AuthorizerId' --output text)
# Apply to a route
aws apigatewayv2 update-route --api-id $api \
--route-id ROUTE_ID --authorization-type JWT --authorizer-id $auth_id
# 6) Throttling per route — quota + burst
aws apigatewayv2 update-stage --api-id $api --stage-name '$default' \
--default-route-settings ThrottlingBurstLimit=200,ThrottlingRateLimit=100
# 7) Custom domain (optional)
aws apigatewayv2 create-domain-name --domain-name api.example.com \
--domain-name-configurations CertificateArn=arn:aws:acm:...:certificate/abc
aws apigatewayv2 create-api-mapping --api-id $api \
--domain-name api.example.com --stage '$default'
# Then DNS: ALIAS / CNAME to <domain-name>.regional-execute-api...
# 8) Logging — send access logs to CloudWatch
log_group="/aws/apigateway/shop-api"
aws logs create-log-group --log-group-name "$log_group"
aws apigatewayv2 update-stage --api-id $api --stage-name '$default' \
--access-log-settings DestinationArn=arn:aws:logs:...:log-group:$log_group,Format='{ "requestId":"$context.requestId","ip":"$context.identity.sourceIp","path":"$context.routeKey","status":"$context.status","latency":"$context.responseLatency" }'
# 9) HTTP API vs REST API — which to pick
# HTTP API cheaper, lower latency, JWT auth, simpler config; default for new services
# REST API more features: usage plans, API keys, request validators (JSON schema),
# WAF integration, request/response transformations, edge-optimized endpoints
# Pick HTTP API unless you NEED a REST API-only feature.
# 10) WebSocket API — for real-time
# aws apigatewayv2 create-api --name shop-ws --protocol-type WEBSOCKET
# routes: $connect, $disconnect, $default + custom message routes
# 11) Pitfalls
# - Forgetting CORS — preflights fail; browser blocks requests
# - Using REST API when HTTP API would do (4x the cost)
# - Not enabling access logs -> impossible to debug 5xx in prod
# - JWT issuer / audience misconfiguration -> 401s on all requests
# - Lambda timeouts longer than API Gateway 30s limit -> 504s
Why it matters
Use HTTP API + a JWT authoriser for most new services in 2026. It is cheaper, faster, and the JSON Web Token authentication path covers the common case without needing a separate Lambda authoriser. Reach for REST API only when its specific features (request validators, usage plans, API keys) are actually required.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
# Managed REST / HTTP / WebSocket endpoints. # Pairs naturally with Lambda.Try it Yourself »
Discussion
Loading…