Claude Code y AWS API Gateway: HTTP API con SAM, CORS, logs, autenticación y límites
Implementa AWS API Gateway con Claude Code, SAM, CORS, logs, auth y throttling con ejemplos reales.
API Gateway es la puerta de entrada de tu API
AWS API Gateway es la capa que recibe las peticiones públicas y concentra autenticación, límites, registros y conexión con el backend. Un navegador, una app móvil o un sistema externo llama a una URL. API Gateway decide qué ruta es, si la petición puede pasar, cómo se registra y si termina en Lambda, en un servidor HTTP o en otro servicio de AWS.
Esta idea es importante cuando trabajas con Claude Code. Si el prompt solo dice “crea una API”, puede generar una Lambda que responde bien en una demo, pero dejar sin resolver CORS, authorizers, logs de acceso, nombres de stage, límites de tasa o incluso la elección entre REST API y HTTP API. El código parece funcionar, pero el primer frontend real o el primer incidente de producción dejan claro que faltaba diseño.
Aquí usamos la documentación oficial de AWS como base y construimos un ejemplo con AWS SAM. El objetivo no es memorizar todas las opciones, sino aprender una forma de pedirle a Claude Code que genere y revise una API que se pueda operar.
Elegir entre REST API, HTTP API y WebSocket API
API Gateway ofrece principalmente REST APIs, HTTP APIs y WebSocket APIs. AWS lo describe como un servicio para crear, publicar y administrar APIs que conectan clientes con Lambda, endpoints HTTP o servicios de AWS.
| Tipo | Uso habitual | Regla práctica |
|---|---|---|
| HTTP API | APIs JSON para SPA, móviles y Lambda | Empieza aquí si necesitas bajo coste, baja latencia, JWT, CORS, logs y rutas simples |
| REST API | Gestión avanzada de APIs | Úsala si necesitas API keys, usage plans, validación de requests, WAF, endpoints privados o controles por cliente |
| WebSocket API | Comunicación bidireccional | Úsala para chat, notificaciones, progreso en tiempo real o eventos enviados desde servidor |
La comparación oficial de AWS deja claro que REST API tiene más funciones y HTTP API está pensada para un conjunto más pequeño de capacidades con menor precio. Por eso, para un formulario, un webhook o una API Lambda sencilla, HTTP API suele ser el punto de partida. Si aparecen API keys, planes por cliente o WAF, entonces REST API vuelve a la mesa.
Referencias oficiales:
- Amazon API Gateway concepts
- Choose between REST APIs and HTTP APIs
- WebSocket APIs
- AWS SAM AWS::Serverless::HttpApi
Casos de uso que conviene diseñar antes del código
El primer caso es la integración con Lambda. Un formulario de contacto, una reserva, un webhook de SaaS o una pequeña API interna puede entrar por API Gateway y pasar a Lambda después de una validación básica. La puerta pública queda en API Gateway; la lógica de negocio queda en Lambda.
El segundo caso es CORS. Si el frontend está en https://example.com y la API en un dominio execute-api, el navegador lo considera otro origen. AWS documenta que, cuando configuras CORS en HTTP API, API Gateway responde a la petición preflight OPTIONS. También explica que, si CORS está configurado en la API, puede ignorar cabeceras CORS devueltas por el backend. Por eso no basta con escribir cabeceras en Lambda; el diseño principal debe estar en API Gateway.
El tercer caso es autenticación. JWT authorizer encaja para usuarios finales que llegan desde Cognito u otro proveedor OIDC. IAM authorization encaja para llamadas entre workloads de AWS con firma SigV4 y permiso execute-api. Lambda authorizer sirve cuando hay reglas propias: base de datos heredada, contratos por partner, listas IP o permisos muy específicos.
El cuarto caso es observabilidad y protección. Los logs de acceso en CloudWatch deben incluir requestId, routeKey, estado, IP y hora. El throttling de API Gateway usa una lógica de bucket y puede devolver 429 Too Many Requests; AWS lo trata como objetivo de protección, no como única barrera absoluta. El backend también debe tener límites.
Ejemplo SAM listo para copiar
Crea template.yaml.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Claude Code Lab HTTP API sample with CORS, logs, throttling, and Lambda proxy
Parameters:
StageName:
Type: String
Default: Prod
AllowedOrigin:
Type: String
Default: https://example.com
Globals:
Function:
Runtime: nodejs20.x
Architectures:
- arm64
Timeout: 10
MemorySize: 256
Resources:
ApiAccessLogs:
Type: AWS::Logs::LogGroup
Properties:
RetentionInDays: 14
PublicHttpApi:
Type: AWS::Serverless::HttpApi
Properties:
StageName: !Ref StageName
CorsConfiguration:
AllowOrigins:
- !Ref AllowedOrigin
AllowHeaders:
- authorization
- content-type
- x-request-id
AllowMethods:
- GET
- POST
- OPTIONS
MaxAge: 300
AccessLogSettings:
DestinationArn: !GetAtt ApiAccessLogs.Arn
Format: '{"requestId":"$context.requestId","routeKey":"$context.routeKey","status":"$context.status","ip":"$context.identity.sourceIp","requestTime":"$context.requestTime","responseLength":"$context.responseLength"}'
DefaultRouteSettings:
ThrottlingBurstLimit: 20
ThrottlingRateLimit: 10
RouteSettings:
"POST /contacts":
ThrottlingBurstLimit: 5
ThrottlingRateLimit: 2
FailOnWarnings: true
HealthFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handler.health
Events:
Health:
Type: HttpApi
Properties:
ApiId: !Ref PublicHttpApi
Path: /health
Method: GET
PayloadFormatVersion: "2.0"
ContactFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handler.contact
Events:
Contact:
Type: HttpApi
Properties:
ApiId: !Ref PublicHttpApi
Path: /contacts
Method: POST
PayloadFormatVersion: "2.0"
TimeoutInMillis: 10000
Outputs:
ApiUrl:
Description: Invoke URL
Value: !Sub "https://${PublicHttpApi}.execute-api.${AWS::Region}.${AWS::URLSuffix}/${StageName}/"
Crea package.json y src/handler.js.
{
"type": "module",
"scripts": {
"check": "node --check src/handler.js"
}
}
const json = (statusCode, body) => ({
statusCode,
headers: { "content-type": "application/json" },
body: JSON.stringify(body)
});
export const health = async () => json(200, {
ok: true,
service: "claude-code-api-gateway",
checkedAt: new Date().toISOString()
});
export const contact = async (event) => {
let payload;
try {
payload = JSON.parse(event.body ?? "{}");
} catch {
return json(400, { message: "Request body must be valid JSON." });
}
const name = String(payload.name ?? "").trim();
const email = String(payload.email ?? "").trim();
if (!name || !email.includes("@")) {
return json(422, { message: "name and a valid email are required." });
}
return json(202, {
message: "accepted",
requestId: event.requestContext?.requestId,
received: { name, email }
});
};
Ejecuta:
npm run check
sam build
sam deploy --guided \
--stack-name clc-api-gateway-sample \
--parameter-overrides AllowedOrigin=https://example.com
Prompt de revisión para Claude Code
Revisa este template AWS SAM antes de producción.
Busca rutas públicas, CORS demasiado amplio, ausencia de JWT/IAM/Lambda authorizer,
logs sin requestId o routeKey, throttling débil, errores de Lambda poco seguros
y requisitos que obliguen a usar REST API en vez de HTTP API.
Devuelve cambios concretos en el template.
Este prompt funciona porque no pide “más código”, sino una revisión de riesgos. En API Gateway eso es más valioso: una ruta pública por error, un origen * o logs incompletos pueden costar más que una función Lambda mal formateada.
Errores frecuentes
El primero es confiar solo en CORS dentro de Lambda. En HTTP API, CORS debe revisarse en la capa de API Gateway.
El segundo es activar logs tarde. Sin access logs, muchos 403, 404 o 429 ocurren antes de Lambda y quedan difíciles de rastrear.
El tercero es creer que throttling es una pared perfecta. Debe combinarse con límites de Lambda, base de datos y reintentos con backoff.
El cuarto es elegir el tipo de API por costumbre. HTTP API no reemplaza todos los casos de REST API; REST API tampoco debería ser la primera opción para cada formulario simple.
Para profundizar, lee Claude Code AWS Lambda, Claude Code AWS CloudWatch y Claude Code AWS IAM. También reunimos materiales prácticos en la página de formación.
Lo que Masa probó
Masa probó este flujo separando diseño, template, Lambda y revisión. Los hallazgos útiles fueron concretos: la ruta POST /contacts necesitaba límites más estrictos que /health, los logs debían incluir requestId y routeKey, y las rutas públicas debían marcarse como estado temporal. Empezar por API Gateway hizo que la implementación de Lambda fuera más limpia.
PDF gratis: cheatsheet de Claude Code
Introduce tu email y descarga una hoja con comandos, hábitos de revisión y flujos seguros.
Cuidamos tus datos y no enviamos spam.
Sobre el autor
Masa
Ingeniero enfocado en workflows prácticos con Claude Code.
Artículos relacionados
Workflow de Obsidian a CLAUDE.md con Claude Code
Convierte notas de trabajo de Obsidian en notas operativas de CLAUDE.md para no repetir contexto.
Claude Code Revenue CTA Routing: de artículos a PDF, Gumroad y consulta
Un flujo con Claude Code para dirigir lectores a PDF gratis, Gumroad o consulta según intención.
Reglas de handoff para equipos con Claude Code: evidencia, permisos, rollback e ingresos
Formato práctico para entregar trabajo de Claude Code con pruebas, permisos, rollback, PDF gratis, Gumroad y consulta.