API Gateway plus Lambda is the classic serverless web back end, and its limits and auth options shape API design.
Amazon API Gateway offers three API types:
- HTTP APIs: simpler, cheaper and lower latency. Routes like
GET /orders/{id}, Lambda and HTTP integrations, JWT authorizers (Cognito or any OIDC provider), Lambda authorizers, CORS and custom domains. The default choice. - REST APIs: the older, feature-rich type, adding request validation, API keys with usage plans, caching, WAF integration, private APIs and request/response transformations.
- WebSocket APIs for bidirectional, long-lived connections.
With Lambda proxy integration the whole request (method, path, headers, query string, body, and authorizer claims under requestContext) arrives as the event, and your function returns statusCode, headers and a string body. HTTP APIs use payload format 2.0, where the method is at event["requestContext"]["http"]["method"].
API Gateway needs permission to invoke the function: a resource-based policy statement on the Lambda added with aws lambda add-permission. Quick-create APIs from the CLI or console add it for you only in some flows, so check when you get 500s with no function logs.
Limits to design around: integrations time out after roughly 30 seconds (29 s by default on REST APIs), payloads are capped at 10 MB, and account-level throttling applies per Region (with per-route limits you can set). Long work should be queued and polled, not held open.
API keys identify clients for usage plans; they are not authentication. Use IAM, JWT or Lambda authorizers. For a single function that just needs a URL, Lambda function URLs are simpler still.
Example
FN=arn:aws:lambda:eu-west-1:111122223333:function:hello
# Quick create: HTTP API + default route + Lambda integration + $default stage
API=$(aws apigatewayv2 create-api --name hello-api --protocol-type HTTP \
--target "$FN" --query ApiId --output text)
# Allow API Gateway to invoke the function
aws lambda add-permission --function-name hello --statement-id apigw-invoke \
--action lambda:InvokeFunction --principal apigateway.amazonaws.com \
--source-arn "arn:aws:execute-api:eu-west-1:111122223333:$API/*"
curl "https://$API.execute-api.eu-west-1.amazonaws.com/?name=Ada"
# {"hello": "Ada", "invocation": 1}
# Require a valid JWT from a Cognito user pool
aws apigatewayv2 create-authorizer --api-id "$API" --name cognito \
--authorizer-type JWT --identity-source '$request.header.Authorization' \
--jwt-configuration Audience=3n4b5c6d7e8f,Issuer=https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_AbCdEf123Remember
- HTTP APIs are the default; REST APIs add validation, caching, usage plans
- Lambda proxy: the request is the event; return statusCode, headers, body
- Lambda needs a resource policy allowing API Gateway to invoke it
- About 30 s integration timeout and 10 MB payloads; API keys are not auth
Watch out for
- Using API keys as the only protection for an API.