JSONTech

Generate Typed Code from JSON — TypeScript, Python, Go, Rust & More

Convert JSON to typed code in 8 programming languages. See how type inference works, with before-and-after examples for TypeScript interfaces, Python dataclasses, Go structs, Rust serde, and more.

فريق JSONTechMarch 25, 202611 min

لماذا توليد الشيفرة من JSON؟

كل مشروع يستهلك واجهة برمجة تطبيقات JSON يحتاج في النهاية إلى نماذج ذات نوع محدد. تقوم بنسخ استجابة نموذجية إلى محررك، وتفحص الحقول، وتبدأ في كتابة واجهة أو هيكل يدويًا. هذا يعمل — حتى يصبح الحمولة تحتوي على 40 حقلًا، وثلاث مستويات من التعشيش، ومصفوفة من الكائنات المتعددة الأشكال. ثم يصبح الأمر مملًا، عرضة للأخطاء، وبطيئًا.

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

  • توفير الوقت — توليد الأنواع لحمولة تحتوي على 50 حقلًا يستغرق ثوانٍ بدلاً من دقائق.
  • أمان النوع — يقوم المترجم أو وقت التشغيل بالكشف عن عدم التطابقات قبل أن تصل إلى الإنتاج.
  • تقليل الشيفرة النمطية — لا مزيد من كتابة الجلب، والتعيين، وعلامات JSON، أو تعليقات serde يدويًا.
  • التناسق — يحصل كل عضو في الفريق على نفس النماذج من نفس بيانات المصدر.

كيف يعمل استنتاج النوع

يقوم مولد JSON إلى الشيفرة بقراءة بيانات النموذج الخاصة بك واستنتاج نوع لكل قيمة. تصبح السلاسل string، وتصبح الأرقام int أو float اعتمادًا على وجود نقطة عشرية، وتُطابق القيم المنطقية مباشرة، وينتج null غلافًا اختياريًا/قابلًا للإلغاء. تصبح الكائنات أنواعًا مسماة (هياكل، فئات، واجهات)، وتصبح المصفوفات مجموعات ذات نوع مما تكون عناصرها.

إليك كيف تتطابق أنواع JSON عبر اللغات:

نوع JSONTypeScriptPythonJavaGoRustSwift
سلسلةstringstrStringstringStringString
رقم (int)numberintintint64i64Int
رقم (float)numberfloatdoublefloat64f64Double
منطقيbooleanboolbooleanboolboolBool
nullnullNonenull*T (مؤشر)Option<T>T?
كائنinterfacedataclassclass (POJO)structstructstruct (Codable)
مصفوفةT[]list[T]List<T>[]TVec<T>[T]

الرؤية الرئيسية: يعرف المولد فقط ما يراه. إذا كانت بيانات النموذج لديك تحتوي على 42 لحقل يمكن أن يكون أيضًا 42.5، سيختار المولد int بدلاً من float. استخدم بيانات نموذج تمثيلية للحصول على أنواع دقيقة.

نموذج الإدخال

سنستخدم هذا JSON في جميع الأمثلة أدناه. يغطي السلاسل، والأرقام، والقيم المنطقية، وكائنًا متداخلًا، ومصفوفة:

{
  "id": 1,
  "name": "Alice Johnson",
  "email": "alice@example.com",
  "active": true,
  "score": 97.5,
  "address": {
    "street": "123 Main St",
    "city": "Portland",
    "zip": "97201"
  },
  "tags": ["admin", "editor"]
}

واجهات TypeScript من JSON

TypeScript هي الهدف الأكثر شيوعًا. يقوم المولد بإنشاء واجهة لكل كائن، باستخدام أسماء الحقول كمفاتيح للخصائص:

interface Address {
  street: string;
  city: string;
  zip: string;
}

interface Root {
  id: number;
  name: string;
  email: string;
  active: boolean;
  score: number;
  address: Address;
  tags: string[];
}

كل حقل له نوع محدد، ويحصل الكائن المتداخل address على واجهته الخاصة، ويتم استنتاج tags كـ string[] من محتوياته. يمكنك لصق هذا مباشرة في مشروعك وبدء استخدامه مع إكمال تلقائي كامل وفحوصات في وقت الترجمة.

فئات Python من JSON

تقوم الزخرفة @dataclass في Python بإنشاء __init__، و__repr__، وطرق المقارنة تلقائيًا. بالاقتران مع تلميحات النوع، إنها أنظف طريقة لتعريف نماذج JSON في Python:

from dataclasses import dataclass

@dataclass
class Address:
    street: str
    city: str
    zip: str

@dataclass
class Root:
    id: int
    name: str
    email: str
    active: bool
    score: float
    address: Address
    tags: list[str]

قم بإقران هذا مع مكتبة مثل dacite أو cattrs لتحويل قواميس JSON مباشرة إلى هذه الفئات.

POJOs Java من JSON

تتطلب Java مزيدًا من الطقوس — الحقول، ومنشئ، وجلب/تعيين. يوفر المولد أكبر قدر من الوقت هنا:

public class Address {
    private String street;
    private String city;
    private String zip;

    public String getStreet() { return street; }
    public void setStreet(String street) { this.street = street; }
    public String getCity() { return city; }
    public void setCity(String city) { this.city = city; }
    public String getZip() { return zip; }
    public void setZip(String zip) { this.zip = zip; }
}

public class Root {
    private int id;
    private String name;
    private String email;
    private boolean active;
    private double score;
    private Address address;
    private List<String> tags;

    // getters and setters...
}

تعمل POJOs المولدة مباشرة مع Jackson، Gson، أو أي مكتبة تسلسل JSON أخرى في نظام Java البيئي.

هياكل Go من JSON

تستخدم هياكل Go علامات الحقول للتحكم في تحويل JSON. ينتج المولد Go بطريقة نموذجية مع حقول مصدرة وعلامات json:"...":

type Address struct {
    Street string `json:"street"`
    City   string `json:"city"`
    Zip    string `json:"zip"`
}

type Root struct {
    ID      int64    `json:"id"`
    Name    string   `json:"name"`
    Email   string   `json:"email"`
    Active  bool     `json:"active"`
    Score   float64  `json:"score"`
    Address Address  `json:"address"`
    Tags    []string `json:"tags"`
}

تضمن العلامات أن json.Unmarshal يطابق مفاتيح JSON الصغيرة مع الحقول المصدرة (الكبيرة) في Go. يتم تلقائيًا تحويل أسماء الحقول إلى PascalCase، ويصبح id ID وفقًا لأساليب التسمية في Go.

هياكل Rust من JSON

تستخدم Rust مكتبة serde للتسلسل. يضيف المولد الماكرو اللازمة:

use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct Address {
    pub street: String,
    pub city: String,
    pub zip: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Root {
    pub id: i64,
    pub name: String,
    pub email: String,
    pub active: bool,
    pub score: f64,
    pub address: Address,
    pub tags: Vec<String>,
}

مع serde_json، يمكنك تحويل سلسلة JSON إلى هذه الهياكل بدعوة واحدة لـ serde_json::from_str. يفرض المترجم أن كل حقل موجود ومحدد بشكل صحيح.

Swift Codable من JSON

يمكن بروتوكول Codable في Swift من الترميز وفك الترميز المدمج لـ JSON بدون أي تبعيات خارجية:

struct Address: Codable {
    let street: String
    let city: String
    let zip: String
}

struct Root: Codable {
    let id: Int
    let name: String
    let email: String
    let active: Bool
    let score: Double
    let address: Address
    let tags: [String]
}

استخدم JSONDecoder().decode(Root.self, from: data) لتحليل بيانات JSON مباشرة إلى هذه الهياكل. يستنتج Swift مفاتيح الترميز من أسماء الخصائص تلقائيًا.

التعامل مع الكائنات المتداخلة والمصفوفات

تعتبر الكائنات المتداخلة الجزء الأكثر إثارة للاهتمام في توليد الشيفرة. عندما يواجه المولد قيمة كائن داخل كائن آخر، فإنه ينشئ نوعًا مسمى منفصلًا. عادةً ما تكون قاعدة التسمية مستندة إلى اسم الحقل:

  • ينتج حقل يسمى address يحتوي على كائن نوعًا يسمى Address.
  • ينتج حقل يسمى shipping_details نوعًا يسمى ShippingDetails (بأسلوب PascalCase).
  • تتبع الكائنات المتداخلة بعمق نفس النمط بشكل متكرر — ينتج address مع كائن متداخل coordinates كل من أنواع Address وCoordinates.

تتم معالجة مصفوفات الكائنات بشكل مشابه. إذا كانت items مصفوفة من الكائنات، يقوم المولد بفحص العنصر الأول (أو دمج جميع العناصر) لاستنتاج النوع، وينشئ نوعًا مسمىً واحدًا مثل Item.

تكون مصفوفات القيم الأولية (["admin", "editor"]) بسيطة — تصبح string[]، Vec<String>، []string، إلخ، اعتمادًا على لغة الهدف.

نصائح لتحسين الشيفرة المولدة

تعتمد جودة الأنواع المولدة تمامًا على جودة بيانات الإدخال الخاصة بك. إليك بعض النصائح العملية:

  • استخدم بيانات نموذج تمثيلية. قم بتضمين على الأقل مثال واحد لكل تنوع حقل. إذا كان يمكن أن يكون حقل null، قم بتضمين قيمة null حتى يقوم المولد بتمييزه كاختياري.
  • احتفظ بالأنواع متسقة. إذا كان id رقمًا في بعض السجلات وسلسلة في أخرى، يجب على المولد اختيار واحدة أو استخدام نوع اتحاد. نظف بيانات النموذج الخاصة بك أولاً.
  • إعادة تسمية النوع الجذري. تقوم معظم المولدات بتعيين Root كاسم المستوى الأعلى بشكل افتراضي. أعد تسميته إلى شيء ذي معنى مثل User أو ApiResponse بعد التوليد.
  • قم بتسطيح قبل التوليد إذا كنت بحاجة فقط إلى مجموعة فرعية من الهيكل. قم بقص نموذج JSON الخاص بك إلى الحقول التي تهمك فقط.
  • تحقق من الحالات الحدية. لا يمكن تعيين المصفوفات الفارغة ([]) بدون سياق. قم بملئها على الأقل بعنصر واحد حتى يعرف المولد نوع العنصر.
  • راجع واضبط. الشيفرة المولدة هي نقطة انطلاق. قد ترغب في إعادة تسمية الحقول، وضبط عرض الأعداد الصحيحة، وإضافة تعليقات التحقق، أو وضع علامات على الحقول الاختيارية بناءً على معرفتك بالمجال.

جربها بنفسك

توليد الشيفرة ذات النوع على الفور: ألصق أي JSON في مولد JSON إلى الشيفرة واحصل على أنواع جاهزة للإنتاج لـ TypeScript، Python، Java، Go، Rust، Swift، Kotlin، وC#. لا حاجة للتسجيل.

أدوات ذات صلة