Claude Code × AWS API Gateway Guía Completa | Diseño REST API hasta Automatización de Despliegue
Automatiza el diseño de endpoints de AWS API Gateway con Claude Code. Diseño de recursos, integración Lambda, autenticación y despliegue — con código real de la experiencia profesional de Masa.
Cómo el tiempo de diseño de API Gateway se redujo a un tercio
Soy Masa, administro claudecode-lab.com. Cuando trabajaba como desarrollador backend freelance, el diseño e implementación de AWS API Gateway encabezaba la lista de “tareas tediosas y que consumen tiempo”. Escribir documentos de especificación de endpoints, traducirlos a CloudFormation, conectar integraciones Lambda manualmente, configurar CORS — y cometer los mismos errores una y otra vez.
El punto de inflexión llegó hace unos seis meses, cuando pedí a Claude Code: “Diseña una REST API basada en este caso de uso e impleméntala en CDK.” El resultado fue sorprendentemente listo para producción, y desde entonces el tiempo de implementación de API Gateway se ha reducido a un tercio.
Errores de CORS, errores de permisos de Lambda, la trampa del timeout de 29 segundos — desde que Claude Code detecta estos problemas con anticipación, los hallazgos de revisión también han caído drásticamente.
Por qué Claude Code destaca en el diseño de API Gateway
El diseño de API Gateway tiene una característica distintiva: no requiere conocimientos profundos, pero implica mucho boilerplate repetitivo.
- Convenciones de nomenclatura de endpoints (sustantivos en plural, estructura jerárquica)
- Selección de métodos HTTP (GET/POST/PUT/PATCH/DELETE)
- Definiciones de esquemas de request/response
- Mapeo de variables de ruta en integración Lambda
- Configuración de encabezados CORS (siempre olvidando algo)
- Gestión de variables de stage (dev/staging/prod)
Paso 1: Delegando el diseño de endpoints REST API a Claude Code
Ejemplo de Prompt
Crea una especificación de endpoints de REST API basada en los siguientes casos de uso.
Casos de uso:
- App de gestión de tareas (usuarios gestionan proyectos y tareas)
- Autenticación de usuario requerida (Cognito)
- Los proyectos pueden tener miembros
- Las tareas soportan comentarios y archivos adjuntos
Formato de salida:
- Lista de endpoints (método, ruta, descripción)
- Esquemas JSON de request/response
- Marcar endpoints que requieren autenticación
- Señalar violaciones de principios REST
Paso 2: Auto-generando configuración de integración Lambda
Stack CDK generado (extracto)
import * as cdk from "aws-cdk-lib";
import * as apigateway from "aws-cdk-lib/aws-apigateway";
import * as nodejs from "aws-cdk-lib/aws-lambda-nodejs";
import * as lambda from "aws-cdk-lib/aws-lambda";
import { Construct } from "constructs";
export class TaskApiStack extends cdk.Stack {
public readonly api: apigateway.RestApi;
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// ===== Factory de funciones Lambda =====
const createLambda = (name: string, handler: string) =>
new nodejs.NodejsFunction(this, name, {
entry: `src/handlers/${handler}.ts`,
handler: "handler",
runtime: lambda.Runtime.NODEJS_20_X,
timeout: cdk.Duration.seconds(29), // Timeout máximo de API Gateway
memorySize: 256,
bundling: {
minify: true,
sourceMap: true,
externalModules: ["@aws-sdk/*"],
},
});
const listProjectsFn = createLambda("ListProjects", "projects/list");
const createProjectFn = createLambda("CreateProject", "projects/create");
const getProjectFn = createLambda("GetProject", "projects/get");
const updateProjectFn = createLambda("UpdateProject", "projects/update");
const deleteProjectFn = createLambda("DeleteProject", "projects/delete");
// ===== Definición de REST API =====
this.api = new apigateway.RestApi(this, "TaskApi", {
restApiName: "task-management-api",
defaultCorsPreflightOptions: {
allowOrigins: apigateway.Cors.ALL_ORIGINS, // restringir en producción
allowMethods: apigateway.Cors.ALL_METHODS,
allowHeaders: ["Content-Type", "Authorization", "X-Api-Key"],
},
deployOptions: {
stageName: "v1",
loggingLevel: apigateway.MethodLoggingLevel.INFO,
dataTraceEnabled: false,
},
});
// ===== Recursos y métodos =====
const projects = this.api.root.addResource("projects");
projects.addMethod("GET", new apigateway.LambdaIntegration(listProjectsFn));
projects.addMethod("POST", new apigateway.LambdaIntegration(createProjectFn));
const project = projects.addResource("{id}");
project.addMethod("GET", new apigateway.LambdaIntegration(getProjectFn));
project.addMethod("PUT", new apigateway.LambdaIntegration(updateProjectFn));
project.addMethod("DELETE", new apigateway.LambdaIntegration(deleteProjectFn));
new cdk.CfnOutput(this, "ApiUrl", {
value: this.api.url,
description: "URL de API Gateway",
});
}
}
Paso 3: Autenticación (Cognito / Lambda Authorizer / API Key)
Patrón 1: Cognito User Pool Authorizer (BtoC)
import * as cognito from "aws-cdk-lib/aws-cognito";
const userPool = new cognito.UserPool(this, "UserPool", {
userPoolName: "task-app-users",
selfSignUpEnabled: true,
signInAliases: { email: true },
passwordPolicy: {
minLength: 8,
requireLowercase: true,
requireUppercase: true,
requireDigits: true,
},
});
const cognitoAuthorizer = new apigateway.CognitoUserPoolsAuthorizer(
this,
"CognitoAuthorizer",
{
cognitoUserPools: [userPool],
identitySource: "method.request.header.Authorization",
resultsCacheTtl: cdk.Duration.minutes(5),
}
);
projects.addMethod("GET", new apigateway.LambdaIntegration(listProjectsFn), {
authorizer: cognitoAuthorizer,
authorizationType: apigateway.AuthorizationType.COGNITO,
});
Patrón 2: Lambda Authorizer
// src/handlers/auth/authorizer.ts
import {
APIGatewayAuthorizerResult,
APIGatewayTokenAuthorizerHandler,
} from "aws-lambda";
import * as jwt from "jsonwebtoken";
export const handler: APIGatewayTokenAuthorizerHandler = async (event) => {
const token = event.authorizationToken.replace("Bearer ", "");
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET!) as {
sub: string;
email: string;
role: string;
};
return generatePolicy(decoded.sub, "Allow", event.methodArn, {
userId: decoded.sub,
email: decoded.email,
role: decoded.role,
});
} catch {
throw new Error("Unauthorized");
}
};
function generatePolicy(
principalId: string,
effect: "Allow" | "Deny",
resource: string,
context?: Record<string, string>
): APIGatewayAuthorizerResult {
return {
principalId,
policyDocument: {
Version: "2012-10-17",
Statement: [
{
Action: "execute-api:Invoke",
Effect: effect,
Resource: resource.replace(/\/[^/]+\/[^/]+$/, "/*/*"),
},
],
},
context,
};
}
Paso 4: Gestión de Stages (dev/staging/prod)
// lib/config.ts
export type Stage = "dev" | "staging" | "prod";
export const stageConfig: Record<Stage, {
throttleRateLimit: number;
corsOrigins: string[];
enableDataTrace: boolean;
}> = {
dev: {
throttleRateLimit: 10,
corsOrigins: ["http://localhost:3000"],
enableDataTrace: true,
},
staging: {
throttleRateLimit: 50,
corsOrigins: ["https://staging.example.com"],
enableDataTrace: false,
},
prod: {
throttleRateLimit: 1000,
corsOrigins: ["https://example.com"],
enableDataTrace: false,
},
};
# Desplegar a desarrollo
CDK_ENV=dev npx cdk deploy Api-dev --require-approval never
# Staging
CDK_ENV=staging npx cdk deploy Api-staging
# Producción (con confirmación)
CDK_ENV=prod npx cdk deploy Api-prod
4 Errores Comunes
Error 1: Configuración CORS faltante (el más frecuente)
Síntoma: fetch() en el navegador lanza error CORS. Postman funciona bien.
// ❌ Insuficiente
defaultCorsPreflightOptions: {
allowOrigins: apigateway.Cors.ALL_ORIGINS,
}
// ✅ Siempre agregar encabezados CORS en respuestas Lambda
return {
statusCode: 200,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "https://example.com",
"Access-Control-Allow-Credentials": "true",
},
body: JSON.stringify(data),
};
Error 2: Permiso de invocación Lambda faltante
listProjectsFn.addPermission("ApiGatewayInvoke", {
principal: new iam.ServicePrincipal("apigateway.amazonaws.com"),
sourceArn: this.api.arnForExecuteApi("GET", "/projects", "v1"),
});
Error 3: El límite de timeout de 29 segundos
// ✅ Patrón asíncrono: devolver job ID inmediatamente
export const startExport: APIGatewayProxyHandler = async (event) => {
const jobId = crypto.randomUUID();
await sqsClient.send(
new SendMessageCommand({
QueueUrl: process.env.JOB_QUEUE_URL!,
MessageBody: JSON.stringify({ jobId, params: JSON.parse(event.body!) }),
})
);
return {
statusCode: 202,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jobId, status: "processing" }),
};
};
Error 4: Cuerpo de request faltante en Lambda
// ✅ Siempre establecer proxy: true explícitamente
project.addMethod(
"POST",
new apigateway.LambdaIntegration(createProjectFn, {
proxy: true,
})
);
Resumen
| Tarea | Valor de Claude Code | Dificultad |
|---|---|---|
| Diseño REST API | Auto-generar specs, verificar principios REST | Baja |
| Lambda Integration CDK | Generar integración proxy + definiciones de recursos | Baja |
| Auth Cognito | Generar User Pool, Authorizer, config de cliente | Media |
| Lambda Authorizer | Implementar validación JWT + generación de policy | Media |
| Gestión de stages | Separar configs de env, generar comandos de despliegue | Media |
| Procesamiento asíncrono | Diseñar integración SQS + patrón de polling | Alta |
Resultado práctico: tiempo de diseño API Gateway-to-CDK-deploy reducido de 3 días a 1 día. La configuración de Cognito Authorizer, que antes requería más de una hora leyendo documentación de AWS, ahora se resuelve con un único prompt de Claude Code.
Artículos Relacionados
- Claude Code × AWS Lambda Guía Completa
- Claude Code × Diseño REST API en Práctica
- Claude Code × Guía de Diseño IAM de AWS
Referencias
Lleva tu flujo con Claude Code al siguiente nivel
50 plantillas de prompts probadas en producción, listas para copiar y pegar en Claude Code.
PDF gratuito: Hoja de trucos de Claude Code en 5 minutos
Solo deja tu correo y te enviaremos al instante la hoja de trucos en una página A4.
Cuidamos tus datos personales y nunca enviamos spam.
Sobre el autor
Masa
Ingeniero apasionado por Claude Code. Dirige claudecode-lab.com, un medio tecnológico en 10 idiomas con más de 2.000 páginas.
Artículos relacionados
Claude Code × Amazon Bedrock Guía Completa | Ejecutar Claude en Producción con AWS
Guía completa para usar Amazon Bedrock con Claude Code. Desde autenticación IAM, streaming, integración con Lambda, implementación RAG hasta optimización de costos, basada en la experiencia real de producción de Masa.
Claude Code × AWS CodePipeline/CodeBuild Guía Completa | Construcción automática de pipelines CI/CD
Construye automáticamente CI/CD con AWS CodePipeline y CodeBuild usando Claude Code. Ejemplos reales de diseño de pipelines, generación de buildspec.yml, automatización de pruebas e infraestructura CDK.
Claude Code × AWS CloudWatch Guía Completa | Análisis de Logs, Alarmas y Dashboards Automáticos
Optimiza AWS CloudWatch con Claude Code. Código práctico para análisis de patrones de logs, configuración automática de alarmas, dashboards de métricas e investigación de incidentes.