Use Cases (Diperbarui: 3/6/2026)

Claude Code dan OpenAPI 3.1: Validasi Swagger serta Generasi TypeScript

Buat spesifikasi OpenAPI 3.1 dengan Claude Code, validasi, lalu hasilkan client TypeScript yang aman.

Claude Code dan OpenAPI 3.1: Validasi Swagger serta Generasi TypeScript

Claude Code bisa membuat file OpenAPI dengan cepat. Masalahnya, spesifikasi yang terlihat rapi belum tentu benar. Ia dapat menebak field dari label UI, menambahkan nilai enum yang tidak ada di database, atau mengubah format error dari satu endpoint ke endpoint lain.

Panduan ini memakai Claude Code sebagai asisten pemelihara kontrak API, bukan pembuat schema yang selalu benar. Kita akan membuat spesifikasi OpenAPI 3.1, memvalidasinya, menghasilkan client TypeScript dan server stub, lalu menambahkan pemeriksaan kecil untuk menangkap schema halusinasi. OpenAPI menjelaskan endpoint REST, request, response, autentikasi, dan error dalam format yang bisa dibaca tool. Swagger adalah ekosistem tool yang umum dipakai untuk mengedit, melihat, dan meninjau dokumen tersebut.

Masa menguji alur ini pada API pesanan sederhana. Prompt bebas seperti “baca repo dan buat OpenAPI” menghasilkan status cancelled yang masuk akal tetapi tidak ada di domain model. Hasilnya jauh lebih stabil ketika prompt menentukan file yang wajib dibaca, melarang field yang tidak terbukti, menjalankan validasi, dan memisahkan pertanyaan terbuka dari schema publik.

Gunakan rujukan resmi. Pada 3 Juni 2026, OpenAPI Specification latest sudah 3.2.0, tetapi contoh di artikel ini tetap memakai openapi: 3.1.0 demi kompatibilitas generator. Untuk detail 3.1, pakai OpenAPI Specification 3.1.2, Swagger Editor documentation, OpenAPI Generator usage, typescript-fetch generator, dan typescript-nestjs-server generator. Untuk OpenAPI 3.1, cek dukungan Swagger Editor Next di dokumentasi terbaru.

Baca juga panduan pengembangan API, panduan testing API, praktik keamanan, dan praktik CLAUDE.md.

flowchart LR
  A["Implementasi, DB, test"] --> B["Claude Code menyusun OpenAPI"]
  B --> C["Validasi Swagger dan CLI"]
  C --> D["Client TypeScript"]
  C --> E["Contract tests"]
  C --> F["Security review"]
  D --> G["Frontend atau partner"]
  E --> H["CI publish gate"]
  F --> H

Kapan dipakai

KebutuhanClaude Code mengerjakanTim memutuskan
Mendokumentasikan API lamaRoute, model, status HTTP, batas authField publik, kompatibilitas, penamaan
Contract-first APIDraft OpenAPI 3.1, contoh, commandAturan bisnis, kebijakan error, scope
Integrasi frontendClient TypeScript, contoh panggilanUX, retry, pesan pengguna
Contract testsoperationId, response 4xx, enum, authKebijakan breaking change dan pengecualian
Security reviewSchema publik, auth, kandidat PII, ID internalRisiko legal, audit, janji ke partner
API untuk partnerDeskripsi Swagger, contoh, authKontrak, rate limit, dukungan

Aturan utamanya: detail schema yang tidak dibuktikan oleh kode, database, test, atau keputusan produk tidak boleh masuk ke schema publik.

Setup yang bisa disalin

Gunakan Node.js 20+. OpenAPI Generator memakai Java untuk proses generasi kode.

mkdir openapi-claude-demo
cd openapi-claude-demo
npm init -y
npm install -D @openapitools/openapi-generator-cli js-yaml
mkdir specs generated scripts

package.json:

{
  "type": "module",
  "scripts": {
    "validate:openapi": "openapi-generator-cli validate -i specs/openapi.yaml",
    "lint:contract": "node scripts/check-openapi-rules.mjs",
    "test:contract": "node --test scripts/contract.test.mjs",
    "generate:client": "openapi-generator-cli generate -i specs/openapi.yaml -g typescript-fetch -o generated/client --additional-properties=supportsES6=true,npmName=@example/orders-client,npmVersion=0.1.0",
    "generate:server": "openapi-generator-cli generate -i specs/openapi.yaml -g typescript-nestjs-server -o generated/server",
    "contract": "npm run validate:openapi && npm run lint:contract && npm run test:contract && npm run generate:client"
  },
  "devDependencies": {
    "@openapitools/openapi-generator-cli": "latest",
    "js-yaml": "latest"
  }
}

specs/openapi.yaml:

openapi: 3.1.0
info:
  title: Orders API
  version: 0.1.0
  description: Contract-first sample API for order intake.
servers:
  - url: https://api.example.com/v1
paths:
  /orders:
    post:
      operationId: createOrder
      summary: Create an order
      tags: [orders]
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateOrderRequest"
      responses:
        "201":
          description: Order created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Order"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  responses:
    BadRequest:
      description: Invalid request
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    Unauthorized:
      description: Missing or invalid token
  schemas:
    CreateOrderRequest:
      type: object
      additionalProperties: false
      required: [customerEmail, items]
      properties:
        customerEmail:
          type: string
          format: email
        note:
          type: [string, "null"]
        items:
          type: array
          minItems: 1
          items:
            $ref: "#/components/schemas/OrderItemInput"
    OrderItemInput:
      type: object
      additionalProperties: false
      required: [sku, quantity]
      properties:
        sku:
          type: string
        quantity:
          type: integer
          minimum: 1
    Order:
      type: object
      additionalProperties: false
      required: [id, customerEmail, status, items, createdAt]
      properties:
        id:
          type: string
          format: uuid
        customerEmail:
          type: string
          format: email
        status:
          type: string
          enum: [pending, paid]
        items:
          type: array
          items:
            $ref: "#/components/schemas/OrderItemInput"
        createdAt:
          type: string
          format: date-time
    ErrorResponse:
      type: object
      additionalProperties: false
      required: [code, message]
      properties:
        code:
          type: string
          enum: [invalid_request, unauthorized]
        message:
          type: string

scripts/check-openapi-rules.mjs:

import { readFileSync } from "node:fs";

const spec = readFileSync("specs/openapi.yaml", "utf8");
const forbidden = [
  { pattern: /\bTBD\b|\bTODO\b|placeholder/i, reason: "unfinished placeholder" },
  { pattern: /nullable:\s*true/, reason: "OpenAPI 3.1 should use JSON Schema null types" },
  { pattern: /password|secret|clientSecret|apiKey/i, reason: "review sensitive fields before publishing" }
];

const errors = forbidden.filter((rule) => rule.pattern.test(spec)).map((rule) => `- ${rule.reason}`);
if (!spec.includes("additionalProperties: false")) errors.push("- schemas should explicitly decide additionalProperties");
if (errors.length > 0) {
  console.error("Contract review failed:\n" + errors.join("\n"));
  process.exit(1);
}
console.log("Contract review passed.");

Tambahkan contract test yang bisa berjalan di CI. Ini bukan pengganti integration test ke server nyata; tujuannya memeriksa kontrak publik: operationId, security untuk operasi mutasi, response 4xx bersama, dan enum Order.status saat ini.

// scripts/contract.test.mjs
import { readFileSync } from "node:fs";
import assert from "node:assert/strict";
import test from "node:test";
import { load } from "js-yaml";

const doc = load(readFileSync("specs/openapi.yaml", "utf8"));
const httpMethods = new Set(["get", "put", "post", "delete", "patch", "options", "head", "trace"]);

function operations() {
  return Object.entries(doc.paths ?? {}).flatMap(([path, pathItem]) =>
    Object.entries(pathItem)
      .filter(([method]) => httpMethods.has(method))
      .map(([method, operation]) => ({ path, method, operation }))
  );
}

test("operationId is unique and camelCase", () => {
  const ids = operations().map(({ operation }) => operation.operationId);
  assert.equal(new Set(ids).size, ids.length);
  for (const id of ids) assert.match(id, /^[a-z][A-Za-z0-9]*$/);
});

test("mutating operations require security", () => {
  for (const { path, method, operation } of operations()) {
    if (["get", "head", "options"].includes(method)) continue;
    assert.ok(operation.security?.length, `${method.toUpperCase()} ${path} must declare security`);
  }
});

test("client-visible 4xx responses reuse shared components", () => {
  for (const { path, method, operation } of operations()) {
    for (const [status, response] of Object.entries(operation.responses ?? {})) {
      if (!status.startsWith("4")) continue;
      assert.ok(response.$ref?.startsWith("#/components/responses/"), `${method.toUpperCase()} ${path} ${status}`);
    }
  }
});

test("Order status enum matches the current implementation decision", () => {
  const status = doc.components.schemas.Order.properties.status;
  assert.deepEqual(status.enum, ["pending", "paid"]);
});

Jalankan:

npm run validate:openapi
npm run lint:contract
npm run test:contract
npm run generate:client
npm run generate:server

Prompt untuk Claude Code

Buat kontrak OpenAPI 3.1 untuk API pesanan.
Baca src/routes/orders.ts, src/domain/order.ts, prisma/schema.prisma, dan tests/orders.test.ts terlebih dahulu.
Jangan membuat field, enum, atau kode error yang tidak dibuktikan oleh kode, schema, test, atau catatan produk.
Masukkan pertanyaan terbuka ke x-claude-review, bukan ke schemas publik.
Jangan gunakan nullable: true. Gunakan operationId camelCase yang stabil.
Deklarasikan security untuk operasi terlindungi. Field internal, PII, dan kandidat secret masuk ke x-claude-review sebelum schema publik.
Jalankan npm run validate:openapi, npm run lint:contract, dan npm run test:contract, lalu perbaiki kegagalan.
Kembalikan diff, contoh pemanggilan client TypeScript, catatan security review, dan pertanyaan untuk review manusia.

Contract tests dan security review

Untuk API SaaS atau partner, review OpenAPI bukan sekadar memperbaiki teks. Pisahkan menjadi spec review, review client hasil generate, contract tests, dan security review. Spec review melihat path, method, schema, status, dan contoh. Review client melihat tipe typescript-fetch serta null/optional. Contract tests menahan auth yang hilang, bentuk error yang berubah, dan enum yang rusak. Security review memeriksa field publik, PII, ID internal, URL server, dan kemungkinan secret.

Claude Code bisa menyusun daftar diff, draft test, dan tabel review. Tim tetap harus memutuskan field mana yang boleh dipublikasikan, rate limit apa yang dijanjikan, risiko legal apa yang ada, dan bukti audit apa yang perlu disimpan.

Kesalahan umum

Kesalahan pertama adalah schema halusinasi seperti cancelled, refunded, atau adminNote. Kedua, format error tidak konsisten. Ketiga, kebiasaan OpenAPI 3.0 seperti nullable: true masih dipakai di file 3.1. Keempat, kode hasil generate diedit manual. Kelima, review hanya memakai tampilan Swagger tanpa memeriksa auth, operationId, contoh response, dan kompatibilitas enum.

CTA training dan konsultasi

Perapihan OpenAPI cocok untuk training dan konsultasi karena output-nya jelas: spesifikasi, client TypeScript, server stub, contract test, validasi, dan checklist CI. Solo builder bisa mulai dari produk ClaudeCodeLab untuk prompt dan template review. Tim yang perlu menyesuaikan ini ke repository nyata, CLAUDE.md, testing API, dan security review bisa memakai training dan konsultasi Claude Code.

Hasil uji langsung

Dalam pengujian Masa, prompt bebas menambahkan status yang tidak diimplementasikan dan mengubah bentuk error. Setelah file wajib, aturan tidak boleh mengarang, openapi-generator-cli validate, script lokal, dan node --test diterapkan, review manusia berfokus pada empat hal: field publik, masa depan enum, teks error autentikasi, dan apakah data internal bocor ke schema. OpenAPI paling berguna sebagai kontrak bersama antara tim dan AI, bukan dokumen yang diserahkan begitu saja.

#Claude Code #OpenAPI #Swagger #API design #REST
Gratis

PDF gratis: cheatsheet Claude Code

Masukkan email dan unduh satu halaman berisi command, kebiasaan review, dan workflow aman.

Kami menjaga datamu dan tidak mengirim spam.

Masa

Tentang penulis

Masa

Engineer yang berfokus pada workflow Claude Code praktis dan adopsi tim.