additionalProperties से ऑब्जेक्ट बंद न करें तो Schema वैलिडेशन बेमानी है
मुख्य बात: वैलिडेशन पास होना साफ़ डेटा की गारंटी नहीं है। Pydantic डिफ़ॉल्ट रूप से अनजान फ़ील्ड को नज़रअंदाज़ करता है, Zod उन्हें हटा देता है, Ajv छोड़ देता है — झूठे पैरामीटर और टाइपो कुंजियाँ चुपचाप निकल जाती हैं। यह लेख मौन स्वीकृति के तीन रूप दिखाता है और पूरे तरीके देता है: ऑब्जेक्ट बंद करना, कोअर्सन नियंत्रित करना, हर नेस्टिंग स्तर कसना।

निष्कर्ष: डिफ़ॉल्ट रूप से वैलिडेटर अघोषित फ़ील्ड को अस्वीकार नहीं करते, नज़रअंदाज़ करते हैं। additionalProperties: false के बिना वैलिडेशन केवल यह सिद्ध करता है कि घोषित फ़ील्ठ ठीक हैं।
वैलिडेटर का सबसे खतरनाक व्यवहार त्रुटि उठाना नहीं, चुप रहना है। टाइपो कुंजी या मॉडल द्वारा गढ़ा पैरामीटर वैलिडेशन से चुपचाप गुज़रता है और बिज़नेस लॉजिक में फटता है।
एक: वह वैलिडेशन जो "पास" हो जाता है
{
"type": "object",
"properties": {
"order_id": { "type": "string" },
"amount": { "type": "number" }
},
"required": ["order_id", "amount"]
}
{"order_id": "A1", "amount": 50, "reasn_code": "damaged"} भेजें — तीसरी कुंजी reason_code की टाइपो है। Ajv के डिफ़ॉल्ट कॉन्फ़िगरेशन में परिणाम पास है। अतिरिक्त फ़ील्ड न अस्वीकृत होता है, न चिह्नित।
JSON Schema विनिर्देश में additionalProperties का डिफ़ॉल्ट true है: अघोषित फ़ील्ड अनुमत हैं।
दो: मौन के तीन रूप
| रनटाइम | डिफ़ॉल्ट व्यवहार | परिणाम |
|---|---|---|
| Ajv (JS) | छोड़ देता है | गंदा डेटा लॉजिक तक पहुँचता है |
Zod z.object |
हटा देता है | फ़ील्ड गायब, ऑब्जेक्ट छोटा |
| Pydantic v2 | नज़रअंदाज़ (extra="ignore") |
वही, लॉग में कोई निशान नहीं |
हटाना छोड़ने से ज़्यादा छिपा हुआ है। दोनों लाइब्रेरी डिफ़ॉल्ट रूप से उसी तरह — चुपचाप — विफल होती हैं।
तीन: LLM टूल कॉल समस्या बढ़ाते हैं
तर्क मॉडल बनाता है: फ़ील्ड नाम गढ़ता है, संख्या की जगह "3" भेजता है। प्लेटफ़ॉर्म पैरामीटर JSON Schema में परिभाषित करते हैं, पर डिफ़ॉल्ट रूप से schema बंद करने को मजबूर नहीं करते — strict मोड स्पष्ट रूप से चालू करना पड़ता है, और व्याकरणिक प्रतिबंध केवल मॉडल के सीधे आउटपुट पर लागू होते हैं।
{
"order_id": 4411,
"refund_amount_usd": 50,
"reason_code": "damaged",
"urgent": "yes"
}
ऑब्जेक्ट बंद करने पर reason_code और urgent अस्वीकृत होते हैं और त्रुटि /reason_code पथ की ओर इशारा करती है।
चार: कैसे बंद करें
Ajv: ऑब्जेक्ट नोड पर additionalProperties: false जोड़ें।
import Ajv from "ajv";
const ajv = new Ajv({ allErrors: true });
const schema = {
type: "object",
properties: { order_id: { type: "string" }, amount: { type: "number" } },
required: ["order_id", "amount"],
additionalProperties: false,
};
const validate = ajv.compile(schema);
validate({ order_id: "A1", amount: 50, reasn_code: "x" }); // false
Zod: z.strictObject या .strict()। Pydantic: ConfigDict(extra="forbid")।
साझा नियम: बंद करना प्रति स्तर होता है। हर नेस्टेड ऑब्जेक्ट को अपने additionalProperties: false की आवश्यकता है।
पाँच: कोअर्सन नीति
Pydantic का lax मोड "5" को 5 में बदलता है। तीन नीतियाँ: सख्त (गलत प्रकार अस्वीकार), नियंत्रित (केवल स्पष्ट सीमित रूपांतरण), खुला (केवल आंतरिक डेटा)। अविश्वसनीय इनपुट के लिए पहली या दूसरी चुनें और परीक्षणों में दर्ज करें।
छह: नेस्टिंग चेकलिस्ट
| बिंदु | कार्य |
|---|---|
| रूट ऑब्जेक्ट | additionalProperties: false |
| हर नेस्टेड ऑब्जेक्ट | वही |
| ऐरे तत्व | items के ऑब्जेक्ट भी बंद करें |
| Enum और सीमाएँ | enum, minimum/maximum जोड़ें |
| जनित स्कीमा | हाथ से पूरा करें |
सात: अस्वीकृति के बाद
allErrors: true सभी उल्लंघनकारी फ़ील्ड एक साथ बताता है; verbose: true पथ देता है। सिंटैक्स समस्याएँ schema वैलिडेशन से पहले parser में पकड़ी जानी चाहिए।
सामान्य प्रश्न
बहुत सख्त नहीं?
अनुबंध पर निर्भर। अपने इनपुट के लिए बंद करें; विस्तार-योग्य तीसरे पक्ष के डेटा के लिए केवल कोर बंद करें और विस्तार क्षेत्र अलग करें।
Zod का strip अधिक सुरक्षित नहीं?
नहीं: वह डाउनस्ट्रीम की रक्षा करता है पर कॉलर को नुकसान पहुँचाता है। त्रुटियाँ जल्दी और स्पष्ट रूप से सामने आनी चाहिए।
प्लेटफ़ॉर्म का strict मोड स्थानीय वैलिडेशन का विकल्प?
नहीं। schema स्वयं खुला हो सकता है और व्याकरण टूल तर्कों को कवर नहीं कर सकता।
बंद करने के बाद पुराना डेटा थोक में विफल?
यही दिखाना था। allErrors से सूची बनाएँ, हानिरहित फ़ील्ड जोड़ें, हानिकारक सुधारें।
एक-पंक्ति समाधान?
नहीं, पर न्यूनतम कदम: हर type: "object" के साथ additionalProperties: false होना सत्यापित करें।