المقالات

إنشاء فئات ⁦C#⁩ وPython وDart من أمثلة JSON

استنتج النماذج المتداخلة والمجموعات والحقول التي قد تقبل null وشيفرة ربط JSON من مثال تمثيلي، من دون التعامل مع الناتج بوصفه عقد API كاملاً.

نُشر في حُدّث في قراءة 7 دقائق

الناشر TOOLFINAفُحصت المصادر وسلوك الأداة في تاريخ التحديث.

تبدأ النماذج المنشأة من دليل لا من يقين كامل

تمثل استجابة JSON بيانات فعلية، لا تعريفاً كاملاً للأنواع. فهي تعرض القيم التي ظهرت في حمولة واحدة، بينما يجب أن يغطي نموذج ⁦C#⁩ أو Python أو Dart كل قيمة قد يستقبلها التطبيق. تشير `42` مثلاً إلى حقل صحيح، وتشير `4.8` إلى عدد عشري، لكنهما لا يوضحان ما إذا كانت الخدمة قد تعيد null لاحقاً أو تحذف الحقل أو ترسل رقماً أكبر. وحتى النص الذي يبدو كتاريخ يظل نصاً في JSON ما لم يمنحه عقد API معنى أدق. لذلك يعتمد التوليد على ما تثبته العينة، ويترك القرارات الدلالية للمراجعة.

تختلف طريقة تمثيل هذه المعلومات من لغة إلى أخرى. تستخدم ⁦C#⁩ عادة خصائص PascalCase وسمات `System.Text.Json` للحفاظ على مفاتيح JSON الأصلية. وتستخدم dataclasses في Python حقولاً موصوفة بالأنواع، لكن تلميحات الأنواع تفيد أدوات الفحص ولا تفرض تحققاً وقت التشغيل؛ لذلك توضح دالتا `from_dict` و`to_dict` عملية الربط من دون حزمة إضافية. أما Dart فتستخدم UpperCamelCase لأسماء الأنواع وlowerCamelCase للحقول، إلى جانب أنواع تقبل null ودالتي `fromJson` و`toJson` للتسلسل اليدوي. ينبغي للمولّد اتباع أسلوب كل لغة، لا تكرار القالب نفسه بعد تغيير الأسماء.

مولّد فئات ⁦C#⁩ وPython وDart من JSON: الطريقة والافتراضات

ابدأ بتحليل العينة وفق صيغة JSON الصارمة، ثم صنّف كل قيمة إلى null أو قيمة منطقية أو عدد صحيح أو عدد عام أو نص أو كائن أو مصفوفة. تتبع الأداة الكائنات المتداخلة وتشتق أسماء الأنواع الفرعية من مفاتيحها. وعندما تحتوي مصفوفة على عدة كائنات، تقارن الأداة جميع العناصر بدلاً من الاكتفاء بالأول: تدمج الحقول المتطابقة، وتوسّع النوع الرقمي إذا اجتمعت أعداد صحيحة وعشرية، وتجعل الحقل قابلاً لقبول null إذا ظهرت له قيمة null أو غاب عن عنصر آخر. تحتفظ المصفوفة المتجانسة بنوع عناصرها، بينما تستخدم المصفوفات الفارغة أو القيم غير المتوافقة نوعاً عاماً يناسب اللغة. وفي النهاية تُصحح أسماء المعرّفات، وتُحل تعارضات الأسماء، وتُحفظ مفاتيح JSON الأصلية في شيفرة الربط، ويُنشأ غلاف أو اسم مستعار إذا كانت الحمولة مصفوفة في مستواها الأعلى.

يحدد ECMA-404 صيغة JSON، لكنه لا يفرض طريقة لتحويل القيم إلى أنواع في لغة برمجة؛ لذلك يجب أن توضح أي أداة تعتمد على العينات قواعد الاستنتاج التي تتبعها. ويوضح توثيق Microsoft أن `JsonPropertyName` يحدد اسم خاصية JSON في اتجاهي التسلسل وفك التسلسل. ويبين توثيق Python أن dataclasses تنشئ دوالها من الحقول الموصوفة بالأنواع، مع بقاء تلميحات الأنواع غير ملزمة وقت التشغيل. ويعرض دليل Flutter دالتي `fromJson` و`toJson` اليدويتين للمشروعات الصغيرة، ويوصي بالتوليد الآلي في الأنظمة الأكبر. أما Effective Dart فيقدم قواعد UpperCamelCase وlowerCamelCase التي يتبعها ناتج Dart.

مثال قابل للتحقق باستخدام مولّد فئات ⁦C#⁩ وPython وDart من JSON

تأمل هذين العنصرين في مصفوفة: `[{"id":1,"name":"A"},{"id":2,"score":4.5}]`. يظهر `id` كعدد صحيح مطلوب في العنصرين. وبما أن `name` غائب عن العنصر الثاني، فيجب أن يكون الحقل اختيارياً. وينطبق الأمر نفسه على `score` لأنه لا يظهر إلا في العنصر الثاني. تدمج الأداة العنصرين في نموذج واحد بدلاً من إنشاء فئة مستقلة لكل عنصر. في ⁦C#⁩ قد ينتج عن ذلك خاصيتان من النوعين `string?` و`double?`، وفي Python حقول تنتهي بـ`| None = None`، وفي Dart حقول من النوعين `String?` و`double?`. وتظل مفاتيح JSON الأصلية محفوظة حتى إذا اتبعت أسماء الحقول الناتجة قواعد كتابة مختلفة.

يمكن تلخيص قاعدة الدمج هكذا: `نوع الحقل المرصود = اتحاد القيم المتوافقة في العينة + احتمال الغياب`. تضيف null قابلية قبولها إلى النوع المعروف بدلاً من استبداله. وإذا اجتمع عدد صحيح مع عدد عشري، تستخدم الأداة نوعاً رقمياً أعم. وتدمج الكائنات حقولها المتداخلة، كما تدمج المصفوفات أنواع عناصرها بالقاعدة نفسها. أما القيم غير المتوافقة، مثل رقم وكائن في الموضع نفسه، فتتحول إلى `object` أو `Any` أو `dynamic` بحسب اللغة. ولا تحاول الأداة تخمين enum أو التواريخ أو UUID أو القيم المالية أو معرّفات النطاق من شكل النص وحده، لأن ذلك يتطلب معرفة بعقد API لا توفرها صيغة JSON.

مواضع تحتاج إلى عناية إضافية في مولّد فئات ⁦C#⁩ وPython وDart من JSON

لا تكشف المصفوفة الفارغة نوع عناصرها، كما أن الحقل الذي لا يظهر إلا بقيمة null لا يقدم نوعاً فعلياً للقيمة. وتمثل مفاتيح JSON المكررة حالة خادعة؛ فالمحللات المعتادة تحتفظ بآخر قيمة فقط، ولا يستطيع المولّد التحذير من القيم التي استُبدلت أثناء التحليل. وقد تتجاوز الأعداد الصحيحة الكبيرة جداً مجال الدقة الرقمية في المتصفح قبل اختيار نوع اللغة المستهدفة. أما المفاتيح التي تتضمن مسافات أو علامات ترقيم أو كلمات محجوزة أو أرقاماً في بدايتها أو نصاً غير لاتيني، فتحتاج إلى معرّفات صالحة وربط صريح بالمفتاح الأصلي. ومن الأفضل اختصار الحمولات شديدة العمق أو كثيرة الحقول إلى بيانات اختبار تمثيلية حتى تظل الأداة سريعة. ونجاح إنشاء الشيفرة لا يعني بالضرورة أنها ستُترجم في كل إصدار من اللغة أو ستطابق سلوكاً غير موثق للخادم.

ترجم الملف المنشأ أو حلّله، واختبر فك التسلسل والتسلسل باستخدام أكثر من حمولة حقيقية، ثم قارن الحقول الاختيارية بتوثيق API أو مخططه. وانتبه إلى خطأ متكرر: اعتبار استجابة ناجحة واحدة عقداً كاملاً، خصوصاً عندما قد تحذف الاستجابات اللاحقة حقولاً أو تعيد null أو تغير شكل الأرقام أو تضيف أشكال كائنات جديدة.

فحوص قبل اعتماد النتيجة

  • كائن JSON أو مصفوفة صالحة حتى مليون حرف، واسم للنوع الجذري، ولغة مستهدفة، ونطاق أو مساحة أسماء اختيارية، وخيار اختياري لإضافة شيفرة ربط JSON.
  • ترجم الملف المنشأ أو حلّله، واختبر فك التسلسل والتسلسل باستخدام أكثر من حمولة حقيقية، ثم قارن الحقول الاختيارية بتوثيق API أو مخططه.
  • لا يستطيع الاستنتاج من العينة اكتشاف الاختلافات غير الموثقة أو تمييز كل معنى للنصوص أو استعادة دقة رقمية فُقدت أثناء تحليل JSON أو استبدال JSON Schema أو عقد OpenAPI تتم صيانته.
  • احتفظ بالحمولة المصدرية واسم النوع الرئيسي واللغة المستهدفة وإعدادات المولّد وبيانات الاختبار بجانب الشيفرة المعتمدة حتى يمكن مراجعة تغييرات API لاحقاً.
  • نسق JSON المصدر وتحقق منه أولاً وافحص حقول Base64 بصورة منفصلة ولا تعد التوليد إلا بعد مقارنة الحمولة الجديدة ببيانات الاختبار الإنتاجية الحالية.

مصادر مولّد فئات ⁦C#⁩ وPython وDart من JSON

استخدم مولّد فئات ⁦C#⁩ وPython وDart من JSON من TOOLFINA

افتح مولّد الفئات من JSON في TOOLFINA، ثم الصق كائناً أو مصفوفة صالحة أو اختر ملف `.json` من جهازك. أدخل اسماً واضحاً للنوع الرئيسي، واختر ⁦C#⁩ أو Python أو Dart. فعّل شيفرة ربط JSON إذا احتاجت النماذج إلى قراءة المفاتيح الأصلية. حقل النطاق اختياري؛ إذ يصبح مساحة أسماء ومسار مجلدات في ⁦C#⁩، أو مجلد حزمة بصيغة snake_case في Python وDart. أنشئ الشيفرة ووسّع مساحة العمل عند الحاجة، ثم راجع الحقول التي قد تقبل null والأنواع العامة وأسماء الأنواع المتداخلة والمجموعات. انسخ الناتج المجمّع أو نزّله، أو نزّل ملف ZIP إذا أردت ملفاً مستقلاً لكل فئة منشأة. وبعد ذلك شغّل أدوات الترجمة والتحليل والتنسيق والاختبارات في مشروعك.

المدخلات: كائن JSON أو مصفوفة بصيغة صحيحة، بحد أقصى مليون حرف، مع اسم للنوع الرئيسي ونطاق اختياري. وتفرض الأداة حدوداً على العمق وعدد الحقول والأنواع لحماية المتصفح. المخرجات: معاينة مجمّعة للشيفرة، مع خيار تنزيل ملف ZIP يحتوي على ملف لكل نوع منشأ. تستخدم ملفات `.cs` أسماء PascalCase، بينما تستخدم ملفات `.py` و`.dart` أسماء snake_case. تعتمد ⁦C#⁩ على `System.Text.Json` المدمجة، وتعتمد Python على `dataclasses` و`typing` من المكتبة القياسية، بينما تستخدم Dart تحويلاً يدوياً للخرائط. لا تجلب الأداة البيانات من رابط، ولا تنفذ JSON، ولا تتحقق منه مقابل مخطط، ولا تفترض أن عينة واحدة تغطي كل استجابات API في بيئة الإنتاج.

يُحلَّل إدخال JSON وتُنشأ النماذج محلياً داخل المتصفح، ولا ترفعه TOOLFINA أو تخزنه أو تنفذه. يحلل المتصفح JSON الصارم ويمر على القيم المتداخلة ويدمج عينات الكائنات في المصفوفات ويوسع الأنواع الرقمية المتوافقة ويحدد الحقول الفارغة أو الناقصة ثم ينشئ أسماء مناسبة لكل لغة وربطاً صريحاً بالمفاتيح.

جرّب هذه الأداة

حوّل كائن JSON أو مصفوفة إلى نماذج بيانات محددة الأنواع للغات ⁦C#⁩ وPython وDart، مع فئات متداخلة وحقول تقبل null وربط JSON وإمكانية تنزيل ملف ZIP يضم الملفات المنفصلة.

مولّد فئات ⁦C#⁩ وPython وDart من JSON

أدوات ذات صلة