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"} পাঠান — তৃতীয় কী টাইপো। 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 আছে কিনা যাচাই করুন।