Use Cases

Claude Code × AWS API Gateway Panduan Lengkap | Desain REST API hingga Otomasi Deployment

Otomasi desain endpoint AWS API Gateway dengan Claude Code. Desain resource, integrasi Lambda, autentikasi, dan deployment — dengan kode nyata dari pengalaman profesional Masa.

Bagaimana Waktu Desain API Gateway Berkurang Menjadi Sepertiga

Saya Masa, mengelola claudecode-lab.com. Saat masih bekerja sebagai developer backend freelance, desain dan implementasi AWS API Gateway selalu menjadi “pekerjaan membosankan yang memakan waktu”. Menulis dokumen spesifikasi endpoint, menerjemahkannya ke CloudFormation, menyambungkan integrasi Lambda secara manual, mengkonfigurasi CORS — dan membuat kesalahan yang sama berulang kali.

Titik baliknya datang sekitar enam bulan lalu, ketika saya meminta Claude Code: “Desain REST API berdasarkan use case ini dan implementasikan dalam CDK.” Hasilnya mengejutkan — sudah siap produksi, dan sejak itu waktu implementasi API Gateway berkurang menjadi sepertiga.


Langkah 1: Mendelegasikan Desain Endpoint REST API ke Claude Code

Contoh Prompt

Buat spesifikasi endpoint REST API berdasarkan use case berikut.

Use case:
- App manajemen tugas (pengguna mengelola proyek dan tugas)
- Autentikasi pengguna diperlukan (Cognito)
- Proyek dapat memiliki anggota
- Tugas mendukung komentar dan lampiran file

Format output:
- Daftar endpoint (metode, path, deskripsi)
- Skema JSON request/response
- Tandai endpoint yang memerlukan autentikasi
- Tandai pelanggaran prinsip REST

Langkah 2: Auto-Generasi Konfigurasi Integrasi Lambda

CDK Stack yang Dihasilkan (kutipan)

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 fungsi 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 maksimum 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");

    // ===== Definisi REST API =====
    this.api = new apigateway.RestApi(this, "TaskApi", {
      restApiName: "task-management-api",
      defaultCorsPreflightOptions: {
        allowOrigins: apigateway.Cors.ALL_ORIGINS, // batasi di produksi
        allowMethods: apigateway.Cors.ALL_METHODS,
        allowHeaders: ["Content-Type", "Authorization", "X-Api-Key"],
      },
      deployOptions: {
        stageName: "v1",
        loggingLevel: apigateway.MethodLoggingLevel.INFO,
        dataTraceEnabled: false,
      },
    });

    // ===== Resource dan metode =====
    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 API Gateway",
    });
  }
}

Langkah 3: Autentikasi (Cognito / Lambda Authorizer / API Key)

Pola 1: Cognito User Pool Authorizer

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,
});

Pola 2: Lambda Authorizer

// src/handlers/auth/authorizer.ts
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");
  }
};

Langkah 4: Manajemen Stage (dev/staging/prod)

# Deploy ke development
CDK_ENV=dev npx cdk deploy Api-dev --require-approval never

# Staging
CDK_ENV=staging npx cdk deploy Api-staging

# Produksi (dengan konfirmasi)
CDK_ENV=prod npx cdk deploy Api-prod

4 Jebakan Umum

Jebakan 1: Konfigurasi CORS Hilang (paling sering)

// ❌ Tidak cukup
defaultCorsPreflightOptions: { allowOrigins: apigateway.Cors.ALL_ORIGINS }

// ✅ Selalu tambahkan header CORS di respons Lambda
return {
  statusCode: 200,
  headers: {
    "Content-Type": "application/json",
    "Access-Control-Allow-Origin": "https://example.com",
  },
  body: JSON.stringify(data),
};

Jebakan 2: Izin Invoke Lambda Hilang

listProjectsFn.addPermission("ApiGatewayInvoke", {
  principal: new iam.ServicePrincipal("apigateway.amazonaws.com"),
  sourceArn: this.api.arnForExecuteApi("GET", "/projects", "v1"),
});

Jebakan 3: Batas Timeout 29 Detik

// ✅ Pola asinkron: kembalikan job ID segera
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" }),
  };
};

Jebakan 4: Body Request Hilang di Lambda

// ✅ Selalu set proxy: true secara eksplisit
project.addMethod("POST", new apigateway.LambdaIntegration(createProjectFn, { proxy: true }));

Ringkasan

TugasNilai Claude CodeKesulitan
Desain REST APIAuto-generate specs, cek prinsip RESTRendah
Lambda Integration CDKGenerate proxy integration + definisi resourceRendah
Auth CognitoGenerate User Pool, Authorizer, config clientSedang
Lambda AuthorizerImplementasi validasi JWT + generate policySedang
Manajemen stagePisah config env, generate perintah deploySedang
Pemrosesan asinkronDesain integrasi SQS + pola pollingTinggi

Hasil praktis: Waktu desain API Gateway hingga deploy CDK berkurang dari 3 hari menjadi 1 hari. Setup Cognito Authorizer yang sebelumnya membutuhkan lebih dari satu jam membaca dokumentasi AWS, kini selesai dengan satu prompt Claude Code.


Artikel Terkait

Referensi

#claude-code #aws #api-gateway #lambda #typescript #rest-api

Tingkatkan alur kerja Claude Code kamu

50 template prompt yang sudah teruji, siap copy-paste ke Claude Code sekarang juga.

Gratis

PDF Gratis: Cheatsheet Claude Code dalam 5 Menit

Cukup masukkan emailmu dan kami akan langsung mengirim cheatsheet PDF A4 satu halaman.

Kami menjaga data pribadimu dengan aman dan tidak pernah mengirim spam.

Masa

Tentang Penulis

Masa

Engineer yang aktif menggunakan Claude Code. Mengelola claudecode-lab.com, media teknologi 10 bahasa dengan lebih dari 2.000 halaman.