كيفية إخفاء حقول الهيكل في JSON: دليل للمبتدئين والمحترفين في Go

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

سحر JSON في Go: لماذا بعض الحقول مرئية والبعض الآخر لا؟

\n

هل سبق لك أن واجهت موقفًا حيث يرسل هيكل Go الخاص بك في استجابة JSON ما لا يجب على العميل رؤيته على الإطلاق؟ على سبيل المثال، كلمة مرور المستخدم، أو معرف قاعدة البيانات الداخلي، أو مفتاح سري. أو العكس، تحتاج إلى إظهار حقل فقط في ظل شرط معين (على سبيل المثال، إذا لم يكن فارغًا).

\n

هذه المشكلة هي واحدة من أكثر المشكلات شيوعًا على Stack Overflow، وليس من دون سبب. العمل مع JSON في Go هو فن التوازن بين صرامة الأنواع ومرونة التمثيل. اليوم سنقوم بتحليل جميع الطرق: من الوسم البسيط json:"-" إلى الحلول المخصصة المعقدة باستخدام الواجهات. هيا بنا!

\n\n

1. الطريقة الأبسط: الوسم json:"-"

\n

يتيح لك Go التحكم في تسلسل الهيكل من خلال وسوم خاصة. إذا كنت تريد إخفاء حقل بشكل دائم من JSON، فقط أضف json:"-".

\n
type User struct {\n    Name     string `json:"name"`\n    Password string `json:"-"`\n    Age      int    `json:"age"`\n}\n\nfunc main() {\n    u := User{Name: "أليس", Password: "supersecret", Age: 30}\n    data, _ := json.Marshal(u)\n    fmt.Println(string(data))\n    // الإخراج: {"name":"أليس","age":30}\n}
\n

اختفى حقل Password كما لو لم يكن موجودًا. مثالي للبيانات السرية التي لا يجب أن تغادر الخادم أبدًا.

\n\n

2. الإخفاء الشرطي: omitempty

\n

أحيانًا تحتاج إلى إخفاء حقل فقط إذا كان فارغًا. لهذا الغرض، تُستخدم الخاصية omitempty (اختصار لـ "omit if empty").

\n
type Product struct {\n    Name        string  `json:"name"`\n    Description string  `json:"description,omitempty"`\n    Price       float64 `json:"price,omitempty"`\n}\n\nfunc main() {\n    p1 := Product{Name: "كتاب", Price: 500.0}\n    data1, _ := json.Marshal(p1)\n    fmt.Println(string(data1)) // {"name":"كتاب","price":500}\n\n    p2 := Product{Name: "دورة"}\n    data2, _ := json.Marshal(p2)\n    fmt.Println(string(data2)) // {"name":"دورة"}\n}
\n

هام: تعمل omitempty فقط مع القيم "الصفرية": ""، 0، false، nil (للمصفوفات، الخرائط، المؤشرات).

\n\n

مأزق الحقول الرقمية

\n

كن حذرًا: إذا كان Price يساوي 0، فسيتم إخفاؤه أيضًا. في بعض منطقيات الأعمال، هذا غير مقبول (المنتج المجاني هو أيضًا سعر). في مثل هذه الحالات، من الأفضل استخدام المؤشرات.

\n\n

3. استخدام المؤشرات (*) والواجهات

\n

المؤشرات هي أفضل صديق لك عندما تحتاج إلى التمييز بين "القيمة غير محددة" و"القيمة تساوي صفرًا".

\n
type UserProfile struct {\n    Name    string  `json:"name"`\n    Age     *int    `json:"age,omitempty"`  // مؤشر إلى int\n    Bio     *string `json:"bio,omitempty"`\n}\n\nfunc main() {\n    // العمر غير محدد - سيتم إخفاء الحقل\n    u1 := UserProfile{Name: "إيفان"}\n    data1, _ := json.Marshal(u1)\n    fmt.Println(string(data1)) // {"name":"إيفان"}\n\n    // العمر = 0 - هذه قيمة ذات معنى\n    zero := 0\n    u2 := UserProfile{Name: "ماريا", Age: &zero}\n    data2, _ := json.Marshal(u2)\n    fmt.Println(string(data2)) // {"name":"ماريا","age":0}\n}
\n

غالبًا ما يُستخدم هذا الأسلوب في REST API، حيث تحتاج إلى تحديث الحقول المرسلة فقط (التحديث الجزئي، طلبات PATCH).

\n\n

4. التسلسل المخصص: الواجهة json.Marshaler

\n

إذا لم تكن الوسوم القياسية كافية، يمكنك التحكم الكامل في العملية. قم بتنفيذ الواجهة json.Marshaler واكتب منطقك الخاص.

\n
type DynamicUser struct {\n    ID        int\n    Name      string\n    ShowEmail bool\n    Email     string\n}\n\nfunc (u DynamicUser) MarshalJSON() ([]byte, error) {\n    // إنشاء هيكل مجهول للتسلسل فقط\n    m := map[string]interface{}{\n        "id":   u.ID,\n        "name": u.Name,\n    }\n    if u.ShowEmail {                

المدونات

توصيات الكتب