JSON Toolkit

স্বয়ংক্রিয় JSON Schema কেন বাস্তব ডেটা বারবার প্রত্যাখ্যান করে

সংক্ষেপে: জেনারেট করা স্কিমা প্রায়ই বৈধ ডেটা আটকায়। সমৃদ্ধ নমুনা কেন আরও খারাপ স্কিমা দেয়, তারপর কার্যপ্রণালী: বহু-রেকর্ড স্যাম্পলিং, সেমান্টিক সম্পূর্ণকরণ, এরর চিহ্নিতকরণ।

মধ্যবর্তী~14 মিনিট পড়াপ্রকাশ 2026-10-30আপডেট 2026-10-30
JSON-to-Schema খসড়া ও বাস্তব ডেটার সংঘর্ষের কভার

মূল কথা: আগে হাতে required/optional সীমানা মিলিয়ে নিন — "সব required" বন্ধ করে ৫–২০টি ভিন্ন-আকৃতির রেকর্ড দিন — তারপর স্কিমা জেনারেট করে format, enum ও additionalProperties হাতে যোগ করুন; একটি পূর্ণ-ফিল্ড নমুনা সবসময় অতিরিক্ত কঠোর হবে।

জেনারেটর কেবল আপনি পেস্ট করা একক রেকর্ড দেখতে পায়। "এই রেকর্ডে email আছে" কে "প্রতিটি রেকর্ডে email থাকতে হবে" হিসেবে পড়ে, তাই নমুনা যত পূর্ণ, দাবি তত বেশি।

১. জেনারেটর কাঠামোগত ম্যাপিং করে, ব্যবসা বোঝে না

এক টুকরো JSON জেনারেটরে দিলে এটি ঠিক একটি কাজ করে: মানের কাঠামো হাঁটে আর প্রতিটি নোডকে স্কিমা কি-ওয়ার্ডে অনুবাদ করে। পুরো ম্যাপিং টেবিল স্থির:

নমুনায় মান অনুমিত টাইপ নোট
"hello" {"type": "string"} email, তারিখ, UUID আলাদা করে না
42 {"type": "number"} ইন্টিজার integer হিসেবে অনুমিত হয় না
3.14 {"type": "number"} উপরের মতো
true {"type": "boolean"} —
null {"type": "null"} কেবল null চেনে, "nullable" বোঝে না
[1, "a"] {"type": "array", "items": {"type": ["number", "string"]}} এলিমেন্ট টাইপ union হয়
{"a": 1} {"type": "object", "properties": {...}, "required": [...]} required এখানেই মূল

সব ঝামেলা শেষ সারিতে। required টাইপ থেকে আসে না; আসে "এই নমুনায় এই কি আছে" থেকে। নমুনা একক রেকর্ড হলে সেই বিবৃতি "প্রতিটি কি বাধ্যতামূলক"-এর সমান।

আর বাস্তব API-র ফেরত দেওয়া ডেটার প্রায়ই অর্ধেক ফিল্ড ঐচ্ছিক। সংঘর্ষ এখানেই শুরু।

২. পাঁচটি সম-আকৃতির রেকর্ড, পাঁচটি গ্রহণযোগ্যতা হার

পরিমাপ দিয়ে শুরু করুন। নিচের পাঁচ রেকর্ড দেখে যে কেউ বলবে "এগুলো একই আকৃতি":

[
  {
    "id": 1,
    "name": "Ada",
    "email": "ada@example.com",
    "tags": ["a"],
    "score": 10
  },
  { "id": 2, "name": "Bob", "tags": [], "score": 7 },
  {
    "id": 3,
    "name": "Cy",
    "email": "cy@example.com",
    "tags": ["a", "b"],
    "score": 8.5
  },
  { "id": 4, "name": "Dee", "email": null, "tags": ["c"], "score": 9 },
  {
    "id": 5,
    "name": "Eve",
    "email": "eve@example.com",
    "tags": ["d"],
    "score": 6,
    "admin": true
  }
]

email ৫টির মধ্যে ৩টিতে, admin কেবল একবার, আর রেকর্ড ২-এ tags খালি অ্যারে।

এখন প্রতিটি রেকর্ড আলাদাভাবে স্কিমা জেনারেট করুন, তারপর প্রতিটি ফল দিয়ে পাঁচ রেকর্ড যাচাই করুন (ভ্যালিডেটর: ajv 8):

কোথা থেকে জেনারেট কি-সংখ্যা জেনারেট করা required ৫টির মধ্যে গ্রহণ করে
রেকর্ড ১ ৫ id, name, email, tags, score ৩ রেকর্ড
রেকর্ড ২ ৪ id, name, tags, score ৫ রেকর্ড
রেকর্ড ৩ ৫ id, name, email, tags, score ৩ রেকর্ড
রেকর্ড ৪ ৫ id, name, email, tags, score ১ রেকর্ড
রেকর্ড ৫ ৬ id, name, email, tags, score, admin ১ রেকর্ড

পাঁচটির কোনোটিই সঠিক নয়, কিন্তু যে একমাত্র সব ডেটা গ্রহণ করে তা রেকর্ড ২ থেকে — যে রেকর্ডে email নেই। এটি জেতে সরল কারণে: যে কি কখনো আসে না তা কখনো required-এ লেখা হয় না।

রেকর্ড ৪ আরও শিক্ষণীয়: এর email মান null, তাই জেনারেটর {"type": "null"} হার্ডকোড করে, আর স্ট্রিং emailযুক্ত বাকি চারটি রেকর্ডই প্রত্যাখ্যাত হয়।

৩. "সবচেয়ে পূর্ণ রেকর্ড পেস্ট করো" কেন সবচেয়ে খারাপ

সহজাত ধারণা "সবচেয়ে বেশি ফিল্ডের নমুনা পেস্ট করলে স্কিমা পূর্ণ হবে"। পরিমাপ ঠিক উল্টো দেখায় — আর তৃতীয় পক্ষ বড় নিয়ন্ত্রিত পরীক্ষা চালিয়েছে।

absurdtools ৩০০০টি দৈব "ডেটা পরিবার", প্রতি পরিবারে ৮ রেকর্ড, প্রতিটি ঐচ্ছিক ফিল্ড প্রায় অর্ধেক সময় উপস্থিত, দিয়ে মেপেছে ভিন্ন কি-সংখ্যার নমুনা থেকে জেনারেট করা স্কিমা কতটা ডেটা গ্রহণ করতে পারে:

নমুনার কি-সংখ্যা পরিবারের গৃহীত ডেটার অংশ
২ ১০০.০%
৩ ৫৬.৮%
৪ ৩৪.৮%
৫ ২৩.৪%
৬ ১৭.৭%
৭ ১৪.৯%

সিদ্ধান্ত "সামান্য কমা" নয়, সম্পূর্ণ উল্টো: সর্বনিম্ন নমুনা ৯৫% পরিবারে সবচেয়ে শিথিল স্কিমা তৈরি করেছে, আর সবচেয়ে পূর্ণ নমুনা তা করতে পেরেছে কেবল ০.১% সময়।

কারণ required-এর সেমান্টিক্সে, যা মানে "সব"; ঐচ্ছিকতা কেবল অনুপস্থিতি দিয়ে পর্যবেক্ষণ করা যায়। প্রতিটি ফিল্ডযুক্ত রেকর্ড পেস্ট করলে জেনারেটরকে বলেন "এই কি-গুলোর কোনোটিই বাদ দেওয়া যাবে না"; অনুপস্থিত ফিল্ডযুক্ত রেকর্ড পেস্ট করলে "এই কি অনুপস্থিত হতে পারে"-র প্রমাণ দেন।

এক বাক্যে মনে রাখুন: নমুনার মূল্য সম্পূর্ণতা নয়, বরং কোন অনুপস্থিতি সে ঢাকে।

কত রেকর্ড যথেষ্ট

একই পরীক্ষা দল মিলনের গতিও মেপেছে: "যেকোনো কি required থাকে কেবল যদি এখন পর্যন্ত প্রতিটি রেকর্ডে থাকে" নিয়মে রেকর্ড একের পর এক জমালে, required সত্য required সেটে মিলতে মধ্যমা রেকর্ড সংখ্যা ৩; ৬ রেকর্ড প্রায় নব্বই শতাংশ পরিবার ঢাকে, ১২ সবগুলো ঢাকে।

তাই দৈনন্দিন ৫–১০ রেকর্ড স্যাম্পল করা পরিশ্রমের সেরা মূল্য; জোর করে বিশ বা তার বেশি নিলে খুব কম বাড়তি পাওয়া যায়।

তবে একটি পূর্বশর্ত: এই রেকর্ডগুলো সত্যিই ভিন্ন পরিস্থিতি থেকে আসতে হবে। একই টেমপ্লেট থেকে কপি করা পাঁচ রেকর্ড দ্বিতীয়টি থেকেই নতুন তথ্য দেওয়া বন্ধ করে — তাদের ফিল্ড-সেট অভিন্ন, আর required একটি কি-ও সংকুচিত করতে পারে না।

৪. সমাধান: একসঙ্গে কয়েকটি রেকর্ড দিন, অনুপস্থিতিকে কথা বলতে দিন

একক-রেকর্ড স্যাম্পলিং অগত্যা অতিরিক্ত কঠোর, তাই সঠিক পথ হলো জেনারেটরকে একসঙ্গে কয়েকটি রেকর্ড দেখতে দেওয়া আর "প্রতিটি রেকর্ডে থাকলেই required" নিয়মে required মিলিয়ে নেওয়া।

এই সাইটের জেনারেটর সোজা অ্যারে গ্রহণ করে আর একটি "সব required" টগল আছে। এটি বন্ধ করলে উপস্থিতি-গণনায় সিদ্ধান্ত নেয়: কেবল প্রতিটি রেকর্ডে থাকা কি required-এ লেখা হয়।

আবার সেই পাঁচ রেকর্ড — এবার অ্যারেতে মিলিয়ে একসঙ্গে অনুমান করুন, তারপর items-কে এলিমেন্ট চুক্তি ধরুন:

দেওয়া রেকর্ড অনুমিত required সব ৫টির ভ্যালিডেশন
১ রেকর্ড id, name, email, tags, score ৩ পাস
২ রেকর্ড id, name, tags, score ৪ পাস
৩ রেকর্ড id, name, tags, score ৪ পাস
৪ রেকর্ড id, name, tags, score ৫ পাস
৫ রেকর্ড id, name, tags, score ৫ পাস

চতুর্থ রেকর্ড যোগ হলেই required মিলে যায়, আর পরে বদলায় না। email ও admin সঠিকভাবে properties-এ আছে কিন্তু required-এ নয়। আর রেকর্ড ৪-এর email null হওয়ায় বহু-রেকর্ড অনুমান এটিকে {"type": ["string", "null"]}-এ মিলিয়ে দেয়, তাই স্ট্রিং ও null — দুটোই পাস করে — যা একক-রেকর্ড স্যাম্পলিং কখনো করতে পারে না।

এটি absurdtools-এর "required মধ্যমা ৩ রেকর্ডে মিলে যায়" আবিষ্কারের একই মাত্রার ক্রম।

তবে বহু-রেকর্ড অনুমানের নিজস্ব অন্ধ জায়গা আছে: এই রেকর্ডগুলোতে email যদি প্রতিটিতেই null হয় (ধরা যাক সব অ্যাকাউন্টে প্রোফাইল ভরা নেই), অনুমান হয় {"type": "null"}, আর স্ট্রিং email তবু প্রত্যাখ্যাত। একইভাবে প্রতিটি tags মান খালি অ্যারে হলে এলিমেন্ট টাইপ আদৌ অনুমান করা যায় না।

তাই স্যাম্পলিংয়ে আরও একটি কঠোর দাবি: প্রতিটি ফিল্ডের প্রতিটি রূপ অন্তত একবার আসতে হবে। একটি স্ট্রিং, একটি সংখ্যা, একটি null, একটি খালি অ্যারে আনুন; কোনো রূপ সম্পূর্ণ অনুপস্থিত থাকতে দেবেন না।

সুনির্দিষ্টভাবে:

  1. লগ, মক বা বাস্তব রিকোয়েস্ট থেকে ৫–২০টি রেসপন্স টানুন, আর অস্বাভাবিক সারি (খালি ফিল্ডযুক্ত, null-যুক্ত, খালি অ্যারেয়ুক্ত) অবশ্যই রাখুন;
  2. সেগুলো JSON অ্যারেতে মিলিয়ে জেনারেটরে পেস্ট করুন;
  3. "সব required" বন্ধ করুন আর draft 2020-12 বাছুন;
  4. ফল হলো type: array প্লাস একটি items; items অংশটি একক রেকর্ডের চুক্তি হিসেবে নিন;
  5. সঙ্গে সঙ্গে মূল নমুনাগুলো এই স্কিমা দিয়ে যাচাই করুন — ১০০% পাস করতে হবে। একটি ব্যর্থ হলেও স্যাম্পলিং যথেষ্ট নয়; ফিরে গিয়ে রেকর্ড যোগ করুন।

ধাপ ৫ সবচেয়ে সস্তা স্ব-যাচাই। জেনারেটর আপনি যে ডেটা দিয়েছেন তা-ই accommodate করতে না পারলে স্যাম্পলিং পদ্ধতি ভুল, আর এগোনো অর্থহীন।

৫. চারটি বিষয় জেনারেটর ভরাতে পারে না — হাতে লিখতে হবে

বহু রেকর্ড দেওয়ার পরও নিচেরগুলো অনুমান করা যায় না, হাতে যোগ করতে হবে:

অনুপস্থিত অংশ মাপা আচরণ পরিণতি কীভাবে ঠিক করবেন
স্ট্রিং ফরম্যাট "a@b.com" কেবল {"type": "string"} উৎপন্ন করে "not an email" যাচাই পাস করে "format": "email" যোগ করুন ও format assertion চালু করুন
রেঞ্জ ও এনাম score ০–১০০-এ সীমিত, বা status-এ কেবল তিন মান — দেখতে পায় না ঋণাত্মক সংখ্যা, বিশাল মান ও আবর্জনা এনাম মান — সব পাস minimum / maximum / enum যোগ করুন
অজানা-ফিল্ড নীতি additionalProperties জেনারেট হয় না ভুল বানানের কি নীরবে গৃহীত, যা এররের চেয়ে বেশি বিপজ্জনক কনফিগ-শৈলী ফাইলে "additionalProperties": false যোগ করুন
Nullability ও খালি-সংগ্রহের সেমান্টিক্স null-যুক্ত একক নমুনা {"type": "null"}-এ লক হয়; খালি অ্যারে "items": {} দেয় বৈধ মান প্রত্যাখ্যাত, বা অ্যারে এলিমেন্ট সম্পূর্ণ অসীমিত ["string", "null"] করুন, ও খালি অ্যারেতে প্রকৃত এলিমেন্ট দিন

তৃতীয় সারি আলাদা উল্লেখের যোগ্য: additionalProperties-এর ডিফল্ট মান "অনুমোদন"। মানে যে কনফিগ ফাইল timeout-কে timeuot লিখে ভ্যালিডেশন পাস করে, তারপর রানটাইমে নীরবে কিছুই করে না। কনফিগ-শৈলীর স্কিমায় এটি স্পষ্টভাবে বন্ধ করতে হবে।

format-এরও ফাঁদ আছে: draft 2019-09 থেকে format টীকা শব্দভাণ্ডারের অন্তর্গত, আর ডিফল্টে কেবল টীকা করে, বলবৎ করে না। format: "email" যোগ করার পরও অবৈধ মান পাস করলে দশবারের আটবার ভ্যালিডেটর validateFormats বা সংশ্লিষ্ট format প্লাগইন চালু করেনি — স্কিমা ভুল নয়।

এখানে draft বাছাই নিয়ে নোট: স্কিমা OpenAPI 3.1-এ গেলে draft 2020-12 হতে হবে, কারণ 3.1 সেই সংস্করণ সরাসরি এম্বেড করে; পুরোনো টুলচেইন (Swagger 2.0 ইকোসিস্টেম ও কিছু $ref বাস্তবায়ন) এখনও draft-07 কেন্দ্রিক। $ref-এর পাশের কি-ওয়ার্ড ও অ্যারে-সম্পর্কিত কি-ওয়ার্ডে দুইটির আচরণ আলাদা, তাই এক স্কিমা সেটে মিশাবেন না।

৬. অপ্রকাশিত তৃতীয়-পক্ষ API-তে রেসপন্স নমুনা থেকে চুক্তি উল্টে বের করুন

তৃতীয়-পক্ষ কলব্যাক ইন্টিগ্রেট করা, ডকুমেন্টেশন না লেখা অংশীদারের সঙ্গে কাজ, বা দশ বছরের পুরোনো লিগ্যাসি সিস্টেম রক্ষণাবেক্ষণ — সবই মানে "ডেটা হাতে, স্পেক নেই"। এখানে জেনারেটর নিছক সুবিধা নয়; চুক্তিতে পৌঁছানোর দ্রুততম পথ।

পদ্ধতি উপরের মতোই, দুই বাড়তি অবশ্যক:

এক: সময় ও অবস্থা জুড়ে স্যাম্পল করুন। তৃতীয়-পক্ষের ফিল্ড প্রায়ই ব্যবসায়িক অবস্থার সঙ্গে বদলায় — প্রোমোশনে discount যোগ হয়, রিফান্ড অর্ডারে refundAt, আর এরর রেসপন্সে data একেবারেই থাকে না। একটি স্ন্যাপশট নিলে কেবল একটি অবস্থা দেখেন।

কয়েকটি সফল, কয়েকটি ব্যর্থ ও কয়েকটি খালি ফল একসঙ্গে দিন: error ও data প্রায়ই পরস্পর-একচেটিয়াভাবে আসে, আর বহু-রেকর্ড অনুমান দুইটিকেই properties-এ রাখে কিন্তু required-এর বাইরে রাখে — বাস্তবের সঙ্গে ঠিক মেলে।

দুই: স্কিমা রিপোজিটরিতে রাখুন ও দৈনিক চেক জুড়ে দিন। আজকের বাস্তব রেসপন্স এর বিরুদ্ধে যাচাই করুন, তাহলে ব্যবহারকারীদের আগেই নীরবে ফিল্ড হারানো বা টাইপ বদল জানতে পারবেন।

// Run once a day: contract-drift alert
const drifted = records.filter((record) => !validate(record));

if (drifted.length > 0) {
  console.warn(
    `${drifted.length} responses do not match the contract; first difference:`,
    validate.errors,
  );
}

এই অভ্যাসের মূল্য "হাতে লেখার পরিশ্রম বাঁচানো" নয়, বরং মৌখিক চুক্তিকে চালনাযোগ্য অ্যালার্টে বদলানো। তৃতীয় পক্ষ কখনো আগে বলে না যে ফিল্ড বদলেছে, কিন্তু পরিবর্তন নিশ্চিতভাবে আপনার লগে দেখাবে।

একটি সীমানা স্পষ্ট করুন: উল্টে বের করা স্কিমা বর্ণনা করে অন্য পক্ষ এখন কী ফেরত দেয়, কী প্রতিশ্রুতি দেয় নয়। প্রথমটি মনিটরিংয়ের; কেবল দ্বিতীয়টি চুক্তি বা API ডকুমেন্টেশনে যায়।

৭. সম্পূর্ণকরণের পর ভ্যালিডেশন এররকে নির্দিষ্ট ফিল্ডে ফেরান

স্কিমা ব্যবহারযোগ্য হলে পরের চিন্তা পাঠযোগ্য এরর। ajv এরর অবজেক্টে পাঁচ ফিল্ড, প্রথম চারটি কাজের:

ফিল্ড অর্থ উদাহরণ (minimum: 1 লঙ্ঘনকারী id: 0)
instancePath ডেটায় দোষী মানের JSON Pointer "/id"
schemaPath স্কিমায় ট্রিগার হওয়া নিয়মের অবস্থান "#/properties/id/minimum"
keyword ব্যর্থ বাধ্যবাধকতার নাম "minimum"
params সেই বাধ্যবাধকতার মেশিন-পাঠযোগ্য বিবরণ { "comparison": ">=", "limit": 1 }
message সংস্করণভেদে বদলানো ইংরেজি গদ্য, পার্স করবেন না "must be >= 1"

একটি অসমতা সবচেয়ে সহজে পা পিছলায়: required ব্যর্থ হলে instancePath প্যারেন্ট অবজেক্টে (সাধারণত খালি স্ট্রিং, মানে রুট) ইশারা করে, অনুপস্থিত ফিল্ডে নয়। অনুপস্থিত কি-এর নাম থাকে params.missingProperty-তে। একইভাবে additionalProperties ব্যর্থ হলে বাড়তি কি-এর নাম params.additionalProperty-তে।

তাই এররকে "ফিল্ড → মেসেজ"-এ ম্যাপ করার সময় এই দুই বিশেষ ক্ষেত্র আগে সামলান:

import Ajv from "ajv";

const ajv = new Ajv({ allErrors: true });
const validate = ajv.compile(schema);

/** Convert the ajv error array into { fieldPath: [message] } for form highlighting */
function groupByField(errors) {
  const grouped = {};

  for (const error of errors) {
    // For required and additionalProperties, the offending field lives in params, not in instancePath
    const field =
      error.keyword === "required"
        ? error.params.missingProperty
        : error.keyword === "additionalProperties"
          ? error.params.additionalProperty
          : error.instancePath.replace(/^\//u, "").split("/").join(".") ||
            "(root)";

    (grouped[field] ??= []).push(error.message);
  }

  return grouped;
}

if (!validate(data)) console.log(groupByField(validate.errors));

allErrors: true ঐচ্ছিক নয়। ডিফল্ট কনফিগে ajv প্রথম এররেই থামে, তাই ব্যবহারকারী একটি ফিল্ড ঠিক করে, আবার জমা দেয়, পরের এরর পায়, আর একটি ফর্ম ভরাতে তিন রাউন্ড ট্রিপ লাগে। কাস্টম মেসেজের জন্য ajv-errors ব্যবহার করলে এই ফ্ল্যাগ ছাড়া প্লাগইন নীরবে কেবল কিছু মেসেজ প্রতিস্থাপন করবে।

৮. একটি পুনরায় ব্যবহারযোগ্য রোলআউট প্রক্রিয়া

উপরের ধাপগুলোকে স্থির রুটিনে গেঁথে প্রতিবার নতুন API ইন্টিগ্রেট করার সময় অনুসরণ করুন:

  1. স্যাম্পল: ৫–২০টি বাস্তব রেসপন্স টানুন, সচেতনভাবে খালি ফিল্ড, null, খালি অ্যারে ও বাড়তি ফিল্ডযুক্তগুলো বাছুন;
  2. অনুমান: সেগুলো অ্যারে হিসেবে একসঙ্গে জেনারেটরে পেস্ট করুন, "সব required" বন্ধ করুন, items নিন;
  3. সেমান্টিক্স সম্পূর্ণ করুন: একে একে format, enum, minimum/maximum, minItems ও additionalProperties যোগ করুন;
  4. স্ব-যাচাই: মূল নমুনা ১০০% পাস করতে হবে, নাহলে ধাপ ১-এ ফিরে স্যাম্পল যোগ করুন;
  5. নেতিবাচক প্রমাণ: প্রতিটি বাধ্যবাধকতার জন্য একটি "ব্যর্থ হওয়া উচিত" ইনপুট তৈরি করে নিশ্চিত করুন সত্যিই ব্যর্থ হয় — কেবল পাসিং পথ পরীক্ষা করা পরীক্ষা না করার সমান;
  6. কমিট: স্কিমা ভার্সন কন্ট্রোলে রাখুন, ব্যর্থ নমুনা টেস্ট কেস হিসেবে রাখুন, আর API কোনো ফিল্ড বদলালে প্রথমে টেস্ট চালান।

ধাপ ৫-এর নেতিবাচক টেস্টিং সবচেয়ে সহজে বাদ পড়ে। required-এ একটি কি যোগ করে কখনো যাচাই না করা যে অনুপস্থিত কি এরর দেয়, মানে ভ্যালিডেটর আপনার মানসিক মডেলের সঙ্গে একমত হবে বলে বাজি ধরা।

import { describe, expect, it } from "vitest";

describe("user schema", () => {
  it("accepts a complete record", () => {
    expect(validate({ id: 1, name: "Ada", tags: [], score: 10 })).toBe(true);
  });

  it("rejects a record without name", () => {
    expect(validate({ id: 2, tags: [], score: 7 })).toBe(false);
    // Also assert the reason, so the test doesn't pass because some other field failed
    expect(
      validate.errors?.some((e) => e.params?.missingProperty === "name"),
    ).toBe(true);
  });
});

শেষ দাবিটি গুরুত্বপূর্ণ। কেবল false দাবি করলে স্কিমা ভাঙার পরও টেস্ট সবুজ থাকতে পারে — তখন ব্যর্থতা সম্পূর্ণ ভিন্ন কারণ থেকে আসতে পারে।

৯. সাধারণ প্রশ্ন

জেনারেটরের তৈরি স্কিমা কি সোজা প্রোডাকশনে যেতে পারে

না। এটি কাঠামোর নিছক স্ন্যাপশট। অন্তত format, রেঞ্জ, এনাম ও অজানা-ফিল্ড নীতি যোগ করতে হবে, তারপর মূল নমুনা ও নেতিবাচক নমুনা — দুটোই এর মধ্য দিয়ে চালাতে হবে। জেনারেটর "হাতে properties টাইপ করা ক্লান্তিকর" সমাধান করে, "ব্যবসায়িক নিয়ম ঠিক করা" নয়।

স্কিমা লেখার কি-ওয়ার্ড ব্যবস্থা, $ref ভাগ ও গঠন কি-ওয়ার্ডের জন্য দেখুন JSON Schema: মূল বিষয় থেকে প্রোডাকশন।

সবচেয়ে বেশি ফিল্ডযুক্ত রেকর্ড বেশি ডেটা প্রত্যাখ্যান করে কেন

কারণ required জমা হয় "নমুনায় কী এসেছে" থেকে। পূর্ণ-ফিল্ড নমুনা প্রতিটি ঐচ্ছিক কি-কে বাধ্যতামূলক করে, অথচ বাস্তব ডেটায় সেই কি-গুলোর বেশিরভাগ অনুপস্থিত। বহু রেকর্ড, বা ইচ্ছাকৃতভাবে ফিল্ড বাদ দেওয়া রেকর্ড দেওয়া সবচেয়ে পূর্ণ নমুনার চেয়ে সত্যের কাছে নিয়ে যায়।

ইন্টিজার কি integer হিসেবে অনুমিত হবে

এই সাইটের জেনারেটর তা করে না: ইন্টিজার ও ফ্লোট — দুটোই number আউটপুট দেয়, তাই {"price": 5} থেকে জেনারেট করা স্কিমা 5.99 গ্রহণ করে। এতে "নমুনা দৈবক্রমে ইন্টিজার ছিল, তাই প্রোডাকশন দশমিকযুক্ত দাম প্রত্যাখ্যান করে" ধরনের দুর্ঘটনা এড়ায়। কিছু তৃতীয়-পক্ষ টুল মান থেকে integer অনুমান করে, তাই টাকার ফিল্ডে বিশেষ সতর্ক থাকুন।

সংখ্যার নির্ভুলতা ও টাইপ সীমানার বিবরণে দেখুন ছয় JSON ডেটা টাইপ ও সংখ্যার নির্ভুলতার ফাঁদ।

format যোগ করেছি কিন্তু কোনো প্রভাব নেই

draft 2019-09 থেকে format ডিফল্টে কেবল টীকা। হয় ভ্যালিডেটরে format assertion স্পষ্টভাবে চালু করুন (ajv-তে ajv-formats দরকার), নয় কঠোর বাধ্যবাধকতার জন্য pattern ব্যবহার করুন। যোগ করলেই কিছু আটকাবে ধরে নেবেন না।

required এরর দেখায়, অথচ ফিল্ড স্পষ্টভাবে ডেটায় আছে

আগে instancePath দেখুন। required এরর প্যারেন্ট অবজেক্টে ইশারা করে, মানে অনুপস্থিত কি সেই স্তরে নেই — সাধারণ কারণ ভুল নেস্টিং স্তর (/profile/name রুটের name-এর সমান নয়), কেস-পার্থক্য (userId বনাম userID), বা আপস্ট্রিম সিরিয়ালাইজেশন undefined পুরো ফেলে দেওয়া।

তদন্তের আগে নিশ্চিত করুন ডকুমেন্ট নিজেই বৈধ JSON: কমেন্ট, ট্রেইলিং কমা ইত্যাদি পার্সিং স্তরেই ব্যর্থ হয়, স্কিমা সুযোগ পাওয়ার আগেই। JSON পার্স ও ফরম্যাট সরাসরি দোষী লাইনে ইশারা করে।

কত রেকর্ড স্যাম্পল করব, আর কোন draft ব্যবহার করব?

দৈনন্দিন ৫–১০ রেকর্ড স্যাম্পল সবচেয়ে ভালো মূল্য দেয়; required মধ্যমা ৩ রেকর্ডে মেলে, আর ১২ রেকর্ড প্রতিটি পরিবার ঢাকে। প্রতিটি রেকর্ড সত্যিই ভিন্ন পরিস্থিতি থেকে আসতে হবে, আর প্রতিটি ফিল্ডের প্রতিটি রূপ অন্তত একবার আসতে হবে। draft 2020-12-তে পিন করুন, কারণ OpenAPI 3.1 কেবল সেই সংস্করণ গ্রহণ করে।

উদার additionalProperties ডিফল্ট বেশি বিপজ্জনক কেন?

ডিফল্ট কোনো কি-ওয়ার্ডই দেয় না, তাই ভুল বানানের কি নীরবে গৃহীত হয়, ভ্যালিডেশন পাস করে, তারপর রানটাইমে ব্যর্থ হয় — সরাসরি এররের চেয়ে নির্ণয় করা কঠিন। কনফিগ-শৈলীর স্কিমায় "additionalProperties": false স্পষ্টভাবে সেট করতে হবে, অথচ API স্কিমায় আগে সামঞ্জস্যের দাম বিবেচনা করুন।

উল্টে বের করা স্কিমা কঠোর গেট হিসেবে ব্যবহার করা উচিত?

না। উল্টে বের করা স্কিমা বর্ণনা করে অন্য পক্ষ এখন কী ফেরত দেয়, কী প্রতিশ্রুতি দেয় নয়, তাই এটি মনিটরিং ও ড্রিফট অ্যালার্টে যায়। চুক্তি বা API ডকুমেন্টেশনে যা যায় তা অবশ্যই প্রতিশ্রুত চুক্তি হতে হবে।