Claude Code से Practical API Design: OpenAPI, Tests और Breaking Change Check
Claude Code से भरोसेमंद REST API design करें: OpenAPI, mock, tests, versioning, security और pitfalls।
API design का मतलब सिर्फ अच्छी URL naming नहीं है। यह एक contract है: client क्या भेज सकता है, server क्या लौटाएगा, और fail होने पर caller को क्या समझ आएगा।
अगर यह contract अस्पष्ट है, तो frontend, mobile app, partner integration, tests और monitoring सब अपनी-अपनी व्याख्या बना लेते हैं। बाद में ठीक करना महंगा होता है, इसलिए शुरुआत में छोटा लेकिन साफ contract बनाना बेहतर है।
Claude Code इस काम में उपयोगी है, पर इसे केवल code generator की तरह इस्तेमाल न करें। इसे API design reviewer की तरह चलाएं: OpenAPI draft बनवाएं, endpoints की समीक्षा कराएं, mock और tests generate कराएं, और पुराने clients को तोड़ने वाले changes check कराएं।
काम करते समय official references रखें: OpenAPI Specification, RFC 9110 HTTP Semantics, JSON Schema docs, और OWASP API Security Top 10. Implementation के लिए production API development, API test automation, और API versioning भी देखें।
API design में क्या तय होता है
API दूसरे program के लिए interface है। इंसानों वाली screen labels और layout से समझाती है; API paths, HTTP methods, status codes, JSON fields, schema, examples और errors से समझाती है।
शुरुआत में ये पांच बातें तय करें।
| विषय | आसान मतलब | उदाहरण |
|---|---|---|
| Resource | API जिस noun को expose करती है | orders, customers, invoices |
| Operation | उस resource पर action | GET, POST, PATCH, DELETE |
| Schema | JSON की shape और rules | items में कम से कम एक item |
| Error | failure कैसे बताया जाएगा | 400, 401, 403, 404, 422 with details |
| Compatibility | existing clients कैसे नहीं टूटेंगे | required field जोड़ना breaking है |
REST को बहुत theoretical बनाने की जरूरत नहीं। Practical rule है: URL में noun रखें और action को HTTP method से दिखाएं। POST /orders अक्सर POST /orders/create से बेहतर है, और GET /orders/ord_123 GET /getOrder?id=ord_123 से ज्यादा साफ है।
Claude Code workflow
Claude Code से एक ही prompt में design, implementation, tests और docs सब न करवाएं। काम को छोटे reviewable steps में रखें।
flowchart TD
A["Business rules summarize करें"] --> B["OpenAPI contract draft करें"]
B --> C["HTTP, schema, security review करें"]
C --> D["Mock server और API tests बनाएं"]
D --> E["CI में breaking changes check करें"]
E --> F["Implement, document, publish करें"]
OpenAPI HTTP API का machine-readable contract है। JSON Schema JSON की shape और constraints बताता है। HTTP status codes success और failure का shared meaning देते हैं। Claude Code इनको जोड़ सकता है, लेकिन final source of truth official specs और tests ही हैं।
Masa ने छोटे verification project में देखा कि सिर्फ endpoint list मांगने पर result ठीक दिखता था। लेकिन authentication, pagination, idempotency key और error details बाद में जोड़ने पर changes बढ़ गए। बेहतर है कि पहले prompt में ही client failure recovery पूछी जाए।
Copy-paste starter kit
यह example external packages नहीं मांगता। इससे OpenAPI, mock server और breaking change check एक साथ try कर सकते हैं।
mkdir api-design-lab
cd api-design-lab
mkdir docs examples
node --version
docs/openapi.yaml बनाएं। Official OpenAPI page latest published spec दिखाता है; यह sample tooling compatibility के लिए 3.1 use करता है।
openapi: 3.1.0
info:
title: Orders API
version: 1.0.0
servers:
- url: https://api.example.com
paths:
/v1/orders:
post:
summary: Create an order
operationId: createOrder
security:
- bearerAuth: []
parameters:
- name: Idempotency-Key
in: header
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateOrderRequest"
responses:
"201":
description: Created
content:
application/json:
schema:
$ref: "#/components/schemas/Order"
"422":
description: Validation error
content:
application/json:
schema:
$ref: "#/components/schemas/Problem"
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
schemas:
CreateOrderRequest:
type: object
required: [customerId, items]
properties:
customerId:
type: string
minLength: 3
items:
type: array
minItems: 1
items:
type: object
required: [sku, quantity]
properties:
sku:
type: string
minLength: 3
quantity:
type: integer
minimum: 1
Order:
type: object
required: [id, status, customerId, total]
properties:
id:
type: string
status:
type: string
enum: [accepted, cancelled]
customerId:
type: string
total:
type: integer
Problem:
type: object
required: [type, title, status, detail]
properties:
type:
type: string
title:
type: string
status:
type: integer
detail:
type: string
errors:
type: array
items:
type: object
examples/mock-server.mjs बनाएं।
import { createServer } from "node:http";
import { randomUUID } from "node:crypto";
function readJson(req) {
return new Promise((resolve, reject) => {
let body = "";
req.on("data", (chunk) => {
body += chunk;
if (body.length > 1_000_000) req.destroy(new Error("Body too large"));
});
req.on("end", () => {
if (!body) return resolve({});
try {
resolve(JSON.parse(body));
} catch (error) {
reject(error);
}
});
req.on("error", reject);
});
}
function send(res, status, body, headers = {}) {
res.writeHead(status, {
"content-type": "application/json; charset=utf-8",
"x-content-type-options": "nosniff",
...headers,
});
res.end(JSON.stringify(body, null, 2));
}
function problem(status, title, detail, errors = []) {
return {
type: "https://example.com/problems/request",
title,
status,
detail,
errors,
};
}
function validateOrder(input) {
const errors = [];
if (typeof input.customerId !== "string" || input.customerId.length < 3) {
errors.push({
path: "customerId",
message: "customerId must be a string with 3+ characters",
});
}
if (!Array.isArray(input.items) || input.items.length === 0) {
errors.push({ path: "items", message: "items must contain at least one item" });
}
for (const [index, item] of (input.items ?? []).entries()) {
if (typeof item.sku !== "string" || item.sku.length < 3) {
errors.push({
path: `items.${index}.sku`,
message: "sku must be a string with 3+ characters",
});
}
if (!Number.isInteger(item.quantity) || item.quantity < 1) {
errors.push({
path: `items.${index}.quantity`,
message: "quantity must be a positive integer",
});
}
}
return errors;
}
const server = createServer(async (req, res) => {
const url = new URL(req.url ?? "/", "http://localhost");
if (req.method === "GET" && url.pathname === "/health") {
return send(res, 200, { ok: true });
}
const customerMatch = url.pathname.match(/^\/v1\/customers\/([a-z0-9-]+)$/);
if (req.method === "GET" && customerMatch) {
return send(res, 200, {
id: customerMatch[1],
name: "Aki Tanaka",
plan: "pro",
});
}
if (req.method === "POST" && url.pathname === "/v1/orders") {
const idempotencyKey = req.headers["idempotency-key"];
if (!idempotencyKey) {
return send(
res,
400,
problem(400, "Missing Idempotency-Key", "POST /v1/orders requires the header.")
);
}
try {
const body = await readJson(req);
const errors = validateOrder(body);
if (errors.length > 0) {
return send(res, 422, problem(422, "Invalid request body", "Fix errors.", errors));
}
return send(
res,
201,
{
id: `ord_${randomUUID()}`,
status: "accepted",
customerId: body.customerId,
total: 4200,
},
{ location: "/v1/orders/example" }
);
} catch {
return send(res, 400, problem(400, "Malformed JSON", "Request body must be JSON."));
}
}
return send(res, 404, problem(404, "Not found", `${req.method} ${url.pathname} is undefined.`));
});
server.listen(3000, () => {
console.log("Mock API running at http://localhost:3000");
});
Server चलाएं और दूसरे terminal से call करें।
node examples/mock-server.mjs
curl -i http://localhost:3000/health
curl -i -X POST http://localhost:3000/v1/orders \
-H "content-type: application/json" \
-H "idempotency-key: demo-001" \
-d '{"customerId":"cus_123","items":[{"sku":"book-1","quantity":2}]}'
curl -i -X POST http://localhost:3000/v1/orders \
-H "content-type: application/json" \
-H "idempotency-key: demo-002" \
-d '{"customerId":"x","items":[]}'
अब examples/contract-check.mjs बनाएं। यह जानबूझकर fail होगा।
import assert from "node:assert/strict";
const previous = {
paths: {
"/v1/orders": {
post: {
request: {
required: ["customerId", "items"],
properties: ["customerId", "items", "couponCode"],
},
response: {
required: ["id", "status", "customerId", "total"],
properties: ["id", "status", "customerId", "total"],
},
},
},
},
};
const next = structuredClone(previous);
next.paths["/v1/orders"].post.request.required.push("shippingAddress");
next.paths["/v1/orders"].post.response.properties =
next.paths["/v1/orders"].post.response.properties.filter((name) => name !== "total");
function diffContract(oldSpec, newSpec) {
const breaking = [];
for (const [path, methods] of Object.entries(oldSpec.paths)) {
for (const [method, oldOperation] of Object.entries(methods)) {
const newOperation = newSpec.paths[path]?.[method];
if (!newOperation) {
breaking.push(`${method.toUpperCase()} ${path} was removed`);
continue;
}
const oldRequired = new Set(oldOperation.request.required);
for (const field of newOperation.request.required) {
if (!oldRequired.has(field)) {
breaking.push(`${method.toUpperCase()} ${path} now requires "${field}"`);
}
}
const newResponseFields = new Set(newOperation.response.properties);
for (const field of oldOperation.response.properties) {
if (!newResponseFields.has(field)) {
breaking.push(`${method.toUpperCase()} ${path} removed response "${field}"`);
}
}
}
}
return breaking;
}
const breaking = diffContract(previous, next);
console.log(breaking.join("\n") || "No breaking changes found");
assert.equal(breaking.length, 0, "Breaking API changes detected");
node examples/contract-check.mjs
यह fail होना सही result है। Script नया required request field और removed response field पकड़ता है।
Claude Code prompts
Draft, review, examples और compatibility check को अलग-अलग रखें।
claude -p "
E-commerce orders API के लिए docs/openapi.yaml में OpenAPI draft बनाएं।
Resources: customers, orders, invoices.
हर endpoint में summary, operationId, requestBody, responses, examples और bearerAuth जोड़ें।
OpenAPI 3.1 और JSON Schema style constraints का उपयोग करें।
"
claude -p "
docs/openapi.yaml को API design reviewer की तरह पढ़ें।
पहले severity order में Findings दें और अभी files edit न करें।
RFC 9110 method/status semantics, vague schema, pagination, idempotency,
authentication और OWASP API Security risks check करें।
"
claude -p "
docs/openapi.yaml से Node.js mock server और API test examples generate करें।
Success, auth failure, validation failure और missing resource cases cover करें।
Long lines 150 characters से कम रखें और README में commands जोड़ें।
"
claude -p "
Current docs/openapi.yaml को HEAD वाली version से compare करें।
Edits suggest करने से पहले breaking changes list करें।
Removed paths, new required fields, removed response fields,
changed status codes और changed auth scopes check करें।
"
Practical use cases
पहला use case SaaS orders API है। Admin screen, billing jobs, emails और accounting export वही Order पढ़ते हैं। अगर total, currency, tax और cancellation state साफ नहीं हैं, हर integration अलग rule बना लेगा।
दूसरा use case mobile profile API है। पुराने app versions महीनों तक users के पास रह सकते हैं। Response field हटाना या enum meaning बदलना ऐसे clients को तोड़ सकता है जिन्हें तुरंत update नहीं किया जा सकता।
तीसरा use case B2B partner API है। External developers आपकी internal conventions नहीं जानते। उन्हें stable error codes, rate limits, retry guidance, sandbox और examples चाहिए।
चौथा use case internal admin API है। Internal होने से API safe नहीं हो जाती। Object-level authorization जरूरी है: सिर्फ order ID जानने से दूसरे tenant का data नहीं मिलना चाहिए।
Pitfalls और failure cases
पहला common pitfall path में verbs डालना है: /cancelOrder, /getUserOrders, /updateOrderStatus। समय के साथ naming inconsistent हो जाती है। पहले resources model करें, फिर subresource या method से action दिखाएं।
दूसरा pitfall हर business error को 200 से लौटाना है। इससे monitoring, SDKs, retries और client error handling कठिन हो जाते हैं। Malformed input के लिए 400, missing auth के लिए 401, forbidden के लिए 403, missing resource के लिए 404 और semantic validation के लिए 422 रखें।
तीसरा pitfall POST retry safety भूलना है। Order creation या payment start timeout के बाद दोबारा भेजे जा सकते हैं। शुरुआत से Idempotency-Key design करें।
Schema ambiguity भी बड़ा issue है। null का मतलब clear करना है, unknown है या not sent? Required fields, minimum length, pagination limit, timezone और extra properties पहले तय करें।
Versioning, errors, schema, security
Versioning सिर्फ /v1 नहीं है। Team को तय करना चाहिए कि breaking change क्या है। Optional field जोड़ना अक्सर safe है; required request field जोड़ना, response field हटाना, status meaning बदलना या permission कठोर करना clients तोड़ सकता है।
Error design caller को next action बताए। सिर्फ Invalid request काफी नहीं। Stable shape रखें: type, title, status, detail, और जरूरत हो तो field-level errors। Production में stack trace, SQL या internal IDs न लौटाएं।
Schema examples से ज्यादा constraints लिखें। ID format, minimum length, array limits, pagination defaults और date timezone clients को सही validation करने में मदद करते हैं।
Security में authentication और authorization अलग हैं। Bearer token बताता है कौन है; authorization बताता है कि वह इस object को access कर सकता है या नहीं। API key query में न डालें, sensitive response data कम करें, rate limit और audit logs रखें।
Monetization और consulting CTA
API design खोजने वाला reader अक्सर real project पर होता है: public integration, mobile backend, team review rules या partner API। Article को theory से आगे जाकर working workflow दिखाना चाहिए।
ClaudeCodeLab Claude Code API design review, OpenAPI cleanup, test automation और breaking change checks में मदद कर सकता है। Teams training और consulting से शुरू कर सकते हैं, और individual developers free resources से prompts adapt कर सकते हैं।
Verified result
इस article का code Node v24.14.1 पर verify किया गया। GET /health ने 200 दिया, valid POST /v1/orders ने 201 दिया, और empty items ने 422 दिया। contract-check.mjs intentionally fail हुआ और नया required field तथा removed response field दिखाया। इससे Claude Code prompts से OpenAPI, mock, errors और CI-friendly compatibility check तक पूरा छोटा workflow मिल जाता है।
मुफ़्त PDF: Claude Code cheatsheet
Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.
हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.
लेखक के बारे में
Masa
Claude Code workflow और team adoption पर काम करने वाला engineer.
संबंधित लेख
Claude Code Obsidian to CLAUDE.md workflow: context बार-बार न समझाएं
Obsidian notes को CLAUDE.md operating notes में बदलकर Claude Code sessions को resume करना आसान बनाएं.
Claude Code Revenue CTA Routing: article से PDF, Gumroad और consultation तक
Reader intent के आधार पर free PDF, Gumroad products और consultation तक CTA route करने वाला workflow.
Claude Code टीम हैंडऑफ नियम: review proof, permissions, rollback और revenue path
Claude Code टीम काम के लिए evidence, permission rules, rollback, free PDF, Gumroad और consultation path वाला handoff.