Claude Code × AWS API Gateway|REST API設計からCDKデプロイまで自動化する
API Gateway の設計は「URLとメソッドを決めるだけじゃないの?」と思われがちですが、実際は認証・CORS・Lambda統合・ステージ管理など設定項目が多く、ドキュメントと格闘する時間が長くなりがちです。
Claude Code にAPI設計を任せるようになってから、同じ品質のAPIを1/3の時間で設計できるようになりました。
ステップ1: エンドポイント設計をClaude Codeに依頼
claude -p "
ECサービスの商品管理APIを設計して。
エンドポイント一覧・HTTPメソッド・リクエスト/レスポンスの型を
TypeScript の型定義として出力して。
機能: 商品一覧取得、商品詳細、商品作成、更新、削除、在庫更新
認証: JWT (Cognito User Pool)
"
ステップ2: CDKでAPI Gateway + Lambda を定義
// lib/api-stack.ts
import * as cdk from "aws-cdk-lib";
import * as apigw from "aws-cdk-lib/aws-apigateway";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as cognito from "aws-cdk-lib/aws-cognito";
export class ApiStack extends cdk.Stack {
constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Lambda 関数
const productLambda = new lambda.Function(this, "ProductLambda", {
runtime: lambda.Runtime.NODEJS_20_X,
handler: "index.handler",
code: lambda.Code.fromAsset("src/lambda/products"),
timeout: cdk.Duration.seconds(29), // API Gatewayの上限29秒に合わせる
});
// Cognito Authorizer
const userPool = cognito.UserPool.fromUserPoolId(this, "UserPool", process.env.USER_POOL_ID!);
const authorizer = new apigw.CognitoUserPoolsAuthorizer(this, "Authorizer", {
cognitoUserPools: [userPool],
});
// REST API
const api = new apigw.RestApi(this, "ProductApi", {
restApiName: "product-api",
defaultCorsPreflightOptions: {
allowOrigins: apigw.Cors.ALL_ORIGINS,
allowMethods: apigw.Cors.ALL_METHODS,
},
deployOptions: {
stageName: process.env.STAGE ?? "dev",
},
});
// リソース定義
const products = api.root.addResource("products");
const product = products.addResource("{id}");
const authOptions = {
authorizer,
authorizationType: apigw.AuthorizationType.COGNITO,
};
// エンドポイント登録
products.addMethod("GET", new apigw.LambdaIntegration(productLambda), authOptions);
products.addMethod("POST", new apigw.LambdaIntegration(productLambda), authOptions);
product.addMethod("GET", new apigw.LambdaIntegration(productLambda), authOptions);
product.addMethod("PUT", new apigw.LambdaIntegration(productLambda), authOptions);
product.addMethod("DELETE", new apigw.LambdaIntegration(productLambda), authOptions);
new cdk.CfnOutput(this, "ApiUrl", { value: api.url });
}
}
ステップ3: Lambda ハンドラーの実装
// src/lambda/products/index.ts
import { APIGatewayProxyHandler } from "aws-lambda";
export const handler: APIGatewayProxyHandler = async (event) => {
const method = event.httpMethod;
const id = event.pathParameters?.id;
try {
switch (method) {
case "GET":
return id ? await getProduct(id) : await listProducts(event.queryStringParameters);
case "POST":
return await createProduct(JSON.parse(event.body ?? "{}"));
case "PUT":
return await updateProduct(id!, JSON.parse(event.body ?? "{}"));
case "DELETE":
return await deleteProduct(id!);
default:
return { statusCode: 405, body: JSON.stringify({ error: "Method not allowed" }) };
}
} catch (err: any) {
console.error(err);
return { statusCode: 500, body: JSON.stringify({ error: "Internal server error" }) };
}
};
ステップ4: ステージ別デプロイ
# 開発環境
STAGE=dev npx cdk deploy ApiStack
# 本番環境
STAGE=prod npx cdk deploy ApiStack
よくある落とし穴
1. CORSの設定が効かない
CDKで defaultCorsPreflightOptions を設定しても、Lambda側で Access-Control-Allow-Origin ヘッダーを返さないと CORS エラーが出ます。Lambda レスポンスにも必ずヘッダーを含めましょう。
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Content-Type,Authorization",
};
return { statusCode: 200, headers: corsHeaders, body: JSON.stringify(data) };
2. タイムアウトは29秒が上限
API Gateway の統合タイムアウトは最大29秒。Lambda のタイムアウトをいくら長くしても29秒で打ち切られます。長時間処理は非同期化 (SQS + Lambda) にしましょう。
3. リクエストボディのContent-Type
API Gateway はデフォルトで application/json しかパーススしません。フォームデータや multipart は別途設定が必要です。
4. Lambda 権限の付与忘れ
// Lambda が DynamoDB を叩く場合は明示的に権限付与
table.grantReadWriteData(productLambda);
まとめ
| タスク | Claude Code の貢献 |
|---|---|
| API設計 | エンドポイント一覧・型定義を一括生成 |
| CDK実装 | API Gateway + Lambda + Cognito を自動生成 |
| Lambda実装 | ルーティング・エラー処理を自動生成 |
| CORS対応 | ヘッダー設定漏れを指摘・修正 |
詳細は claudecode-lab.com のブログ記事 をご覧ください。