Claude Code × AWS API Gateway Komplettleitfaden | REST API Design bis Deployment-Automatisierung
AWS API Gateway-Endpunkte automatisch mit Claude Code entwerfen. Ressourcendesign, Lambda-Integration, Authentifizierung und Deployment — mit echtem Code aus Masas Berufserfahrung.
Wie der API Gateway-Aufwand auf ein Drittel sank
Ich bin Masa und betreibe claudecode-lab.com. Als ich noch als freiberuflicher Backend-Entwickler tätig war, stand AWS API Gateway-Design und -Implementierung ganz oben auf der Liste der „mühsamen, zeitaufwändigen Aufgaben”. Endpunkt-Spezifikationen schreiben, in CloudFormation übersetzen, Lambda-Integrationen manuell verdrahten, CORS konfigurieren — und dabei immer wieder dieselben Fehler machen.
Der Wendepunkt kam vor etwa sechs Monaten, als ich Claude Code bat: „Entwirf eine REST API basierend auf diesem Use Case und implementiere sie in CDK.” Das Ergebnis war überraschend produktionsreif, und seitdem hat sich der Implementierungsaufwand für API Gateway auf ein Drittel reduziert.
CORS-Vergessen, Lambda-Berechtigungsfehler, die 29-Sekunden-Timeout-Falle — seit Claude Code diese Probleme frühzeitig abfängt, sind auch die Review-Befunde drastisch gesunken.
Dieser Artikel zeigt jeden Claude Code × API Gateway-Pattern, den ich tatsächlich in professionellen Projekten einsetze, Schritt für Schritt.
Warum Claude Code beim API Gateway-Design glänzt
API Gateway-Design hat eine besondere Eigenschaft: Es erfordert keine Tiefenkenntnisse, aber viel repetitiven Boilerplate.
- Endpunkt-Namenskonventionen (Plural-Substantive, Hierarchiestruktur)
- HTTP-Methodenauswahl (GET/POST/PUT/PATCH/DELETE)
- Request-/Response-Schema-Definitionen
- Lambda-Integration Pfadvariablen-Mapping
- CORS-Header-Konfiguration (immer vergessen)
- Stage-Variablen-Verwaltung (dev/staging/prod)
Diese folgen klaren Regeln. Jeder kann sie mit Dokumentation schreiben, aber Claude Code zu bitten „Entwirf eine REST API für diesen Use Case und schreibe sie in CDK” liefert in Minuten eine vollständige Implementierung.
Besonders stark ist Claude Code beim Design-Konsistenz-Check. „Weise auf REST-Prinzip-Verletzungen in diesem Endpunkt-Design hin” — und es flaggt sofort Idempotenz-Probleme, URL-Inkonsistenzen und mehr.
Schritt 1: REST API Endpunkt-Design an Claude Code delegieren
Bevor eine einzige Zeile Code geschrieben wird, übernimmt Claude Code das Endpunkt-Design.
Beispiel-Prompt
Erstelle eine REST API-Endpunkt-Spezifikation basierend auf folgenden Use Cases.
Use Cases:
- Task-Management-App (Benutzer verwalten Projekte und Aufgaben)
- Benutzerauthentifizierung erforderlich (Cognito)
- Projekte können Mitglieder haben
- Aufgaben unterstützen Kommentare und Dateianhänge
Ausgabeformat:
- Endpunktliste (Methode, Pfad, Beschreibung)
- Request-/Response-JSON-Schemas
- Kennzeichnung authentifizierungspflichtiger Endpunkte
- REST-Prinzip-Verletzungen markieren
Generiertes Endpunkt-Design
# Task-Management API Endpunkt-Design
## Authentifizierung
POST /auth/login - Anmelden (öffentlich)
POST /auth/refresh - Token aktualisieren (öffentlich)
DELETE /auth/logout - Abmelden (Auth erforderlich)
## Projekte
GET /projects - Projektliste (Auth erforderlich)
POST /projects - Projekt erstellen (Auth erforderlich)
GET /projects/{id} - Projektdetail (Auth erforderlich)
PUT /projects/{id} - Projekt aktualisieren (Auth erforderlich)
DELETE /projects/{id} - Projekt löschen (Auth erforderlich)
## Projektmitglieder
GET /projects/{id}/members - Mitgliederliste
POST /projects/{id}/members - Mitglied hinzufügen
DELETE /projects/{id}/members/{uid} - Mitglied entfernen
## Aufgaben
GET /projects/{id}/tasks - Aufgabenliste
POST /projects/{id}/tasks - Aufgabe erstellen
GET /tasks/{taskId} - Aufgabendetail
PUT /tasks/{taskId} - Aufgabe aktualisieren
DELETE /tasks/{taskId} - Aufgabe löschen
## Kommentare
GET /tasks/{taskId}/comments - Kommentarliste
POST /tasks/{taskId}/comments - Kommentar erstellen
DELETE /tasks/{taskId}/comments/{commentId} - Kommentar löschen
## Anhänge
POST /tasks/{taskId}/attachments - Presigned URL abrufen (für direkten S3-Upload)
GET /tasks/{taskId}/attachments - Anhängeliste
DELETE /tasks/{taskId}/attachments/{attachmentId} - Anhang löschen
Schritt 2: Lambda-Integrationskonfiguration automatisch generieren
CDK-Stack (Auszug)
import * as cdk from "aws-cdk-lib";
import * as apigateway from "aws-cdk-lib/aws-apigateway";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as nodejs from "aws-cdk-lib/aws-lambda-nodejs";
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);
// ===== Lambda-Funktions-Factory =====
const createLambda = (name: string, handler: string) =>
new nodejs.NodejsFunction(this, name, {
entry: `src/handlers/${handler}.ts`,
handler: "handler",
runtime: lambda.Runtime.NODEJS_20_X,
environment: {
STAGE: props?.env?.region ?? "dev",
},
timeout: cdk.Duration.seconds(29), // API Gateway max. Timeout
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");
const listTasksFn = createLambda("ListTasks", "tasks/list");
const createTaskFn = createLambda("CreateTask", "tasks/create");
const getTaskFn = createLambda("GetTask", "tasks/get");
const updateTaskFn = createLambda("UpdateTask", "tasks/update");
const deleteTaskFn = createLambda("DeleteTask", "tasks/delete");
// ===== REST API-Definition =====
this.api = new apigateway.RestApi(this, "TaskApi", {
restApiName: "task-management-api",
description: "Task Management REST API",
defaultCorsPreflightOptions: {
allowOrigins: apigateway.Cors.ALL_ORIGINS, // in Produktion einschränken
allowMethods: apigateway.Cors.ALL_METHODS,
allowHeaders: ["Content-Type", "Authorization", "X-Api-Key"],
},
deployOptions: {
stageName: "v1",
accessLogDestination: new apigateway.LogGroupLogDestination(
new cdk.aws_logs.LogGroup(this, "ApiAccessLog", {
retention: cdk.aws_logs.RetentionDays.ONE_MONTH,
})
),
loggingLevel: apigateway.MethodLoggingLevel.INFO,
dataTraceEnabled: false,
},
});
// ===== Ressourcen & Methoden =====
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));
const projectTasks = project.addResource("tasks");
projectTasks.addMethod("GET", new apigateway.LambdaIntegration(listTasksFn));
projectTasks.addMethod("POST", new apigateway.LambdaIntegration(createTaskFn));
const tasks = this.api.root.addResource("tasks");
const task = tasks.addResource("{taskId}");
task.addMethod("GET", new apigateway.LambdaIntegration(getTaskFn));
task.addMethod("PUT", new apigateway.LambdaIntegration(updateTaskFn));
task.addMethod("DELETE", new apigateway.LambdaIntegration(deleteTaskFn));
new cdk.CfnOutput(this, "ApiUrl", {
value: this.api.url,
description: "API Gateway URL",
});
}
}
Schritt 3: Authentifizierung (Cognito / Lambda Authorizer / API Key)
Muster 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,
requireSymbols: false,
},
accountRecovery: cognito.AccountRecovery.EMAIL_ONLY,
});
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,
});
Muster 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,
};
}
Schritt 4: CDK-Infrastruktur-Implementierung
Stage-Konfigurationstrennung
// lib/config.ts
export type Stage = "dev" | "staging" | "prod";
export const stageConfig: Record<Stage, {
logLevel: "ERROR" | "INFO" | "DEBUG";
throttleRateLimit: number;
throttleBurstLimit: number;
corsOrigins: string[];
enableDataTrace: boolean;
}> = {
dev: {
logLevel: "DEBUG",
throttleRateLimit: 10,
throttleBurstLimit: 20,
corsOrigins: ["http://localhost:3000"],
enableDataTrace: true,
},
staging: {
logLevel: "INFO",
throttleRateLimit: 50,
throttleBurstLimit: 100,
corsOrigins: ["https://staging.example.com"],
enableDataTrace: false,
},
prod: {
logLevel: "ERROR",
throttleRateLimit: 1000,
throttleBurstLimit: 2000,
corsOrigins: ["https://example.com"],
enableDataTrace: false,
},
};
Deployment-Befehle
# Entwicklungsumgebung
CDK_ENV=dev npx cdk deploy Api-dev --require-approval never
# Staging
CDK_ENV=staging npx cdk deploy Api-staging
# Produktion (mit Bestätigung)
CDK_ENV=prod npx cdk deploy Api-prod
# Diff vor Produktion immer prüfen
CDK_ENV=prod npx cdk diff Api-prod
4 häufige Fallstricke
Fallstrick 1: Fehlende CORS-Konfiguration (häufigster Fehler)
Symptom: fetch() im Browser wirft einen CORS error. Postman funktioniert.
Ursache: Auch bei aktiviertem CORS in API Gateway muss Lambda (Proxy-Integration) CORS-Header in der Antwort zurückgeben.
// ❌ Unzureichend
defaultCorsPreflightOptions: {
allowOrigins: apigateway.Cors.ALL_ORIGINS,
}
// ✅ CORS-Header immer in Lambda-Antworten setzen
return {
statusCode: 200,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "https://example.com",
"Access-Control-Allow-Credentials": "true",
},
body: JSON.stringify(data),
};
Fallstrick 2: Fehlende Lambda-Aufrufberechtigung
Symptom: API gibt {"message": "Internal server error"} zurück. CloudWatch-Logs zeigen AccessDeniedException.
// Berechtigung manuell hinzufügen wenn nötig
listProjectsFn.addPermission("ApiGatewayInvoke", {
principal: new iam.ServicePrincipal("apigateway.amazonaws.com"),
sourceArn: this.api.arnForExecuteApi("GET", "/projects", "v1"),
});
Fallstrick 3: Die 29-Sekunden-Timeout-Grenze
Symptom: Anfragen, die länger als 30 Sekunden dauern, scheitern plötzlich mit {"message": "Endpoint request timed out"}.
Ursache: Das Integrations-Timeout von API Gateway ist auf 29 Sekunden begrenzt. Dies kann nicht erhöht werden.
// ✅ Asynchrones Muster: Job-ID sofort zurückgeben, dann Status abfragen
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" }),
};
};
Fallstrick 4: Fehlender Request-Body in Lambda
Symptom: Lambda empfängt null für event.body.
// ✅ Proxy-Integration immer explizit setzen
project.addMethod(
"POST",
new apigateway.LambdaIntegration(createProjectFn, {
proxy: true,
})
);
Zusammenfassung
| Aufgabe | Claude Code-Mehrwert | Schwierigkeit |
|---|---|---|
| REST API-Design | Specs aus Use Cases generieren, REST-Prinzip-Check | Niedrig |
| Lambda-Integration CDK | Proxy-Integration + Ressourcen-Definitionen gebündelt | Niedrig |
| Cognito-Auth | User Pool, Authorizer, Client-Config generieren | Mittel |
| Lambda Authorizer | JWT-Validierung + Policy-Generierung | Mittel |
| Stage-Verwaltung | Env-Configs trennen, Deploy-Befehle generieren | Mittel |
| Asynchrone Verarbeitung | SQS-Integration + Polling-Muster | Hoch |
| CORS-Konfiguration | Lambda-seitige Header ohne Auslassungen | Niedrig |
Praxisergebnis: API Gateway Design-to-CDK-Deploy-Zeit von 3 Tagen auf 1 Tag reduziert. Die Cognito Authorizer-Einrichtung, die früher über eine Stunde AWS-Doku-Lesen erforderte, löst sich jetzt mit einem einzigen Claude Code-Prompt.
Verwandte Artikel
- Claude Code × AWS Lambda Komplettleitfaden
- Claude Code × REST API-Design in der Praxis
- Claude Code × AWS IAM Berechtigungsdesign
Referenzen
Bring deinen Claude-Code-Workflow aufs nächste Level
50 in der Praxis erprobte Prompt-Vorlagen zum direkten Copy-and-paste in Claude Code.
Kostenloses PDF: Claude-Code-Spickzettel in 5 Minuten
Trag einfach deine E-Mail-Adresse ein – wir senden dir den A4-Spickzettel als PDF sofort zu.
Wir behandeln deine Daten sorgfältig und senden niemals Spam.
Über den Autor
Masa
Ingenieur, der Claude Code intensiv nutzt. Betreibt claudecode-lab.com, ein Tech-Medium in 10 Sprachen mit über 2.000 Seiten.
Ähnliche Artikel
Claude Code × Amazon Bedrock Komplettleitfaden | Claude produktiv auf AWS betreiben
Komplettleitfaden zur Nutzung von Amazon Bedrock mit Claude Code. Von IAM-Authentifizierung, Streaming, Lambda-Integration und RAG-Implementierung bis zur Kostenoptimierung – basierend auf Masas Produktionserfahrung.
Claude Code × AWS CodePipeline/CodeBuild Komplettanleitung | CI/CD-Pipeline automatisch aufbauen
CI/CD mit AWS CodePipeline & CodeBuild automatisch aufbauen mit Claude Code. Praxisbeispiele für Pipeline-Design, buildspec.yml-Generierung, Testautomatisierung und CDK-Infrastruktur.
Claude Code × AWS CloudWatch Komplettanleitung | Log-Analyse, Alarme & Dashboard-Automatisierung
AWS CloudWatch mit Claude Code effizienter nutzen. Praxisnaher Code für Log-Musteranalyse, automatische Alarmkonfiguration, Metriken-Dashboards und Incident-Untersuchung.