0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Code × AWS API Gateway|REST API設計からCDKデプロイまで自動化する

0
Posted at

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 のブログ記事 をご覧ください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?