غالبًا ما تحتوي معلمات واجهة برمجة التطبيقات (API) على هياكل معقدة، حيث تدعم نقطة نهاية واحدة مجموعات مختلفة ومتعددة من المعلمات. على سبيل المثال، قد تدعم نقطة نهاية تسجيل الدخول المصادقة باسم المستخدم وكلمة المرور، أو المصادقة بالبريد الإلكتروني وكلمة المرور، أو رموز التحقق عبر رقم الهاتف. يمكن أن تقدم نقاط نهاية الدفع طرقًا متنوعة مثل بطاقات الائتمان، أو WeChat Pay، أو Alipay، حيث تتطلب كل منها حقولاً مختلفة.

غالبًا ما تكتفي أساليب توثيق واجهة برمجة التطبيقات التقليدية بسرد جميع الحقول الممكنة واستخدام أوصاف نصية مثل "اختر حقولاً مختلفة بناءً على سيناريوهات مختلفة". هذا النهج ليس دقيقًا ولا صديقًا للمطورين، وغالبًا ما يؤدي إلى الارتباك. يدعم Apidog ميزات JSON Schema وهي oneOf و anyOf و allOf، مما يتيح لك وصف هياكل البيانات المركبة المعقدة هذه بدقة في وثائق واجهة برمجة التطبيقات الخاصة بك.
فهم أوضاع الدمج الثلاثة
في JSON Schema، تُستخدم oneOf و anyOf و allOf لدمج مخططات فرعية متعددة، ولكن لها معاني منطقية مختلفة:
- allOf: يدمج قواعد متعددة، ويتطلب مطابقة جميعها
- anyOf: يتطلب مطابقة واحدة على الأقل، والمطابقات المتعددة مقبولة
- oneOf: يجب أن يطابق مخططًا واحدًا بالضبط، وستفشل المطابقة لصفر أو مخططات متعددة
إعداد أوضاع الدمج في Apidog
يوفر Apidog طريقتين لاستخدام أوضاع الدمج هذه:
نهج المحرر المرئي
تستخدم الطريقة الأولى لوحة التحرير المرئي. في مشروعك، انقر على "نماذج البيانات" لإنشاء نموذج جديد، ثم ابحث عن "أوضاع الدمج" في اختيار النوع. اختر وضع oneOf أو anyOf أو allOf المطلوب، ثم حدد هياكل بيانات محددة لكل مخطط فرعي.

محرر كود JSON Schema
يتضمن النهج الثاني تحرير كود JSON Schema مباشرة. في لوحة تحرير نموذج البيانات، يمكنك التبديل إلى وضع الكود وكتابة JSON Schema مباشرة لتحديد أنماط الدمج المنطقية هذه. هذه الطريقة أكثر مباشرة للمطورين الملمين بـ JSON Schema.

تطبيق هذه الأنماط في نقاط نهاية واجهة برمجة التطبيقات
بمجرد تحديد نماذج البيانات الخاصة بك، يمكنك استخدامها في وثائق واجهة برمجة التطبيقات الخاصة بك. عند تحرير معلمات طلب الواجهة، حدد نوع النص (Body) كـ JSON، ثم في قسم هيكل البيانات، يمكنك الرجوع إلى "نماذج البيانات" التي أنشأتها للتو، أو تحديد "أوضاع الدمج" مباشرة لتحديد هياكل المعلمات المعقدة.

ينطبق نفس المبدأ على تعريفات بيانات الاستجابة. عند إضافة أمثلة للاستجابة في قسم استجابة الإرجاع، يمكنك استخدام أوضاع الدمج لوصف تنسيقات الاستجابة لسيناريوهات مختلفة. بهذه الطريقة، يمكن للمطورين فهم هيكل البيانات الذي سيتم إرجاعه بوضوح في المواقف المختلفة.
حالات الاستخدام في العالم الحقيقي
allOf: دمج هياكل متعددة
allOf يدمج هياكل متعددة معًا - لا يتعلق الأمر بالاختيار، بل بالتراص. allOf لا يغير تسلسل الحقول؛ تنتهي جميع الحقول في نفس الكائن. إنه ببساطة يكدس قواعد متعددة على نفس البيانات. فكر في الأمر على أنه "AND منطقي" - يجب أن يتم استيفاء جميع قيود البنية الفرعية.
على سبيل المثال، مخطط JSON هذا:
{
"allOf": [
{
"description": "معلومات المستخدم الأساسية",
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" }
},
"required": ["id", "name"]
},
{
"description": "معلومات الاتصال",
"type": "object",
"properties": {
"email": { "type": "string", "format": "email" },
"phone": { "type": "string" }
},
"required": ["email"]
}
]
}
يعني هذا المخطط: يجب أن تستوفي البيانات النهائية في وقت واحد كلاً من هياكل "معلومات المستخدم الأساسية" و "معلومات الاتصال".
بمعنى آخر، يجب أن يتضمن نص الطلب المعرف (id) والاسم (name) والبريد الإلكتروني (email)، بينما رقم الهاتف (phone) اختياري.
بيانات صالحة:
{
"id": 1001,
"name": "John Doe",
"email": "john@example.com",
"phone": "1-800-000-0000"
}
بيانات غير صالحة:
{
"id": 1001,
"name": "John Doe"
}
هذا يفتقر إلى حقل البريد الإلكتروني المطلوب ولا يفي بالهيكل الثاني.
هذا النهج مناسب لتقسيم الكائنات المعقدة. يمكن تقسيم معلومات المستخدم، وتفاصيل الطلب، وعناصر التكوين، وما إلى ذلك، إلى هياكل مستقلة حسب الوحدات الوظيفية، ثم دمجها باستخدام allOf. يمكن للواجهات الأخرى التي تحتاج جزءًا من هذه الهياكل الرجوع إليها مباشرة دون تعريفات زائدة.
anyOf: تلبية شرط واحد على الأقل
تسرد anyOf هياكل متعددة ممكنة، وتعتبر البيانات صالحة طالما أنها تتوافق مع واحد منها على الأقل. لا تهتم بما إذا كانت شروط متعددة مستوفاة، ولا تتطلب مطابقة فريدة.
على سبيل المثال، قد يكون حقل المعرف بريدًا إلكترونيًا أو رقم هاتف. يختلف هذان التنسيقان بشكل واضح، لكن كلاهما ينتمي إلى فئة "بيانات اعتماد تسجيل دخول المستخدم".
يمكنك استخدام anyOf للتعبير بوضوح عن نية "يمكن أن يكون A أو B" هذه:
{
"type": "object",
"properties": {
"identifier": {
"description": "معرف المستخدم: يمكن أن يكون بريدًا إلكترونيًا أو رقم هاتف",
"anyOf": [
{
"title": "تنسيق البريد الإلكتروني",
"description": "يجب أن يكون عنوان بريد إلكتروني صالحًا",
"type": "string",
"format": "email"
},
{
"title": "تنسيق الهاتف",
"description": "يجب أن يكون رقم هاتف دولي صالحًا",
"type": "string",
"pattern": "^\\+?[1-9]\\d{1,14}$"
}
]
},
"password": {
"type": "string",
"minLength": 6,
"description": "كلمة مرور تسجيل الدخول، 6 أحرف على الأقل"
}
},
"required": ["identifier", "password"],
"description": "معلمات طلب تسجيل دخول المستخدم"
}
يعني هذا الهيكل: المعرف عبارة عن سلسلة تعتبر صالحة طالما أنها تستوفي إما تنسيق البريد الإلكتروني أو تنسيق رقم الهاتف.
بيانات صالحة:
{
"identifier": "test@example.com",
"password": "123456"
}
{
"identifier": "+1-800-000-0000",
"password": "123456"
}
بيانات غير صالحة:
{
"identifier": "abc",
"password": "123456"
}
"abc" ليس بريدًا إلكترونيًا ولا تنسيق رقم هاتف صالحًا، ولا يفي بأي من الشروط.
oneOf: اختيار خيار واحد بالضبط
تسرد oneOf هياكل متعددة ممكنة، ويجب أن تتوافق البيانات مع واحد منها بالضبط. إنها تؤكد على الحصرية - يمكنك اختيار واحد فقط، لا أكثر ولا أقل.
على سبيل المثال، طرق الدفع: لإتمام عملية دفع، يجب على المستخدمين اختيار واحدة من بطاقة الائتمان، أو WeChat Pay، أو Alipay، ولكن لا يمكنهم استخدام طريقتين في وقت واحد، ولا يمكنهم عدم اختيار أي منها. يمكنك تعريف منطق "الاختيار الفردي" هذا باستخدام oneOf:
{
"properties": {
"paymentMethod": {
"description": "طريقة الدفع، يجب اختيار واحدة بالضبط",
"oneOf": [
{
"title": "الدفع ببطاقة الائتمان",
"description": "الدفع ببطاقة الائتمان، يتطلب رقم البطاقة وتاريخ انتهاء الصلاحية",
"type": "object",
"properties": {
"type": { "const": "credit_card" },
"cardNumber": { "type": "string" },
"expiryDate": { "type": "string" }
},
"required": ["type", "cardNumber", "expiryDate"],
"additionalProperties": false
},
{
"title": "الدفع عبر WeChat Pay",
"description": "الدفع عبر WeChat، يتطلب openid المستخدم",
"type": "object",
"properties": {
"type": { "const": "wechat" },
"openid": { "type": "string" }
},
"required": ["type", "openid"],
"additionalProperties": false
},
{
"title": "الدفع عبر Alipay",
"description": "الدفع عبر Alipay، يتطلب معرف الحساب",
"type": "object",
"properties": {
"type": { "const": "alipay" },
"accountId": { "type": "string" }
},
"required": ["type", "accountId"],
"additionalProperties": false
}
]
}
}
}
يعني هذا التعريف: paymentMethod هو كائن يمكن أن يطابق أحد الهياكل الفرعية الثلاثة فقط.
أمثلة صالحة:
{
"paymentMethod": {
"type": "wechat",
"openid": "wx_123456"
}
}
{
"paymentMethod": {
"type": "credit_card",
"cardNumber": "4111111111111111",
"expiryDate": "12/25"
}
}
مثال غير صالح:
{
"paymentMethod": {
"type": "wechat",
"openid": "wx_123",
"accountId": "2088102"
}
}
على الرغم من أن النوع هو "wechat"، فإن وجود accountId قد يجعله يطابق هياكل متعددة، مما يتسبب في فشل oneOf. إضافة "additionalProperties": false
يمنع هذا الالتباس (بمعنى عدم السماح بحقول إضافية)، مما يضمن أن كل هيكل يسمح فقط بحقوله المحددة. يدعم Apidog التكوين المرئي لـ additionalProperties.
عندما تحتاج إلى إجراء اختيارات حصرية بين أنواع متعددة ومميزة، فإن oneOf هي الطريقة الأكثر مباشرة وموثوقية للتعبير عن ذلك.
اختيار وضع الدمج الصحيح
يعتمد اختيار وضع الدمج بشكل أساسي على منطق عملك:
- استخدم allOf عندما تحتاج إلى دمج وتوريث أنماط متعددة
- استخدم anyOf عندما تحتاج إلى مجموعات اختيارية مرنة
- استخدم oneOf عندما تحتاج إلى اختيارات حصرية صارمة
فهم أدوارها يسمح لوثائق واجهة برمجة التطبيقات الخاصة بك بوصف هياكل البيانات المعقدة بدقة، مما يجعل من الواضح على الفور لمستخدمي الواجهة كيفية تمرير المعلمات.
الخاتمة
يدعم Apidog الشامل لـ JSON Schema المطورين لإنشاء وثائق API دقيقة وواضحة حتى لأكثر هياكل المعلمات تعقيدًا. من خلال الاستفادة من مجموعات oneOf و anyOf و allOf، يمكنك إزالة الغموض وتقديم إرشادات واضحة تمامًا لمستهلكي API.
هل أنت مستعد لتجربة قوة توثيق API المتقدم؟ جرب Apidog اليوم وشاهد مدى سهولة إدارة معلمات API المعقدة بدقة ووضوح.