टीम सहयोग FAQ: कॉन्ट्रैक्ट, कॉन्फ़िग और Fixtures
मुख्य बात: नामकरण शैली, समय फ़ॉर्मैट, null का अर्थ, enum आकार, कॉन्फ़िग फ़ॉर्मैट, fixture संगठन, और merge conflicts — बारह ऐसे समझौते जिन पर टीमें वाकई बहस करती हैं।

मुख्य बात: इन्हें एक बार टीम की परंपरा में तय करें — {"data":…,"meta":…} envelope के साथ HTTP स्टेटस कोड, पूरी साइट पर एक ही नामकरण शैली, टाइम ज़ोन के साथ RFC 3339 टाइमस्टैम्प, और string enums — फिर हर नए API को उसी कॉन्ट्रैक्ट के सामने विकसित करें, केवल फ़ील्ड जोड़कर, कभी बदलकर या हटाकर नहीं।
इन प्रश्नों का कोई एक सही उत्तर नहीं है, लेकिन टीम के पास एक ही उत्तर होना चाहिए — वरना हर नया API वही बहस फिर शुरू कर देता है।
1. API कॉन्ट्रैक्ट
API कौन-सी संरचना लौटाए?
तीन सामान्य आकार, हर एक की अपनी कीमत:
| आकार | उदाहरण | लाभ | हानि |
|---|---|---|---|
| कच्चा डेटा | [{...}, {...}] |
सरल | मेटाडेटा नहीं रख सकता |
| स्थिर envelope | {"code":0,"message":"ok","data":{...}} |
एकसमान एरर हैंडलिंग | व्यावसायिक कोड HTTP स्टेटस की नकल करता है |
| Resource envelope | {"data":{...},"meta":{...},"links":{...}} |
विस्तारणीय, स्पष्ट अर्थ | नेस्टिंग का एक अतिरिक्त स्तर |
आंतरिक व्यावसायिक API के लिए, "resource envelope + परिणाम बताने वाले HTTP स्टेटस कोड" को प्राथमिकता दें:
{
"data": [{ "id": "1", "name": "示例" }],
"meta": { "total": 128, "page": 2, "pageSize": 20 }
}
एरर के लिए, एक और code नेस्ट करने के बजाय HTTP स्टेटस कोड के साथ संरचित एरर body उपयोग करें:
{
"error": {
"type": "validation_failed",
"message": "请求参数校验失败",
"details": [
{ "path": "/email", "reason": "格式不正确" }
]
}
}
मुख्य बात: HTTP स्टेटस कोड पहले से सफलता या विफलता बताते हैं, इसलिए व्यावसायिक कोड अनावश्यक है। जब दोनों सिस्टम साथ रहते हैं, तो "201 लेकिन code 500 है" जैसी असंगतियाँ लगभग अपरिहार्य होती हैं।
नंगे arrays से बचें। शीर्ष स्तर पर array होने पर आप पेजिनेशन, कुल, या कर्सर नहीं जोड़ सकते, और बाद में जोड़ने का अर्थ है हर caller को बदलना।
फ़ील्ड नाम snake_case उपयोग करें या camelCase?
एक चुनें, पूरी साइट पर लागू करें, और एक ही JSON दस्तावेज़ में कभी मिलाएँ नहीं।
| शैली | सामान्य पारिस्थितिकी | उदाहरण |
|---|---|---|
camelCase |
JavaScript / TypeScript / Java | userName, createdAt |
snake_case |
Python / Ruby / Go (आंशिक) / डेटाबेस कॉलम | user_name, created_at |
kebab-case |
दुर्लभ; हाइफ़न वाली कुंजियाँ उपयोग करना असुविधाजनक | user-name |
मानदंड:
- यह JSON कौन उपभोग करता है: फ़्रंटएंड प्रमुख हो तो camelCase चुनें, डेटा पाइपलाइन और Python सेवाएँ प्रमुख हों तो snake_case;
- क्या यह सीधे डेटाबेस कॉलम से मैप होता है: टेबल संरचनाएँ सीधे पास करते समय snake_case एक रूपांतरण परत बचाता है;
- मौजूदा सिस्टम की निरंतरता: मौजूदा API जो उपयोग करता है वही रखें; संगति सही होने से बड़ी है।
अगर वाकई रूपांतरण करना पड़े, तो उसे सीमा पर (गेटवे या फ़्रंटएंड रिक्वेस्ट परत) करें, न कि toCamelCase कॉल व्यावसायिक कोड में बिखेरें।
समय फ़ील्ड का कौन-सा फ़ॉर्मैट उपयोग करें?
टाइम ज़ोन ऑफ़सेट के साथ RFC 3339 / ISO 8601 स्ट्रिंग उपयोग करें:
{
"createdAt": "2026-10-30T11:37:57+08:00",
"updatedAt": "2026-10-30T03:37:57Z"
}
मुख्य बातें:
- टाइम ज़ोन शामिल करें: ज़ोन के बिना
2026-10-30 11:37:57क्रॉस-टाइम-ज़ोन परिदृश्यों में अनिवार्य रूप से टूटेगा; Zया offset लगातार उपयोग करें: दोनों सही हैं, लेकिन एक ही API में मिलाएँ नहीं;- संख्यात्मक टाइमस्टैम्प से बचें: सेकंड है या मिलीसेकंड, और leap seconds शामिल हैं या नहीं, हर टीम को इसे फिर से व्याख्या करना पड़ता है। जहाँ संक्षिप्तता चाहिए, मिलीसेकंड पूर्णांक उपयोग करें, लेकिन दस्तावेज़ीकरण में इकाई पिन करें।
createdAt / updatedAt / deletedAt जैसे At प्रत्यय वाले फ़ील्ड नाम पसंद करें,
ताकि एक नज़र में स्पष्ट हो कि मान समय का बिंदु है, अवधि नहीं। अवधियों के लिए timeoutMs, ttlSeconds उपयोग करें — इकाई नाम में रखें।
nulls null हों या फ़ील्ड छोड़ा जाए?
यह इस पर निर्भर है कि "यह फ़ील्ड अर्थपूर्ण है" या नहीं:
| अर्थ | रूप | टिप्पणियाँ |
|---|---|---|
| फ़ील्ड मौजूद है लेकिन अभी मान नहीं है | "name": null |
स्पष्ट कहता है "जाँचा गया और यह खाली है" |
| फ़ील्ड इस resource से असंबंधित है | छोड़ दें | उदाहरण के लिए, सामान्य उपयोगकर्ता के पास vipExpireAt नहीं होना चाहिए |
| आंशिक अपडेट (PATCH) | छोड़ना = मत बदलो | यहाँ केवल null का अर्थ "साफ़ करो" है |
तीसरा मामला सबसे अधिक अनदेखा किया जाता है। PATCH रिक्वेस्ट में:
{ "nickname": null }
इसका अर्थ है "nickname साफ़ करें", जबकि रिक्वेस्ट body से nickname छोड़ने का अर्थ है "nickname को छेड़ो नहीं"।
अगर आप दोनों को "साफ़ करो" मानते हैं, तो ईमेल बदलने वाला उपयोगकर्ता अपना nickname मिटा देगा।
एक बार फिर: undefined उपयोग न करें। यह मान्य JSON मान नहीं है, और JSON.stringify कुंजी पूरी तरह गिरा देता है,
इसलिए व्यवहार "छोड़ने" जैसा होता है जबकि कोड दिखता है "खाली मान स्पष्ट रूप से भेजा गया"।
boolean फ़ील्ड का नाम कैसे रखें?
is / has / can / should उपसर्ग उपयोग करें और निषेध से बचें।
{
"isActive": true,
"hasPassword": false,
"canEdit": true
}
तीन सबक:
- निषेध नहीं:
isDisabled: falseपाठक को इसे एक बार उलटने पर मजबूर करता है;isEnabled: trueअधिक सीधा है। दोहरा निषेध (isNotDisabled) एक आपदा है; - booleans के लिए संख्याएँ नहीं:
"enabled": 1हर उपभोक्ता को एक बार=== 1लिखने पर मजबूर करता है; - स्ट्रिंग नहीं:
"enable": "true"JavaScript में truthy है, औरif (data.enable)"false"के लिए भी true है; ऐसे बग खोजना बहुत कठिन होता है।
enum फ़ील्ड संख्याएँ उपयोग करें या स्ट्रिंग?
स्ट्रिंग उपयोग करें, जब तक कोई स्पष्ट स्टोरेज या बैंडविड्थ बाधा न हो।
{ "status": "active" }
{ "status": 1 } की तुलना में स्ट्रिंग जीतती है क्योंकि:
- लॉग, packet captures, और डेटाबेस बिना mapping तालिका देखे सीधे पढ़े जा सकते हैं;
- enum मान जोड़ने से मौजूदा मानों का अर्थ नहीं बदलता (संख्या enum के बीच में मान डालने से सब कुछ खिसक जाता है);
- फ़्रंटएंड को
1 → 'active'mapping सिंक में रखने की ज़रूरत नहीं।
कीमत कुछ अतिरिक्त बाइट्स है, जो संपीड़न के बाद लगभग नगण्य है।
साथ का अभ्यास: string enum मानों के लिए lowercase + underscores उपयोग करें (pending_review), और Schema में enum से उन्हें सीमित करें
ताकि अमान्य मान वैलिडेशन चरण में अस्वीकार हो जाएँ।
2. कॉन्फ़िगरेशन और fixtures
कॉन्फ़िग JSON, YAML, या TOML होना चाहिए?
उद्देश्य के अनुसार चुनें, पसंद के अनुसार नहीं:
| फ़ॉर्मैट | किसके लिए अच्छा | किसके लिए खराब |
|---|---|---|
| JSON | प्रोग्रामीक पठन-लेखन, सख्त संरचित डेटा, Schema वैलिडेशन | बार-बार मैन्युअल संपादन (कमेंट अनुमत नहीं) |
| YAML | गहराई से नेस्टेड डिप्लॉयमेंट कॉन्फ़िग (K8s) | हाथ से लिखा इंडेंटेशन एरर-प्रवण; yes/no booleans बन जाते हैं |
| TOML | सपाट dependency और टूल कॉन्फ़िग (Cargo.toml, pyproject.toml) |
गहरे नेस्टिंग के लिए खराब पठनीयता |
| JSONC | कमेंट चाहने वाला एडिटर कॉन्फ़िग (tsconfig.json) |
सिस्टम सीमाओं के पार जाना |
टीमों में एक सामान्य गलती है व्यावसायिक कॉन्फ़िग YAML में रखना — YAML का अंतर्निहित टाइप रूपांतरण (1.0 संख्या बन जाता है,
NO boolean बन जाता है, 2026-10-30 तारीख़ बन जाता है) अलग-अलग पार्सर में अलग परिणाम देता है।
अगर कॉन्फ़िग को किसी प्रोग्राम द्वारा सख्ती से वैलिडेट करना है, तो JSON + Schema चुनें, और कमेंट _comment फ़ील्ड या अलग दस्तावेज़ों से दर्ज करें।
टेस्ट fixtures कैसे व्यवस्थित करें?
"एक baseline + न्यूनतम अंतर" से व्यवस्थित करें, हर टेस्ट केस के लिए बड़ी JSON कॉपी करके नहीं।
fixtures/
├─ users/
│ ├─ base.json # Baseline user object
│ ├─ no-email.json # केवल email गायब है
│ └─ invalid-age.json # केवल age सीमा से बाहर है
└─ fixtures.ts # लोडिंग और शैलो merging के लिए उपयोगिता फ़ंक्शन
import baseUser from './users/base.json';
export function makeUser(overrides: Partial<User> = {}): User {
return { ...baseUser, ...overrides };
}
इस तरह नए टेस्ट केस को केवल अलग फ़ील्ड लिखने पड़ते हैं, और baseline फ़ील्ड बदलने पर हर केस अपने आप अपडेट हो जाता है।
तीन नियम:
- Fixtures Schema वैलिडेशन पास करें: baseline fixture खुद मान्य डेटा होना चाहिए;
- प्रोडक्शन से असली डेटा एक्सपोर्ट न करें: फ़ोन नंबर, ID नंबर, और पते सब व्यक्तिगत जानकारी हैं;
- Fixtures संस्करण नियंत्रण में रहें लेकिन छोटे रहें: कुछ दर्जन KB से बड़ी एक फ़ाइल pruning या जनरेशन के योग्य है।
JSON फ़ाइलों में merge conflicts कैसे कम करूँ?
JSON में conflicts आसानी से होते हैं: एक फ़ॉर्मैटर पूरी फ़ाइल को एक साथ reflow कर देता है, इसलिए दो लोग एक-एक पंक्ति बदलते हैं तो पूरी फ़ाइल पर conflict होता है।
चार रणनीतियाँ:
- फ़ॉर्मैटिंग एकसमान करें और उसे
.editorconfigमें जोड़ें: लगातार इंडेंटेशन, line endings, और trailing newline असंबंधित diffs से बचाते हैं; - कुंजियाँ क्रमबद्ध करें: वर्णानुक्रम पर सहमत हों ताकि नया फ़ील्ड किसी और के insertion point से न टकराए;
- फ़ाइलें विभाजित करें: एक बड़ी
config.jsonको डोमेन के अनुसार कई फ़ाइलों में तोड़ें, जिससे conflict की सतह स्वाभाविक रूप से घटती है; - "सब कुछ reformat करने" वाले commits से बचें: फ़ॉर्मैटिंग को व्यावसायिक परिवर्तनों से अलग दो commits में रखें ताकि review पठनीय रहे।
अगर टीम lock फ़ाइलें उपयोग करती है (pnpm-lock.yaml, package-lock.json), तो उन्हें हाथ से merge न करें; उन्हें फिर से जनरेट करें:
git checkout --theirs pnpm-lock.yaml
pnpm install
संस्करण संगतता कैसे बनाए रखूँ?
सिद्धांत है "जोड़ें, बदलें नहीं, हटाएँ नहीं"।
| परिवर्तन | संगतता | तरीका |
|---|---|---|
| वैकल्पिक फ़ील्ड जोड़ना | संगत | जोड़ें; उपभोक्ता अज्ञात फ़ील्ड अनदेखा करते हैं |
| आवश्यक फ़ील्ड जोड़ना | असंगत | संस्करण बढ़ाएँ, या डिफ़ॉल्ट दें |
| फ़ील्ड हटाना | असंगत | पहले deprecated चिह्नित करें, callers देखें, फिर हटाएँ |
| फ़ील्ड टाइप बदलना | असंगत | नया फ़ील्ड नाम जोड़ें और संक्रमण के दौरान dual-write करें |
| enum मान सेट बदलना | निर्भर | मान जोड़ना संगत है; हटाना नहीं |
सहायक तंत्र:
- उपभोक्ता "उदार पार्सिंग" उपयोग करें: अज्ञात फ़ील्ड अनदेखा करें और गायब फ़ील्ड के लिए डिफ़ॉल्ट दें;
- सर्वर कुछ समय पुराने फ़ील्ड रखे और संकेत के रूप में रिस्पॉन्स में
Deprecationहेडर लौटाए; - Schema में नए फ़ील्ड को
requiredचिह्नित न करें, और deprecated फ़ील्ड कोdeprecated: trueसे टैग करें।
CI में कॉन्ट्रैक्ट कैसे वैलिडेट करूँ?
Schema को कोड का हिस्सा मानें और हर commit पर उसे वैलिडेट करें।
# सैंपल डेटा को Schema के सामने वैलिडेट करें (ajv-cli उपयोग करके)
npx ajv-cli validate -s schemas/user.json -d "fixtures/users/*.json" --strict=false
CI में तीन चीज़ें चलाएँ:
- Schema की खुद की वैधता:
$schemaघोषणा मान्य है या नहीं और$refresolve होता है या नहीं; - Fixtures Schema से मेल खाते हैं या नहीं: सुनिश्चित करता है कि टेस्ट डेटा drift न हो;
- कॉन्ट्रैक्ट बैकवर्ड संगत है या नहीं: पिछले संस्करण से तुलना करें और हटाए गए फ़ील्ड या बदले टाइप जाँचें।
तीसरे मद के लिए टूलिंग समर्थन चाहिए (जैसे openapi-diff या json-schema-diff);
उसके बिना, कम से कम required arrays और properties कुंजी सेट में परिवर्तनों की तुलना किसी स्क्रिप्ट से करें।
3. त्वरित संदर्भ
| प्रश्न | सिफ़ारिश |
|---|---|
| रिस्पॉन्स संरचना | {"data":..., "meta":...}, एरर के लिए HTTP स्टेटस कोड के साथ |
| नामकरण शैली | camelCase (फ़्रंटएंड-प्रथम) या snake_case (डेटा-प्रथम), पूरी साइट पर एकसमान |
| समय फ़ॉर्मैट | टाइम ज़ोन के साथ RFC 3339 स्ट्रिंग, At में खत्म होने वाले फ़ील्ड नाम |
| Nulls | कोई मान न हो तो null, असंबंधित फ़ील्ड छोड़ें, PATCH में छोड़ने का अर्थ "मत बदलो" |
| Boolean नामकरण | is/has/can उपसर्ग, निषेध नहीं, 0/1 नहीं |
| Enums | स्ट्रिंग, lowercase और underscores, Schema में enum जोड़ें |
| कॉन्फ़िग फ़ॉर्मैट | प्रोग्रामीक वैलिडेशन के लिए JSON, मैन्युअल संपादन के लिए TOML या JSONC |
| Fixtures | एक baseline + न्यूनतम-अंतर overrides, Schema के सामने मान्य |
| Merge conflicts | फ़ॉर्मैटिंग एकसमान करें, कुंजियाँ क्रमबद्ध करें, फ़ाइलें विभाजित करें |
| संस्करण संगतता | जोड़ें, बदलें नहीं, हटाएँ नहीं; हटाने से पहले deprecated चिह्नित करें |