API Gateway
After this you can answer: When would API Gateway improve our API design, and which checks must remain in the application?
Picture it
Section titled “Picture it”Where it sits
Section titled “Where it sits”This proposed scanner API is separate from the existing browser application. A JWT is a signed JSON Web Token containing identity claims. The proposed identity provider issues it; API Gateway validates it before invoking the handler.
Our existing ticket uses HMAC, a keyed message authentication code. A proposed ticket verifier must therefore read the same signing secret; the operator’s JWT and the ticket’s HMAC are separate checks.
flowchart LR scan["Check-in scanner (designed, not built)"] -->|"submits scan - HTTPS, JWT and route scope"| gateway["API Gateway HTTP API (designed, not built)"] gateway -->|"validates token - configured issuer, audience and public keys"| auth["JWT authorizer; Cognito issuer (designed, not built)"] gateway -->|"invokes - lambda:InvokeFunction; apigateway.amazonaws.com, SourceArn"| lambda["Check-in Lambda (designed, not built)"] lambda -->|"admits once - proposed role dynamodb:UpdateItem on tickets table"| db["minitickets-dev-tickets DynamoDB"] lambda -->|"verifies HMAC - proposed role secretsmanager:GetSecretValue on one secret"| secret["minitickets/dev/ticket-signing"] class gateway service class gateway designed class scan,lambda app class scan,lambda designed class auth security class auth designed class db aws class secret securityLegend: highlighted = API Gateway; app = proposed scanner code; security = authorizer; dashed = designed, not built; the tickets table is implemented.
Open the existing ALB entry point in the map → · Open the existing tickets table →. No API Gateway map piece is deployed or defined.
How it works
Section titled “How it works”- The scanner obtains an access token from the proposed identity provider and calls
POST /check-ins. A route is a method and path that selects request handling. The token identifies an operator, while the request contains the ticket and a stable scan request ID. - API Gateway selects the stage and route. A stage is a named API deployment endpoint with settings such as logging and throttling. A deployment captures the API configuration used by that endpoint.
- A JWT authorizer verifies the signature, issuer, audience, time claims, and required route scope. A scope is a named permission carried in an access token, such as the proposed
tickets:check-in. Valid authentication does not prove access to every event. - A Lambda proxy integration wraps the request and identity context into the function’s event. Proxy integration means the backend handles most request and response details, rather than a large set of gateway transformations.
- The handler validates input, checks the operator’s event access, verifies the ticket signature, and performs one conditional DynamoDB update. The condition allows admission only while the ticket is in its expected state.
- The handler returns a result such as admitted or already checked in. The gateway returns it to the scanner. A lost response can be retried with the same request ID to recover the result without treating it as a new admission.
sequenceDiagram participant Scan as Scanner (designed, not built) box rgb(237,233,254) API Gateway participant GW as API Gateway (designed, not built) end participant Auth as JWT authorizer (designed, not built) participant Fn as Check-in Lambda (designed, not built) participant DB as tickets DynamoDB Scan->>GW: POST /check-ins with token and requestId GW->>Auth: Validate signature, claims and route scope Auth-->>GW: Verified identity GW->>Fn: Request and verified identity context Fn->>Fn: Validate ticket and authorize event Fn->>DB: Conditional UpdateItem with scan requestId DB-->>Fn: Won admission or condition failed Fn-->>GW: Structured result GW-->>Scan: Admission decisionLegend: proposed request sequence; the DynamoDB table exists in code, while the scanner endpoint and update behavior are designed, not built.
Under the hood
Section titled “Under the hood”API Gateway manages request handling and connections; it does not run our business logic by itself. The public API configuration and its backend integration are distinct resources. A deployed route can exist while its Lambda invocation permission or backend configuration is wrong.
| API type | Why choose it | Important distinction |
|---|---|---|
| REST API | API keys and usage plans, request validation, response caching, or other API management features | More features and configuration; compare current cost against HTTP APIs. |
| HTTP API | A simpler HTTP/Lambda API with native JWT authorization | No REST usage plans or gateway response cache. |
| WebSocket API | Persistent two-way messaging between clients and backend | Routes handle messages and connection lifecycle, rather than independent HTTP requests only. |
REST and HTTP are product names; both can expose REST-style endpoints. The AWS comparison lists exact feature support. A WebSocket connection lets a backend send later messages; the application still manages which connection may receive which event. AWS WebSocket overview
An HTTP API can integrate with Lambda, a reachable HTTP endpoint, supported AWS APIs, or private resources through a VPC link. A VPC link gives API Gateway network connectivity into a VPC. It does not replace backend permissions or application authentication. An AWS service integration can send a request to SQS without a pass-through Lambda when transformation and authorization requirements fit. AWS HTTP integrations
Authorization options solve different problems. IAM authorization requires a request signed with AWS credentials and permission such as execute-api:Invoke. A Lambda authorizer calls custom code to allow or deny a caller. Native HTTP API JWT authorizers validate tokens from compatible issuers, including Cognito. REST APIs support Cognito user-pool authorizers and Lambda authorizers; a custom Lambda authorizer can validate other JWTs. AWS authorizer types
Cognito is an identity service that can issue tokens; API Gateway does not issue a login token merely because a route uses JWT authorization. Configure the expected issuer and audience, meaning the token’s issuer and intended recipient. Require access-token scopes where appropriate so an ID token intended for login identity is not mistaken for API access. AWS JWT authorization
API keys identify clients for REST usage plans. A usage plan attaches best-effort request-rate and quota targets to those keys. Keys are not user authentication, and quotas are not exact billing caps. Throttling limits accepted traffic when request rates exceed configured targets; clients may see 429 Too Many Requests. AWS usage plans
Response caching and authorizer caching are different. REST response caching reuses backend answers; authorizer caching reuses an access decision. Cache keys determine which requests share a result. Never cache a state-changing check-in, and do not let one operator’s authorization result authorize another route or event unintentionally. AWS response caching, AWS authorizer caching
Limits and numbers
Section titled “Limits and numbers”At the time of writing; check the AWS docs. No API Gateway quota has been read from our live account because this service is explain-only here.
| Property | Current documented value | Source |
|---|---|---|
| HTTP API integration timeout | Maximum 30 seconds | AWS HTTP quotas |
| REST buffered integration timeout | Default maximum 29 seconds; increases available for Regional/private APIs, potentially reducing regional throttle quota | AWS REST quotas |
| WebSocket integration timeout | Maximum 29 seconds | AWS WebSocket quotas |
| HTTP API payload size | Maximum 10 MB | AWS HTTP quotas |
| Shared API request-rate quota | Default 10,000 requests/s in us-east-1, burst capacity 5,000; verify account quota | AWS account quotas |
| REST response-cache TTL | Default 300 seconds, maximum 3,600 seconds | AWS caching |
| REST response streaming | Supported proxy integrations can stream up to 15 minutes; separate idle timeouts apply | AWS response streaming |
The effective request limit also depends on the backend. A Lambda proxy request must fit Lambda’s synchronous invocation limit, including its event wrapper and any base64 expansion; a 10 MB gateway ceiling does not promise a 10 MB Lambda request. AWS Lambda payload limits.
Do not memorize “all API Gateway requests stop at 29 seconds.” API type, endpoint type, quota increases, and buffered versus streaming responses matter. REST now supports response streaming for HTTP_PROXY and AWS_PROXY integrations; HTTP APIs do not. Streaming can exceed the normal buffered response-size and duration limits but disables features that require the full response, including endpoint caching. AWS response streaming
In MiniTickets
Section titled “In MiniTickets”Explain-only: designed, not built. There are no API Gateway routes, Cognito user pools, API keys, usage plans, check-in authorizers, or check-in Lambda functions in our infrastructure.
The existing entry layer uses an Application Load Balancer, or ALB, which routes HTTP requests to container targets. infra/src/entry/https-listener.ts routes /trpc/* to the API target group and other paths to the web target group in ALB-only mode. infra/src/entry/target-groups.ts targets API port 4000 and web port 3000. The optional CloudFront mode has its separate listener configuration.
apps/api/src/app.ts mounts the Fastify tRPC adapter at /trpc. tRPC shares typed procedure contracts with our TypeScript web client. apps/api/src/trpc/context.ts reads the sid session cookie and looks up the session in Redis. apps/api/src/trpc/init.ts enforces login and reads current roles for admin procedures. A managed JWT authorizer would not understand this opaque cookie automatically.
ALB plus tRPC fits two existing container services and a browser client on the same origin. Adding API Gateway in front of every request would introduce another configuration and failure surface without eliminating those services. A separate HTTP API could make sense for short scanner requests, independent deployment, and token-based mobile clients. Existing tRPC could also implement check-in; API Gateway is a choice, not a requirement for safe admission.
Connections
Section titled “Connections”| Connection | What allows it | Boundary to keep |
|---|---|---|
| Proposed scanner → HTTP API | HTTPS and JWT authorizer with issuer, audience, route scopes | A valid token still needs event-specific authorization. |
| API Gateway → proposed Lambda | Function resource policy allowing apigateway.amazonaws.com to lambda:InvokeFunction, constrained by source API ARN | This does not grant the function datastore access. |
| Proposed Lambda → tickets table | New function role with the required dynamodb:GetItem / dynamodb:UpdateItem grants | Existing API role has Query only; do not silently reuse it. |
| Proposed Lambda → ticket-signing secret | New function role: secretsmanager:GetSecretValue on the existing signing secret | Our current ticket token uses HMAC, so verification needs that shared secret; a holder can also sign tokens. This proposed grant needs a deliberate trust decision; public-key verification would require a different token design. |
| Proposed HTTP API → private container | VPC link, supported integration target, network rules | A private integration is not the same as a private client-facing API. |
| Existing ALB → API task | /trpc/* listener rule and inbound TCP 4000 from ALB security group to API security group | That network rule does not authenticate the user. |
Lambda proxy event and response formats are documented in AWS HTTP Lambda integration; the invocation grant uses the function resource policy as shown in AWS invocation permissions. Private integration capabilities have evolved: REST VPC links V2 can now target ALBs; old advice that REST always needs an NLB is outdated. AWS REST private integrations
CORS means cross-origin resource sharing: browser rules controlling which origins may read responses. It is separate from authentication and does not restrict ordinary non-browser clients. HTTP APIs can answer preflight OPTIONS requests from configured CORS settings. Allow the scanner web origin and required headers; ensure preflight does not require the access token it is asking permission to send. AWS HTTP CORS
When it fails
Section titled “When it fails”flowchart TB request["Scanner request"] --> auth{"Authentication and route access"} auth -->|"Invalid token or denied scope"| reject["401 or 403; inspect authorizer result"] auth -->|"Allowed"| backend["Check-in Lambda"] backend -->|"Slow or response lost"| timeout["504 or client timeout"] timeout --> retry["Retry same scan requestId"] retry --> condition["Read prior result or conditionally admit"] class request,backend,retry app class request,backend,retry designed class auth security class auth designed class reject,timeout failure class condition service class condition designedLegend: proposed failure path; red = rejected or uncertain result; retry preserves the operation identity.
| What you see | Why | Fix |
|---|---|---|
401 Unauthorized or 403 Forbidden | Missing/expired token, wrong issuer/audience, denied route, or backend event denial | Compare the access log, token claims, route configuration, and application decision. Do not remove authorization to test success. |
429 Too Many Requests | Route, stage, usage-plan, or shared account throttling | Identify the applicable layer; apply client backoff and adjust capacity deliberately. |
500 before handler logs | API Gateway cannot invoke the function or its authorizer | Check Lambda resource policy, source ARN, integration target, and authorizer errors. |
502 Bad Gateway or malformed response error | Lambda proxy output does not match the configured payload format | Inspect safe error logs and return a supported response; test the actual event format. |
504 or client timeout after admission | Backend was slow or the response did not arrive | Recover using the same request ID; timeout does not prove the admission update failed. |
Enable structured access logs with route, request ID, status, integration status, and latency. Do not log complete tokens or QR contents. Compare Latency, the total gateway response time, with IntegrationLatency, backend waiting time, where available. That separates slow integration work from other request overhead. AWS API Gateway metrics
At 10x / 100x
Section titled “At 10x / 100x”At 10x, the bottleneck might be Lambda concurrency, an authorizer’s identity lookup, or a hot DynamoDB item. Set route throttles from backend capacity and expected latency. A gateway capable of accepting many requests can overload a smaller backend. Preserve enough capacity for other APIs sharing account quotas.
At 100x, arrival bursts and retries amplify each other. Use bounded retry with jitter, meaning a randomized delay, and show scanners a clear retryable state. Do not acknowledge “admitted” before the conditional update finishes. An asynchronous 202 Accepted means work was queued, which is insufficient to decide whether someone can enter now.
A venue outage creates a product decision: reject scans without connectivity or accept a defined offline risk. API Gateway cannot coordinate disconnected devices. Measure duplicate attempts, denied operators, backend latency, throttling, and unknown results, not just successful HTTP responses.
Common interview traps
Section titled “Common interview traps”- “An API key authenticates the operator.” It identifies a client for a usage plan. Use a real identity mechanism and event authorization.
- “JWT verification means this ticket is valid.” The operator token and the ticket token represent different things. Verify both and check business state.
- “A 504 means nothing happened.” The backend may have committed. Retry the same operation identity.
- “CORS prevents unauthorized API calls.” It controls browser access to responses; scripts and other clients can still call the endpoint.
- “The stage creates a separate backend database.” A stage selects deployment configuration. Separate data and roles must be configured explicitly.
Design question
Section titled “Design question”Design a scanner endpoint for two entrances that may scan the same QR code simultaneously.
Use a short HTTP API request with a JWT authorizer for operator identity. The handler checks event access and ticket signature, then conditionally records admission and the scan request ID in DynamoDB. Return success only to the winning request. A retry of that request retrieves the stored result; a different scan receives already checked in. Keep authorization changes timely rather than hiding event access in a long-lived cached allow decision.
flowchart TB a["Entrance A scanner (designed, not built)"] --> gw["HTTP API and JWT authorization (designed, not built)"] b["Entrance B scanner (designed, not built)"] --> gw gw --> fn["Authorize event and verify ticket (designed, not built)"] fn --> db["Conditional check-in update (designed, not built)"] db -->|"Winning requestId"| ok["Admit"] db -->|"Different requestId"| no["Already checked in"] class a,b,fn app class a,b,fn designed class gw service class gw designed class db aws class db designed class ok aws class no failureLegend: all check-in behavior is designed, not built; one conditional update resolves simultaneous scans.
HTTP API is sufficient unless REST-only management features are requirements. A WebSocket API is useful for later pushed updates, not necessary for one scan and response. If the main app stays on ALB, keep this endpoint’s identity, deployment, and operational costs explicit rather than migrating unrelated traffic.
Say it in an interview
Section titled “Say it in an interview”Follow-ups
Section titled “Follow-ups”Why not use an API key as scanner authentication?
What changes for a WebSocket API?
Can API Gateway call SQS without Lambda?
How do stages affect deployment?
Why keep ALB plus tRPC?
Remember it
Section titled “Remember it”- Choose REST, HTTP, or WebSocket from the features the client actually needs.
- Authorizers establish request identity and access; handlers enforce business rules.
- API keys and usage plans are not authentication or exact spending limits.
- A timeout leaves the operation outcome uncertain; preserve the same request ID.
- MiniTickets uses ALB and tRPC today; API Gateway check-in is designed, not built.
Advanced
Section titled “Advanced”Advanced: Stages, WebSocket authorization, and read-only inspection
Console: API Gateway → selected API → Routes or Resources → integration and authorization; then Stages → deployment, logs, throttling. Verify the invoked stage and actual Lambda version before blaming application code.
aws apigatewayv2 get-apis --region us-east-1aws apigateway get-rest-apis --region us-east-1aws apigatewayv2 get-stages --api-id "$API_ID" --region us-east-1aws apigatewayv2 get-routes --api-id "$API_ID" --region us-east-1These inspect existing APIs. They do not create the proposed endpoint, and this repository supplies no API ID. HTTP API stages may use automatic deployment; REST stages point to deployment snapshots. AWS HTTP stages, AWS REST deployments
For WebSocket APIs, Lambda authorizers run only on $connect. Changing authorization does not retroactively validate every connected message. The backend must enforce message access, handle token expiry and revoked access, and remove stale connection records. AWS WebSocket authorization
For a Lambda authorizer, choose cache identity sources carefully. If a cached response applies to only one route or event, include that distinction in the cache key or return a policy that is correct for every request sharing the key. Backend authorization remains useful when event membership changes faster than token or cache expiry.
With HTTP API’s $default route and an authorizer, configure unauthenticated preflight handling deliberately. Cross-origin cookie requests also need an exact allowed origin and credentials support; do not assume a wildcard origin is sufficient.
Checkpoint
Section titled “Checkpoint”Answer these without scrolling up. If one feels hard, reread that section.
- Which required feature would make you choose REST over HTTP API?
- Which permission lets API Gateway invoke Lambda, and whose role accesses DynamoDB?
- Why must the handler check event access after the JWT is valid?
- What should a scanner retry after a timeout following a possible successful admission?
- Why does a second API stage not automatically isolate production data?
Redraw it from memory: the scanner, API Gateway, authorizer, Lambda and conditional DynamoDB update
Try this: compare the current sid-cookie context with the claims a proposed JWT integration would supply
Read this book online: https://book.theversehub.in/