Tips & Tricks (अपडेट: 3/6/2026)

Claude Code से REST API डिजाइन: endpoint, error, pagination और idempotency

Claude Code से coding से पहले REST API डिजाइन करें: OpenAPI, error format, pagination, idempotency और checklist.

Claude Code से REST API डिजाइन: endpoint, error, pagination और idempotency

REST API सिर्फ कुछ routes बना देने से पूरी नहीं हो जाती। implementation से पहले यह तय करना पड़ता है कि resource क्या होगा, कौन सा HTTP method किस operation के लिए इस्तेमाल होगा, failure पर API क्या लौटाएगी, list कैसे paginate होगी, और वही request दोबारा आए तो क्या होगा। अगर ये बातें अस्पष्ट रहें, तो Claude Code तेज़ी से code लिख सकता है, लेकिन frontend, mobile app और partner integration अलग-अलग contract मान लेंगे।

इस लेख का उद्देश्य Claude Code की मदद से coding से पहले REST API design को पक्का करना है। REST का पूरा नाम Representational State Transfer है, लेकिन practical रूप में इसे orders, users और invoices जैसे resources को HTTP rules से operate करने का तरीका समझें। resource वह चीज है जिस पर काम होता है, method वह action है, और status code result का संकेत है।

official reference के लिए MDN के HTTP request methods, HTTP response status codes, और OpenAPI Specification देखें। 3 जून 2026 तक OpenAPI की latest page 3.2.0 दिखाती है; इस article का example openapi: 3.1.0 इस्तेमाल करता है क्योंकि कई linters और generators अभी उसके साथ ज्यादा भरोसेमंद हैं।

implementation के अगले कदम के लिए Claude Code से production API development, Claude Code API testing, और Claude Code code review भी देखें। ready templates और checklists के लिए /products/ और team में API design review standardize करने के लिए /training/ देखें।

पहले शब्दों का अर्थ एक करें

नए developers अक्सर REST terms में उलझते हैं क्योंकि वे एक जैसे लगते हैं। Claude Code को implementation देने से पहले team में इन शब्दों का अर्थ साफ कर लें।

शब्दसरल अर्थउदाहरण
ResourceAPI जिस noun को manage करती हैorders, customers
EndpointURL और HTTP method का जोड़ाGET /v1/orders
MethodHTTP verb जो action बताता हैGET, POST, PATCH
Status codesuccess, bad input, auth missing जैसी स्थिति का number200, 201, 400, 404
Validationrequest सही shape में है या नहीं यह जांचemail format, minimum quantity
Idempotencyवही operation दोहराने पर final state न बदलनाsame key से सिर्फ एक order

Claude Code context पढ़ने में अच्छा है, लेकिन design intent का अनुमान लगाना guarantee नहीं है। “order creation API बनाओ” से /createOrder, /orders/create, या POST /orders कुछ भी बन सकता है। पहले vocabulary और design rules देना generated implementation को काफी बेहतर बनाता है।

तीन use cases से design तय करें

एक ही orders API का design usage के हिसाब से बदलता है।

पहला use case B2B SaaS order ingestion है। अगर partner वही nightly CSV दोबारा भेजता है, तो POST /v1/orders में Idempotency-Key चाहिए, ताकि duplicate orders न बनें। incident recovery में retry बहुत common है, इसलिए idempotency को बाद में जोड़ना मुश्किल होता है।

दूसरा use case admin list API है। कोई staff status=paid से filter करता है, next page पर जाता है, और उसी समय कोई दूसरा order add कर देता है। केवल page=2 से result खिसक सकते हैं। limit और after के साथ cursor pagination रखें, और sort order जैसे createdAt desc, id desc fix करें।

तीसरा use case mobile app API है। अगर पुराने app versions महीनों तक users के phone में रहते हैं, तो response field names अचानक नहीं बदल सकते। नया required field या नया error format आए तो उसे /v2 में रखें, और /v1 contract OpenAPI में बनाए रखें। छोटा optional field जोड़ना आम तौर पर नई version नहीं मांगता।

चौथा common case internal service API है। यहां consumers को साथ में upgrade करना आसान है, लेकिन monitoring और alerts कमजोर हो सकते हैं। internal API में भी inconsistent status codes और error format हर caller से custom exception handling लिखवाते हैं।

Design flow को diagram में देखें

Claude Code को task देने से पहले design को इस क्रम में fix करें। इससे file edit होते समय implementation contract से दूर नहीं जाता।

flowchart TD
  A["Use cases"] --> B["Resources and endpoints"]
  B --> C["OpenAPI contract"]
  C --> D["Errors, pagination, idempotency"]
  D --> E["Claude Code implementation"]
  E --> F["Tests and review"]

Coding से पहले endpoint table freeze करें

पहला deliverable code नहीं, endpoint table है। इसे Claude Code को दें ताकि routing, OpenAPI, tests और documentation एक ही contract से शुरू हों।

उद्देश्यMethod और pathSuccessजरूरी rule
Orders listGET /v1/orders?status=paid&limit=20&after=ord_123200 OKstable sort के साथ cursor pagination
Order createPOST /v1/orders201 CreatedIdempotency-Key लें और Location लौटाएं
Order detailGET /v1/orders/{orderId}200 OKन मिले तो 404
Order updatePATCH /v1/orders/{orderId}200 OKpartial update; empty patch 400
Order cancelPOST /v1/orders/{orderId}/cancel200 OKbusiness state transition को consistent रखें

सामान्य rule है: URL में nouns, method में verbs। लेकिन order cancel जैसे business action को कभी-कभी explicit sub-action के रूप में लिखना forced DELETE से ज्यादा readable होता है। जरूरी बात यह है कि exception को document करें और similar operations में वही pattern रखें।

OpenAPI को design source बनाएं

OpenAPI paths, parameters, requests और responses को machine-readable design document में लिखता है। जब आप Claude Code से कहते हैं कि यह OpenAPI contract source of truth है, तो implementation की freedom सही सीमा में आ जाती है।

openapi: 3.1.0
info:
  title: Acme Orders API
  version: 1.0.0
servers:
  - url: https://api.example.com
paths:
  /v1/orders:
    get:
      operationId: listOrders
      summary: List orders
      parameters:
        - $ref: "#/components/parameters/StatusParam"
        - $ref: "#/components/parameters/LimitParam"
        - $ref: "#/components/parameters/AfterParam"
      responses:
        "200":
          description: Orders are returned in a stable cursor order.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OrderListResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
    post:
      operationId: createOrder
      summary: Create an order
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateOrderRequest"
      responses:
        "201":
          description: Order created.
          headers:
            Location:
              schema:
                type: string
              description: URL of the created order.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OrderResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "409":
          $ref: "#/components/responses/Conflict"
  /v1/orders/{orderId}:
    get:
      operationId: getOrder
      summary: Get one order
      parameters:
        - $ref: "#/components/parameters/OrderId"
      responses:
        "200":
          description: Order found.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OrderResponse"
        "404":
          $ref: "#/components/responses/NotFound"
    patch:
      operationId: updateOrder
      summary: Update mutable order fields
      parameters:
        - $ref: "#/components/parameters/OrderId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateOrderRequest"
      responses:
        "200":
          description: Order updated.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OrderResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "404":
          $ref: "#/components/responses/NotFound"
components:
  parameters:
    OrderId:
      name: orderId
      in: path
      required: true
      schema:
        type: string
    StatusParam:
      name: status
      in: query
      schema:
        type: string
        enum: [draft, paid, canceled]
    LimitParam:
      name: limit
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 20
    AfterParam:
      name: after
      in: query
      schema:
        type: string
      description: Cursor returned by the previous response.
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
        minLength: 16
        maxLength: 128
  schemas:
    CreateOrderRequest:
      type: object
      required: [customerId, items]
      properties:
        customerId:
          type: string
        items:
          type: array
          minItems: 1
          items:
            type: object
            required: [sku, quantity]
            properties:
              sku:
                type: string
              quantity:
                type: integer
                minimum: 1
    UpdateOrderRequest:
      type: object
      minProperties: 1
      properties:
        status:
          type: string
          enum: [draft, paid, canceled]
    OrderResponse:
      type: object
      required: [data]
      properties:
        data:
          $ref: "#/components/schemas/Order"
    OrderListResponse:
      type: object
      required: [data, pageInfo]
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Order"
        pageInfo:
          type: object
          required: [nextCursor, hasMore]
          properties:
            nextCursor:
              type: [string, "null"]
            hasMore:
              type: boolean
    Order:
      type: object
      required: [id, status, totalCents, createdAt]
      properties:
        id:
          type: string
        status:
          type: string
        totalCents:
          type: integer
        createdAt:
          type: string
          format: date-time
    ErrorResponse:
      type: object
      required: [error]
      properties:
        error:
          type: object
          required: [code, message, requestId]
          properties:
            code:
              type: string
            message:
              type: string
            requestId:
              type: string
            details:
              type: array
              items:
                type: object
  responses:
    BadRequest:
      description: Request validation failed.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    Conflict:
      description: Idempotency key conflicts with a different request.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    NotFound:
      description: Resource was not found.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"

इसे openapi.yaml के रूप में save करें और Claude Code को साफ लिखें कि वह इस contract से हटकर implementation propose न करे। इसके बाद npx @redocly/cli lint openapi.yaml जैसे linter से syntax और references check किए जा सकते हैं। अगर OpenAPI से TypeScript types या client generate कर रहे हैं, तो पहले endpoint table का human meaning review करें।

Error और status code standardize करें

Status code HTTP का बाहरी signal है। JSON body वह detail है जिसे इंसान और program पढ़ते हैं। 200 OK के साथ { "success": false } लौटाने से monitoring, SDK और retry logic failure को success समझते हैं। पहले table तय करें: invalid input 400, authentication missing 401, permission missing 403, resource not found 404, duplicate या idempotency conflict 409.

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Request body has invalid fields.",
    "requestId": "req_01J0RESTAPI001",
    "details": [
      {
        "field": "items[0].quantity",
        "reason": "must be greater than or equal to 1"
      }
    ]
  }
}
{
  "error": {
    "code": "IDEMPOTENCY_CONFLICT",
    "message": "The same Idempotency-Key was used with a different request body.",
    "requestId": "req_01J0RESTAPI002"
  }
}
{
  "error": {
    "code": "ORDER_NOT_FOUND",
    "message": "Order was not found.",
    "requestId": "req_01J0RESTAPI003"
  }
}

सरल भाषा में, code program के branch करने के लिए छोटा नाम है, message logs या UI में दिखने वाला explanation है, और requestId server logs खोजने में मदद करता है। details मुख्यतः field-level validation error के लिए रखें।

Pagination, idempotency और versioning को vague न छोड़ें

List APIs में pagination शुरुआत से होनी चाहिए। कम data पर सारे orders लौटाना काम कर सकता है, पर table बढ़ने के बाद response बदलना breaking change बन जाता है। cursor pagination में client पिछली response का nextCursor अगली request के after में भेजता है।

{
  "data": [
    {
      "id": "ord_100",
      "status": "paid",
      "totalCents": 4800,
      "createdAt": "2026-06-03T09:00:00Z"
    }
  ],
  "pageInfo": {
    "nextCursor": "ord_099",
    "hasMore": true
  }
}

Idempotency repeated requests से duplicate effects रोकती है। POST /orders खास तौर पर sensitive है क्योंकि network failure के बाद clients retry करते हैं। Idempotency-Key और request body का hash सीमित समय तक store करें। same key और same body आए तो previous result लौटाएं; same key और different body आए तो 409 लौटाएं।

Versioning consumers को migration time देता है। required response field हटाना, type बदलना, default sort बदलना या request में नया required field जोड़ना breaking change है और /v2 में जाना चाहिए। optional response field जोड़ना सामान्यतः /v1 में रह सकता है।

Claude Code से design review मांगें

implementation से पहले यह concrete prompt दें।

Review this OpenAPI design.
Check:
- Resource names are nouns
- HTTP methods and status codes match MDN semantics
- 400/401/403/404/409/500 errors share the same JSON shape
- List pagination is unambiguous
- POST creation endpoints that need idempotency keys are identified
- No response change breaks the v1 contract
- Return a table of issues to fix before TypeScript implementation and tests

इससे Claude Code file edit करने से पहले design reviewer की तरह काम करता है। implementation तभी मांगें जब reviewed OpenAPI save हो जाए।

आम गलतियां

पहली गलती action-style endpoints हैं। अगर POST /createOrder, POST /updateOrderStatus, और GET /deleteOrder साथ-साथ हैं, तो URL resource और operation साफ नहीं बताता। बेहतर है POST /v1/orders, PATCH /v1/orders/{orderId}, और DELETE /v1/orders/{orderId} इस्तेमाल करें, और exceptions document करें।

दूसरी गलती inconsistent status codes हैं। अगर bad input 500, missing resource 200, और successful creation कभी 200 कभी 201 लौटाए, तो clients सही branch नहीं लिख पाएंगे। success codes को भी standardize करें।

तीसरी गलती ambiguous pagination है। अगर page=2 यह नहीं बताता कि sorting creation time से है या update time से, तो नया data duplicates या skipped rows ला सकता है। sort order, max limit, और next page detection spec में लिखें।

चौथी गलती validation को सिर्फ implementation में छिपाना है। अगर quantity >= 1 code में है लेकिन OpenAPI में नहीं, तो frontend और generated SDK rule reuse नहीं कर पाएंगे। constraints specification और code दोनों में हों।

Review Checklist

  • Resource names consistent plural nouns हैं
  • Methods GET, POST, PATCH, और DELETE semantics से मेल खाते हैं
  • Success codes 200, 201, और 204 को अलग करते हैं
  • 400, 401, 403, 404, 409, और 500 errors का JSON shape समान है
  • List APIs में limit, after, nextCursor, और hasMore हैं
  • limit का default और maximum documented है
  • Create endpoints retry पर duplicate data नहीं बनाते
  • Breaking changes को /v2 में भेजने के criteria लिखे हैं
  • Validation rules OpenAPI में मौजूद हैं
  • Claude Code को task देने से पहले endpoint table और OpenAPI match करते हैं

REST API design सुंदर URLs बनाने का काम नहीं है। यह consumers से किए गए promises को readable text और machine-readable specification में बदलने का काम है। Claude Code implementation तेज करता है, लेकिन system को कौन से promises निभाने हैं, यह इंसानों को पहले तय करना पड़ता है।

Masa की orders API पर इसे आजमाने पर, Claude Code से implementation मांगने से पहले OpenAPI, endpoint table और error JSON तैयार करने से review rework साफ कम हुआ। Design stage में Idempotency-Key और cursor pagination जोड़ने से बाद में duplicate orders और missing list records के लिए patch लगाने की जरूरत नहीं पड़ी।

#claude-code #rest-api #openapi #typescript #backend
मुफ़्त

मुफ़्त PDF: Claude Code cheatsheet

Email डालें और commands, review habits तथा safe workflow वाली एक-page PDF पाएँ.

हम आपका data सुरक्षित रखते हैं और spam नहीं भेजते.

Masa

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

Masa

Claude Code workflow और team adoption पर काम करने वाला engineer.