Amazon API Gateway
Amazon API Gateway is a managed service for creating, publishing, monitoring and securing REST, HTTP and WebSocket APIs. It handles TLS termination, authorisation, request routing, throttling and logging, so a backend can be a bare Lambda function, an internal service behind a load balancer, or an AWS service called directly.
Choosing an API type
Section titled “Choosing an API type”Most of the guidance written about API Gateway before 2020 describes REST APIs only. There are three types, and the choice is not cosmetic — it decides both the price and the feature set.
| REST API | HTTP API | WebSocket API | |
|---|---|---|---|
| Protocol | Request/response over HTTPS | Request/response over HTTPS | Stateful, full-duplex |
| Relative cost | Highest | Lower | Per message and per connection-minute |
| Typical use | Public or monetised APIs needing API keys, request validation, WAF or private endpoints | Lambda and HTTP proxying where none of those are needed | Chat, live dashboards, streaming updates |
REST APIs support the larger feature set. HTTP APIs are deliberately minimal so they can be offered at a lower price, and for a straightforward Lambda proxy they are usually the right default. WebSocket APIs are a different shape entirely: the client holds a connection open and API Gateway routes incoming messages to backend integrations by message content.
Features that exist only on REST APIs include response caching, API keys and usage plans, per-client rate limiting, request validation, request-body mapping templates, custom gateway responses, canary release deployments, mock integrations, execution logging, X-Ray tracing, AWS WAF integration, resource policies and private endpoints. HTTP APIs, in exchange, offer automatic deployments, native JWT authorizers and private integrations with AWS Cloud Map.
AWS maintains a feature-by-feature comparison in Choose between REST APIs and HTTP APIs; check it before committing, because the list moves.
REST endpoint types
Section titled “REST endpoint types”A REST API is published to one of three endpoint types.
Regional. The API is served from the Region it is deployed in. This is the default and the right choice when clients are in the same Region, or when a CDN is already being managed separately in front of the API.
Edge-optimised. API Gateway fronts the API with a CloudFront distribution, so requests enter the AWS network at the nearest edge location. This helps geographically dispersed clients; it does not cache responses unless caching is configured.
Private. The API is reachable only from inside a VPC through an interface VPC endpoint. Nothing about it is exposed to the internet.
HTTP APIs are Regional only. Private endpoints and edge optimisation are REST-only.
Integrations
Section titled “Integrations”The integration is what API Gateway calls when a route matches:
- Lambda — proxy integration passes the whole request through and takes the function’s response as-is; non-proxy integration uses mapping templates to reshape both.
- HTTP — any reachable HTTP endpoint, public or private.
- AWS service — call another AWS service directly (for example putting a record on a Kinesis stream or a message on an SQS queue) with no compute in between.
- Private — a Network Load Balancer, Application Load Balancer, or, for HTTP APIs, an AWS Cloud Map service.
- Mock — return a canned response without a backend; useful for CORS pre-flight and for stubbing a contract before the backend exists. REST APIs only.
Request and response handling
Section titled “Request and response handling”A REST API can transform requests and responses with Velocity mapping templates: rewrite the body, move values between headers, query string and path, and convert content types. It can also validate the request against a JSON Schema model and reject malformed input before the backend is invoked.
HTTP APIs support parameter mapping (headers, path and query string) but not body transformation and not request validation. Where an HTTP API is chosen, validation belongs in the backend.
Stages and deployments
Section titled “Stages and deployments”A REST API is not live until a deployment is made to a stage. Stages carry their own throttle
settings, logging configuration, cache configuration and stage variables, which is how a single
API definition serves dev, test and prod. Canary release deployments — sending a fixed
percentage of stage traffic to a new deployment — are a REST API feature; HTTP APIs instead
support automatic deployment on change.
Response caching
Section titled “Response caching”Response caching is a REST API feature, configured per stage with a provisioned cache size and a per-method time-to-live. When a cached entry is present, API Gateway answers directly and the backend is never invoked, which reduces both latency and backend cost. Cache keys can be built from selected request parameters, and clients can be permitted to bypass the cache with a header if the API grants them that right. HTTP APIs have no built-in cache; put CloudFront in front of them instead.
Access control
Section titled “Access control”- IAM — SigV4-signed requests, for callers that already hold AWS credentials.
- Amazon Cognito user pools — token validation against a user pool.
- Lambda authorizers — arbitrary token or request-parameter validation in a function, with a cacheable policy result.
- JWT authorizers — native OIDC/OAuth 2.0 token validation. HTTP APIs only.
- Resource policies — allow or deny by source VPC, VPC endpoint or account. REST only.
- Mutual TLS — client-certificate authentication on a custom domain, on both types.
API keys identify a caller; they are not an authentication mechanism and should never be the only thing between the internet and the backend.
Usage plans, throttling and 429 responses
Section titled “Usage plans, throttling and 429 responses”Throttling is applied at several levels, and a request is rejected by the first one it exceeds:
- Account level, per Region, across all APIs.
- Stage and method level, set on the deployment.
- Usage plan level, per API key, when the API is a REST API with usage plans configured.
API Gateway throttles with a token bucket: a steady refill rate plus a burst allowance, so a
short spike above the rate limit is absorbed while a sustained one is not. A request that is
throttled is rejected with HTTP 429 Too Many Requests and the body
{"message": "Too Many Requests"}. Usage plans additionally impose a quota — a hard cap on
requests per day, week or month for a given API key — and a request that exceeds the quota is
also rejected with 429.
Usage plans and per-client rate limiting are REST-only. An HTTP API can be throttled at the account, stage and route level, but there is no per-client dimension.
Handling 429 on the client side
Section titled “Handling 429 on the client side”429 means the caller should slow down and retry, not that the request was invalid. A client
that retries immediately makes the problem worse; a client that retries in lockstep with every
other client produces a thundering herd. Two rules cover it:
- Honour a
Retry-Afterheader when the server sends one. - Otherwise back off exponentially with jitter, and give up after a bounded number of attempts.
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
async function callApi(url, { attempts = 5 } = {}) { for (let attempt = 0; attempt < attempts; attempt++) { const response = await fetch(url);
if (response.status !== 429 && response.status !== 503) { return response; }
const retryAfter = Number(response.headers.get('Retry-After')); const backoff = Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter * 1000 : Math.min(2 ** attempt * 100, 20_000) * (0.5 + Math.random());
await sleep(backoff); }
throw new Error(`Still throttled after ${attempts} attempts`);}The AWS SDKs implement this behaviour already, with configurable retry modes; hand-rolled retry logic is only needed for direct HTTP callers.
Throttling algorithms
Section titled “Throttling algorithms”The same four algorithms come up whenever a rate limit has to be designed rather than consumed:
- Fixed window — simplest to implement, but allows a double-rate burst across a window boundary.
- Sliding window — more accurate, and removes the boundary burst.
- Token bucket — allows a controlled burst while holding a long-run average. This is what API Gateway uses.
- Leaky bucket — smooths output to a constant rate, which suits queue-backed processing.
Example: a REST API over Lambda and DynamoDB
Section titled “Example: a REST API over Lambda and DynamoDB”A minimal CRUD API has two routes and two functions:
GET /customer/{id}— API Gateway matches the route, invokes agetCustomerfunction, which reads the item from DynamoDB and returns it. With stage caching enabled, a repeated request for the same customer is answered from the cache and the function is never invoked.PUT /customer/{id}— API Gateway validates the request against the method’s model, invokes acreateCustomerfunction, which writes the item and returns a confirmation.
Everything above the function — TLS, authorisation, throttling, logging, retries on 5xx — is the gateway’s responsibility, and none of it is code in the handler.
Custom domains
Section titled “Custom domains”An API is published under a generated hostname of the form
{api-id}.execute-api.{region}.amazonaws.com. A custom domain name maps a real hostname onto
one or more APIs and stages, using an ACM certificate and SNI. Both REST and HTTP APIs support
custom domains, and a single domain can route different base paths to different APIs.
Monitoring
Section titled “Monitoring”CloudWatch metrics (Count, 4XXError, 5XXError, Latency, IntegrationLatency,
CacheHitCount, CacheMissCount) are available for both REST and HTTP APIs, and access logs
can be delivered to CloudWatch Logs. Execution logging — the verbose per-request trace of what
the gateway did internally — and X-Ray tracing are REST-only. Alarm on 5XXError and on
Latency percentiles rather than averages.
Charges are per million requests, plus data transfer, plus an hourly charge for a provisioned cache. HTTP APIs cost materially less per request than REST APIs, so the API type is the single largest cost lever. After that: cache aggressively where responses are cacheable, and use usage-plan quotas to make third-party abuse bounded rather than unbounded.