पाठ 23 / 27
OpenAPI के साथ Contract-First
API को OpenAPI दस्तावेज़ में वर्णित करें और उसे अपने आप lint व diff करें।
एक दस्तावेज़, कई उपयोग
OpenAPI दस्तावेज़ (YAML या JSON) paths, parameters, request व response schemas, errors और सुरक्षा को मशीन-पठनीय रूप में वर्णित करता है। इसे पहले डिज़ाइन करने (contract-first) से टीमें implementation से पहले API की समीक्षा और mock कर सकती हैं, और वही फ़ाइल फिर interactive docs, client SDK और server stub generation, request/response validation, contract tests और versions के बीच तोड़ने वाले बदलाव की जाँच चलाती है। components के अंतर्गत $ref से परिभाषाएँ दोबारा उपयोग करें, हर operation को अनोखा operationId दें, और error responses भी वर्णित करें। Spec को कोड के पास version control में रखें और implementation उससे भटके तो build विफल करें।
वादे को कोड में रखें
मशीन-पठनीय अनुबंध, स्वचालित जाँचें और साझा मानक कई टीमों को एकरूप रखते हैं।
छोटा OpenAPI 3.1 दस्तावेज़
v2 की list और get endpoints को पुनः उपयोग योग्य Item schema, problem+json error और rate-limit response के साथ वर्णित करता है। मैंने इसे अगले snippet में PyYAML से parse किया।
openapi: 3.1.0
info:
title: Items API
version: "2.0.0"
servers:
- url: https://api.example.com
paths:
/v2/items:
get:
operationId: listItems
summary: List items (cursor pagination)
parameters:
- name: limit
in: query
schema: { type: integer, minimum: 1, maximum: 100, default: 20 }
- name: cursor
in: query
schema: { type: string }
responses:
"200":
description: A page of items
content:
application/json:
schema: { $ref: "#/components/schemas/ItemPage" }
"429":
$ref: "#/components/responses/RateLimited"
/v2/items/{id}:
get:
operationId: getItem
parameters:
- name: id
in: path
required: true
schema: { type: integer }
responses:
"200":
description: One item
content:
application/json:
schema: { $ref: "#/components/schemas/Item" }
"404":
description: Not found
content:
application/problem+json:
schema: { $ref: "#/components/schemas/Problem" }
components:
schemas:
Item:
type: object
required: [id, first_name, last_name]
properties:
id: { type: integer }
first_name: { type: string }
last_name: { type: string }
plan: { type: string, enum: [free, pro] }
ItemPage:
type: object
required: [data]
properties:
data:
type: array
items: { $ref: "#/components/schemas/Item" }
next_cursor: { type: [string, "null"] }
Problem:
type: object
required: [title, status]
properties:
type: { type: string }
title: { type: string }
status: { type: integer }
detail: { type: string }
responses:
RateLimited:
description: Too many requests
headers:
Retry-After: { schema: { type: integer } }
Spec की संरचना जाँचना, चलाकर
मैंने यह सादा-Python उदाहरण चलाया। ऊपर के YAML को openapi.yaml नाम से सहेजें; यह script उसे लोड करती है, operations सूचीबद्ध करती है, operationId की अनोखापन जाँचती है और पुष्टि करती है कि सभी 5 $ref संकेतक दस्तावेज़ के भीतर resolve होते हैं। यह सिखाने की जाँच है; असली projects समर्पित validators और linters उपयोग करते हैं।
import yaml
spec = yaml.safe_load(open("openapi.yaml"))
ops, refs = [], []
def walk(o):
if isinstance(o, dict):
if "$ref" in o: refs.append(o["$ref"])
for v in o.values(): walk(v)
elif isinstance(o, list):
for v in o: walk(v)
walk(spec)
for path, item in spec["paths"].items():
for method, op in item.items(): ops.append((method.upper(), path, op["operationId"]))
def resolve(ref):
node = spec
for part in ref.lstrip("#/").split("/"): node = node[part]
return node
missing = [r for r in refs if not _ok(r)] if False else []
for r in refs:
try: resolve(r)
except KeyError: missing.append(r)
print(spec["openapi"], len(spec["paths"]), "paths")
print(ops)
print("unique operationIds:", len({o[2] for o in ops}) == len(ops), "| refs:", len(refs), "| unresolved:", missing)
Output:
3.1.0 2 paths
[('GET', '/v2/items', 'listItems'), ('GET', '/v2/items/{id}', 'getItem')]
unique operationIds: True | refs: 5 | unresolved: []त्वरित जाँच: पहले OpenAPI अनुबंध डिज़ाइन करने का लाभ क्या है?
- टीमें implementation से पहले समीक्षा, mock और कोड generate कर सकती हैं
- यह किसी भी कोड की ज़रूरत हटाता है
- यह APIs को धीमा करता है
- यह सारे bugs रोकता है
Answer
टीमें implementation से पहले समीक्षा, mock और कोड generate कर सकती हैं — साझा, समीक्षा योग्य अनुबंध उत्पादकों और उपभोक्ताओं को जल्दी एकमत करता है।