Tips & Tricks

Claude Code से REST API को तेज़ी से डिज़ाइन, इम्प्लीमेंट और टेस्ट करें | OpenAPI स्पेक से प्रोडक्शन तक

Claude Code के साथ REST API को OpenAPI स्पेक से लेकर प्रोडक्शन-रेडी TypeScript कोड तक एंड-टू-एंड डेवलप करना सीखें। Hono, zod वैलिडेशन, vitest टेस्ट जनरेशन और काम करने वाले कोड उदाहरण शामिल।

Claude Code REST API डिज़ाइन के लिए क्यों बेहतरीन है

REST API डेवलपमेंट में बार-बार दोहराए जाने वाले पैटर्न होते हैं: एंडपॉइंट डेफिनेशन, वैलिडेशन, एरर हैंडलिंग और टेस्ट — सब हाथ से लिखना पड़ता है। इस बोइलरप्लेट को मैनेज करते हुए बिज़नेस लॉजिक पर ध्यान देना मुश्किल हो जाता है।

मैं Masa हूँ, एक DX इंजीनियर जो इंटरनल सिस्टम APIs के आधुनिकीकरण पर काम करता है। Claude Code से पहले, मेरी प्रति एंडपॉइंट स्टैंडर्ड लागत थी: “30 मिनट डिज़ाइन → 2 घंटे इम्प्लीमेंटेशन → 1 घंटे टेस्टिंग”। Claude Code को पूरी तरह इंटीग्रेट करने के बाद: 10 मिनट डिज़ाइन → 30 मिनट इम्प्लीमेंटेशन → 15 मिनट टेस्टिंग

Claude Code के API डेवलपमेंट में बेहतर होने के 3 कारण

  1. OpenAPI स्पेक को कॉन्टेक्स्ट के रूप में समझता है — YAML पेस्ट करें और स्पेक-कम्प्लायंट कोड तुरंत जनरेट होता है
  2. TypeScript टाइप सिस्टम में महारत — शुरू से ही टाइप-सेफ कोड प्रोड्यूस करता है
  3. टेस्ट पैटर्न का व्यापक ज्ञान — एक ही रन में हैप्पी-पाथ, एरर-पाथ और एज केस टेस्ट जनरेट करता है

1. Claude Code के साथ OpenAPI स्पेक ऑटो-जनरेट करें

प्रॉम्प्ट उदाहरण

निम्नलिखित आवश्यकताओं के लिए OpenAPI 3.1 स्पेसिफिकेशन (YAML) जनरेट करें।

रिसोर्स: Task (टास्क मैनेजमेंट)
फील्ड्स:
  - id: UUID
  - title: string (1–200 कैरेक्टर)
  - description: string (वैकल्पिक)
  - status: "todo" | "in_progress" | "done"
  - priority: "low" | "medium" | "high" (डिफॉल्ट: medium)
  - assignee_id: UUID (वैकल्पिक)
  - due_date: ISO8601 फॉर्मेट (वैकल्पिक)
  - created_at: ISO8601 फॉर्मेट
  - updated_at: ISO8601 फॉर्मेट

एंडपॉइंट्स:
  - GET /tasks (पैजिनेशन के साथ लिस्ट)
  - GET /tasks/:id
  - POST /tasks
  - PUT /tasks/:id (पूर्ण अपडेट)
  - PATCH /tasks/:id (आंशिक अपडेट)
  - DELETE /tasks/:id

रेस्पॉन्स फॉर्मेट: { data, meta, errors }
एरर कोड: 400, 401, 403, 404, 422, 500
ऑथेंटिकेशन: Bearer Token (Authorization हेडर)

जनरेट किया गया OpenAPI YAML (अंश)

openapi: 3.1.0
info:
  title: Task Management API
  version: 1.0.0
  description: टास्क मैनेजमेंट API की OpenAPI स्पेसिफिकेशन

servers:
  - url: https://api.example.com/v1
    description: प्रोडक्शन
  - url: http://localhost:3000/v1
    description: डेवलपमेंट

components:
  schemas:
    Task:
      type: object
      required: [id, title, status, priority, created_at, updated_at]
      properties:
        id:
          type: string
          format: uuid
        title:
          type: string
          minLength: 1
          maxLength: 200
        status:
          type: string
          enum: [todo, in_progress, done]
        priority:
          type: string
          enum: [low, medium, high]
          default: medium

2. Hono के साथ टाइप-सेफ हैंडलर इम्प्लीमेंटेशन

// src/index.ts
import { Hono } from "hono";
import { cors } from "hono/cors";
import { logger } from "hono/logger";
import { prettyJSON } from "hono/pretty-json";
import { taskRouter } from "./routes/tasks";

const app = new Hono();

// मिडलवेयर
app.use("*", cors());
app.use("*", logger());
app.use("*", prettyJSON());

// राउटर रजिस्ट्रेशन
app.route("/v1/tasks", taskRouter);

// ग्लोबल एरर हैंडलर
app.onError((err, c) => {
  console.error(err);
  return c.json(
    { data: null, meta: null, errors: [{ code: "INTERNAL_ERROR", message: "सर्वर में आंतरिक त्रुटि हुई" }] },
    500
  );
});

export default app;

टास्क राउटर इम्प्लीमेंटेशन

// src/routes/tasks.ts
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { TaskCreateSchema, TaskUpdateSchema, TaskPatchSchema, TaskQuerySchema } from "../schemas/task";
import { TaskService } from "../services/taskService";

export const taskRouter = new Hono();
const taskService = new TaskService();

// टास्क लिस्ट
taskRouter.get("/", zValidator("query", TaskQuerySchema), async (c) => {
  const query = c.req.valid("query");
  const result = await taskService.findAll(query);
  return c.json({
    data: result.tasks,
    meta: { total: result.total, page: query.page, per_page: query.per_page },
    errors: null,
  });
});

// ID से टास्क प्राप्त करें
taskRouter.get("/:id", async (c) => {
  const id = c.req.param("id");
  const task = await taskService.findById(id);
  if (!task) {
    return c.json(
      { data: null, meta: null, errors: [{ code: "NOT_FOUND", message: "टास्क नहीं मिला", field: "id" }] },
      404
    );
  }
  return c.json({ data: task, meta: null, errors: null });
});

// टास्क बनाएं
taskRouter.post("/", zValidator("json", TaskCreateSchema), async (c) => {
  const body = c.req.valid("json");
  const task = await taskService.create(body);
  return c.json({ data: task, meta: null, errors: null }, 201);
});

// टास्क डिलीट करें
taskRouter.delete("/:id", async (c) => {
  const id = c.req.param("id");
  const deleted = await taskService.delete(id);
  if (!deleted) {
    return c.json(
      { data: null, meta: null, errors: [{ code: "NOT_FOUND", message: "टास्क नहीं मिला", field: "id" }] },
      404
    );
  }
  return c.json({ data: null, meta: null, errors: null }, 204);
});

3. Zod वैलिडेशन स्कीमा ऑटो-जनरेशन

// src/schemas/task.ts
import { z } from "zod";

const TaskStatus = z.enum(["todo", "in_progress", "done"]);
const TaskPriority = z.enum(["low", "medium", "high"]);

export const TaskSchema = z.object({
  id: z.string().uuid(),
  title: z.string().min(1, "टाइटल कम से कम 1 कैरेक्टर का होना चाहिए").max(200, "टाइटल 200 कैरेक्टर से अधिक नहीं हो सकता"),
  description: z.string().nullable(),
  status: TaskStatus,
  priority: TaskPriority,
  assignee_id: z.string().uuid().nullable(),
  due_date: z.string().datetime().nullable(),
  created_at: z.string().datetime(),
  updated_at: z.string().datetime(),
});

export const TaskCreateSchema = z.object({
  title: z.string().min(1).max(200),
  description: z.string().optional(),
  status: TaskStatus.default("todo"),
  priority: TaskPriority.default("medium"),
  assignee_id: z.string().uuid().optional(),
  due_date: z.string().datetime().optional(),
});

export const TaskUpdateSchema = z.object({
  title: z.string().min(1).max(200),
  description: z.string().nullable(),
  status: TaskStatus,
  priority: TaskPriority,
  assignee_id: z.string().uuid().nullable(),
  due_date: z.string().datetime().nullable(),
});

export const TaskPatchSchema = TaskUpdateSchema.partial();

export const TaskQuerySchema = z.object({
  page: z.coerce.number().int().min(1).default(1),
  per_page: z.coerce.number().int().min(1).max(100).default(20),
  status: TaskStatus.optional(),
  priority: TaskPriority.optional(),
});

export type Task = z.infer<typeof TaskSchema>;
export type TaskCreate = z.infer<typeof TaskCreateSchema>;
export type TaskQuery = z.infer<typeof TaskQuerySchema>;

पहले/बाद की तुलना

मेट्रिकClaude Code से पहलेClaude Code के बाद
स्कीमा डेफिनेशन समयप्रति एंडपॉइंट 30–45 मिनट5–10 मिनट (प्रॉम्प्ट सहित)
टाइप एरर दरप्रोजेक्ट के बाद में अक्सरशुरू से ही लगभग शून्य
छूटे हुए वैलिडेशन केसहर कोड रिव्यू में पकड़े जातेएज केस अपने आप कवर होते
स्पेक/कोड डिवर्जेंस2–3 हफ्ते में पुराना हो जाताहमेशा सिंक्रोनाइज़ (स्पेक से जनरेट)

4. Vitest के साथ टेस्ट ऑटो-जनरेशन

// src/routes/tasks.test.ts
import { describe, it, expect, vi } from "vitest";
import app from "../index";
import { TaskService } from "../services/taskService";

vi.mock("../services/taskService");

const mockTask = {
  id: "550e8400-e29b-41d4-a716-446655440000",
  title: "टेस्ट टास्क",
  description: "टेस्टिंग के लिए एक टास्क",
  status: "todo" as const,
  priority: "medium" as const,
  assignee_id: null,
  due_date: null,
  created_at: "2026-04-25T00:00:00.000Z",
  updated_at: "2026-04-25T00:00:00.000Z",
};

describe("GET /v1/tasks", () => {
  it("हैप्पी पाथ: टास्क लिस्ट रिटर्न करता है", async () => {
    vi.mocked(TaskService.prototype.findAll).mockResolvedValue({ tasks: [mockTask], total: 1 });
    const res = await app.request("/v1/tasks", { headers: { Authorization: "Bearer valid-token" } });
    expect(res.status).toBe(200);
    const body = await res.json();
    expect(body.data).toHaveLength(1);
  });

  it("एरर: per_page अधिकतम से अधिक", async () => {
    const res = await app.request("/v1/tasks?per_page=101", { headers: { Authorization: "Bearer valid-token" } });
    expect(res.status).toBe(400);
  });
});

describe("POST /v1/tasks", () => {
  it("हैप्पी पाथ: टास्क बनाता है", async () => {
    vi.mocked(TaskService.prototype.create).mockResolvedValue(mockTask);
    const res = await app.request("/v1/tasks", {
      method: "POST",
      headers: { "Content-Type": "application/json", Authorization: "Bearer valid-token" },
      body: JSON.stringify({ title: "नया टास्क" }),
    });
    expect(res.status).toBe(201);
  });

  it("एरर: खाली टाइटल", async () => {
    const res = await app.request("/v1/tasks", {
      method: "POST",
      headers: { "Content-Type": "application/json", Authorization: "Bearer valid-token" },
      body: JSON.stringify({ title: "" }),
    });
    expect(res.status).toBe(400);
  });
});

5. एरर हैंडलिंग पैटर्न

// src/lib/errors.ts
export class AppError extends Error {
  constructor(
    public readonly code: string,
    public readonly message: string,
    public readonly statusCode: number,
    public readonly field?: string
  ) {
    super(message);
    this.name = "AppError";
  }
}

export const Errors = {
  notFound: (resource: string) => new AppError("NOT_FOUND", `${resource} नहीं मिला`, 404),
  unauthorized: () => new AppError("UNAUTHORIZED", "ऑथेंटिकेशन आवश्यक है", 401),
  forbidden: () => new AppError("FORBIDDEN", "आपके पास इस रिसोर्स तक पहुँचने की अनुमति नहीं है", 403),
  conflict: (message: string) => new AppError("CONFLICT", message, 409),
  internal: () => new AppError("INTERNAL_ERROR", "सर्वर में आंतरिक त्रुटि हुई", 500),
};

3 सामान्य गलतियाँ

गलती 1: UUID वैलिडेशन की कमी

Claude Code कभी-कभी :id पाथ पैरामीटर को एक साधारण स्ट्रिंग के रूप में ट्रीट करता है। UUID फॉर्मेट वैलिडेशन के बिना, गलत क्वेरी डेटाबेस तक पहुँच सकती है।

// गलत: रॉ स्ट्रिंग सीधे DB को भेजना
const task = await db.findById(c.req.param("id"));

// सही: पहले UUID फॉर्मेट वैलिडेट करें
const idSchema = z.string().uuid("वैध UUID नहीं है");
const parsed = idSchema.safeParse(c.req.param("id"));
if (!parsed.success) {
  return c.json({ data: null, meta: null, errors: [{ code: "INVALID_ID", message: "अमान्य ID फॉर्मेट" }] }, 400);
}
const task = await db.findById(parsed.data);

गलती 2: Content-Type हेडर वैलिडेशन की कमी

Content-Type: application/json के बिना PUT/POST रिक्वेस्ट में Hono बॉडी को खाली ऑब्जेक्ट मानता है। Zod वैलिडेशन पास हो जाती है और खाली डेटा सेव होता है।

// src/middleware/contentType.ts
import { createMiddleware } from "hono/factory";

export const requireJson = createMiddleware(async (c, next) => {
  if (["POST", "PUT", "PATCH"].includes(c.req.method)) {
    const contentType = c.req.header("Content-Type");
    if (!contentType?.includes("application/json")) {
      return c.json(
        { data: null, meta: null, errors: [{ code: "UNSUPPORTED_MEDIA_TYPE", message: "Content-Type: application/json आवश्यक है" }] },
        415
      );
    }
  }
  await next();
});

गलती 3: डेट फील्ड में टाइमज़ोन समस्या

z.string().datetime() केवल UTC फॉर्मेट स्वीकार करता है। अगर फ्रंटएंड 2026-04-25T14:30:00+05:30 भेजे, तो वह रिजेक्ट हो जाता है।

// गलत
due_date: z.string().datetime()

// सही: टाइमज़ोन ऑफसेट की अनुमति दें
due_date: z.string().datetime({ offset: true }).optional()

सारांश

REST API डेवलपमेंट में Claude Code को इंटीग्रेट करने से प्रोडक्शन तक का समय काफी कम हो जाता है:

  1. पहले OpenAPI स्पेक जनरेट करें — यह सभी बाद के चरणों का आधार बनती है
  2. Zod स्कीमा स्पेक से जनरेट करें — हाथ से लिखने पर डिवर्जेंस होती है
  3. हैप्पी-पाथ, एरर-पाथ और एज केस टेस्ट स्पष्ट रूप से मांगें — बिना निर्देश के केवल हैप्पी पाथ लिखे जाते हैं
  4. गलतियों को प्रॉम्प्ट में पहले से शामिल करें — UUID वैलिडेशन, Content-Type चेक, टाइमज़ोन हैंडलिंग

इस वर्कफ्लो को अपनाने के बाद, प्रति एंडपॉइंट डेवलपमेंट समय में लगभग 70% की कमी आई।

फिर भी, Claude Code के आउटपुट को बिना रिव्यू के प्रोडक्शन में न भेजें। सिक्योरिटी और बिज़नेस लॉजिक को हमेशा मानवीय समीक्षा की जरूरत होती है। Claude Code एक फास्ट फर्स्ट-ड्राफ्ट टूल है; अंतिम गुणवत्ता की जिम्मेदारी डेवलपर की होती है।


संबंधित लेख:

#claude-code #rest-api #openapi #typescript #backend

अपने Claude Code वर्कफ़्लो को अगले स्तर पर ले जाएँ

Claude Code में तुरंत कॉपी-पेस्ट करने योग्य 50 आज़माए हुए प्रॉम्प्ट टेम्पलेट।

मुफ़्त

मुफ़्त PDF: 5 मिनट में Claude Code चीटशीट

बस अपना ईमेल दर्ज करें और हम तुरंत A4 एक-पृष्ठ चीटशीट PDF भेज देंगे।

हम आपकी व्यक्तिगत जानकारी की सुरक्षा करते हैं और स्पैम नहीं भेजते।

Masa

लेखक के बारे में

Masa

Claude Code का गहराई से उपयोग करने वाले इंजीनियर। claudecode-lab.com चलाते हैं, जो 10 भाषाओं में 2,000 से अधिक पेजों वाला टेक मीडिया है।

संबंधित लेख

Claude Code की सम्पूर्ण शुरुआती गाइड 2026 | शून्य से प्रोफेशनल उपयोग तक 7 स्टेप्स में
Tips & Tricks

Claude Code की सम्पूर्ण शुरुआती गाइड 2026 | शून्य से प्रोफेशनल उपयोग तक 7 स्टेप्स में

पहली बार Claude Code उपयोग करने वालों के लिए पूरी गाइड। इंस्टॉलेशन से लेकर असली डेवलपमेंट वर्कफ्लो में शामिल करने तक — Masa के शुरुआती अनुभव के आधार पर।

Claude Code vs Gemini CLI 2026 गहरी तुलना | Google का AI वास्तव में कितना अलग है?
Tips & Tricks

Claude Code vs Gemini CLI 2026 गहरी तुलना | Google का AI वास्तव में कितना अलग है?

DX इंजीनियर Masa द्वारा Claude Code और Gemini CLI की व्यावहारिक तुलना। कीमत, स्वायत्तता, संदर्भ विंडो और इकोसिस्टम का विश्लेषण। सही टूल चुनने के लिए निर्णय फ्लोचार्ट के साथ।