في مقالنا السابق "ماذا تفعل عندما يكون لـ API هياكل معلمات متعددة"، ناقشنا أنه عندما يتطلب API هياكل معلمات مختلفة، يمكنك استخدام oneOf أو anyOf أو allOf في Apidog لتعريفها.
بمجرد إعداد هياكل المعلمات باستخدام تركيبات المخطط هذه، وتضمين معلماتك لحقل يحدد نوع البيانات، يمكنك جعل التوثيق أوضح باستخدام ميزة discriminator من مواصفات OpenAPI للتمييز بين المخططات بشكل أكثر سهولة.
ما هو Discriminator؟
في OpenAPI، يتمثل دور discriminator في تنفيذ "تعدد الأشكال" (polymorphism) من البرمجة الشيئية.
ببساطة، يستخدم خاصية مشتركة وقيمتها الفريدة للإشارة بوضوح إلى أي مخطط محدد في قائمة oneOf أو anyOf يجب استخدامه.
على سبيل المثال، في متجر للحيوانات الأليفة، نحتاج إلى استخدام مخطط لوصف الحيوانات الأليفة. (وللقطط والكلاب خصائص مختلفة.)
مخطط الكلاب هو:
{
"name": "Hotdog",
"age": 3,
"weight": 25.5,
"petType": "dog",
"breed": "Golden Retriever",
"isVaccinated": true,
"walkingSchedule": "Morning and Evening",
"favoriteToys": ["Frisbee", "Tennis Ball"],
"trainingLevel": "Intermediate"
}مخطط القطط هو:
{
"name": "Meow",
"age": 2,
"weight": 4.2,
"petType": "cat",
"isVaccinated": true,
"isIndoor": true,
"litterBoxType": "Enclosed",
"scratchingPostHeight": 120,
"favoriteSleepingSpot": "Balcony"
}كما ترى، على الرغم من أن كلا المخططين يحتويان على حقول مشتركة مثل petType وname وage وما إلى ذلك، إلا أن الكلاب لديها حقول محددة مثل breed وwalkingSchedule وما إلى ذلك، بينما القطط لديها حقول محددة مثل isIndoor وlitterBoxType وما إلى ذلك.
إذا استخدمت oneOf فقط لتعريف هذه المخططات عند تصميم وثائق API الخاصة بك، يمكن للوثائق أن تميز تقنيًا بين مخططات dog وcat. ومع ذلك، فإن مطابقة كل نوع ليست واضحة جدًا. يجب على القراء التبديل بين علامتي تبويب المخططين لمقارنتهما، مما يصبح مربكًا عندما يكون هناك العديد من المعلمات.

بإضافة discriminator، ستعرض الوثائق قائمة منسدلة، حيث يمكن للقراء اختيار قيمة petType (dog أو cat). بمجرد الاختيار، تعرض الصفحة تلقائيًا المخطط الصحيح مع الحقول ذات الصلة. هذا يزيل الحاجة إلى مقارنة علامات تبويب متعددة ويجعل الفروق بين كل مخطط أوضح بكثير.

يستخدم discriminator عادةً مع oneOf أو anyOf. تحدد oneOf مخططات الكائنات المحتملة، ويخبر discriminator المحلل كيفية تحديد المخطط الذي يجب تطبيقه بناءً على النوع المحدد.
هذا يجعل الكائنات المعقدة أوضح ويساعد الأدوات على التمييز التلقائي بين الأنواع عند عرض الوثائق أو إنشاء التعليمات البرمجية.
خصائص تكوين discriminator
يحتوي discriminator على خاصيتين رئيسيتين:
- propertyName: يحدد اسم الحقل المستخدم للتمييز بين الأنواع، مثل
petTypeفي المثال أعلاه. - mapping: يحدد علاقة التعيين بين قيم الحقول والمخططات المحددة، مثل
"dog"المقابل لمخطط الكلب و"cat"المقابل لمخطط القطة.
مثال التكوين في OpenAPI:
discriminator:
propertyName: petType
mapping:
dog: '#/components/schemas/Dog'
cat: '#/components/schemas/Cat'تكوين Discriminator في Apidog
يدعم Apidog تكوين discriminator بطريقتين:
- واجهة المستخدم الرسومية (GUI) + JSON Schema
- استيراد مواصفات OpenAPI مباشرةً
الطريقة 1: واجهة المستخدم الرسومية (GUI) + JSON Schema
أولاً، أنشئ المخططات في Apidog، مثل Dog وCat:

افتح نقطة النهاية حيث تريد استخدام هذه المخططات وانتقل إلى محرر نص الطلب أو الاستجابة.
حدد الحقل الذي تريد تعريفه كتركيب مخطط واختر Advanced Settings → Schema Compositions → oneOf.

في oneOf، قم بالإشارة إلى المخططات التي تحتاجها، مثل Dog وCat.

الآن قمت بتعريف عدة مخططات محتملة عبر oneOf. بعد ذلك، تحتاج إلى إضافة discriminator لتحديد كيفية التمييز بين هذه المخططات. انقر على JSON Schema للتبديل إلى وضع التعليمات البرمجية:

أضف تكوين discriminator في الموقع المناسب (على نفس مستوى oneOf)، على سبيل المثال:
"discriminator": {
"propertyName": "petType",
"mapping": {
"dog": "#/definitions/190704823",
"cat": "#/definitions/190704706"
}
}القيم في mapping، مثل #/definitions/190704823، هي معرفات فريدة يتم إنشاؤها داخليًا بواسطة Apidog للمخططات. يمكنك العثور على مسار definitions المقابل لكل مخطط في لوحة تكوين JSON Schema.

بعد اكتمال التكوين، احفظه. في وثائق API، يمكنك التبديل بذكاء بين أنواع الكائنات بناءً على قيمة حقل petType.

الطريقة 2: استيراد مواصفات OpenAPI مباشرةً
هذه طريقة أكثر معيارية، ومناسبة بشكل خاص للفرق التي اعتادت على سير عمل "التصميم أولاً".
اكتب مواصفات OpenAPI الخاصة بك مع تضمين discriminator، ثم استوردها إلى Apidog.
على سبيل المثال، في مواصفات OpenAPI، تعريف discriminator هو كما يلي:
Pet:
oneOf:
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Cat'
discriminator:
propertyName: petType
mapping:
dog: '#/components/schemas/Dog'
cat: '#/components/schemas/Cat'يحدد هذا التعريف بوضوح:
- من خلال
oneOf، حدد أن الكائن قد يكون من نوعDogأوCat - من خلال
discriminator، حدد تحديد النوع المحدد بناءً على قيمة حقلpetType - من خلال
mapping، حدد بوضوح أن"dog"يتوافق مع مخططDogو"cat"يتوافق مع مخططCat.
مواصفات OpenAPI الكاملة هي كما يلي:
openapi: 3.0.3
info:
title: Pet Shop API
version: 1.0.0
components:
schemas:
Dog:
type: object
properties:
petType:
type: string
enum: [dog]
name:
type: string
age:
type: integer
weight:
type: number
breed:
type: string
isVaccinated:
type: boolean
walkingSchedule:
type: string
favoriteToys:
type: array
items:
type: string
trainingLevel:
type: string
required:
- petType
- name
- age
Cat:
type: object
properties:
petType:
type: string
enum: [cat]
name:
type: string
age:
type: integer
weight:
type: number
isVaccinated:
type: boolean
isIndoor:
type: boolean
litterBoxType:
type: string
scratchingPostHeight:
type: integer
favoriteSleepingSpot:
type: string
required:
- petType
- name
- age
Pet:
oneOf:
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Cat'
discriminator:
propertyName: petType
mapping:
dog: '#/components/schemas/Dog'
cat: '#/components/schemas/Cat'
paths:
/pets:
get:
summary: Get pet information
responses:
'200':
description: Successful response
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'بعد الانتهاء من مواصفات OpenAPI، استخدم ميزة import في Apidog. سيقوم Apidog بتحليل جميع المواصفات، وإنشاء المخططات ونقاط النهاية المقابلة تلقائيًا، والتعرف بشكل صحيح على تكوين discriminator (يتم إضافة enum هنا لقفل قيم المعلمات).

الأسئلة الشائعة
1. متى تستخدم Discriminator؟
يجب عليك استخدام discriminator فقط عندما تتضمن نقطة النهاية الخاصة بك بالفعل حقلاً يحدد المخططات. في المثال أعلاه، يوجد حقل petType في تصميم API ويستخدم للتمييز بين أنواع الحيوانات الأليفة.
يخبر discriminator الأدوات ببساطة كيفية اختيار المخطط الصحيح بناءً على قيمة هذا الحقل.
إذا لم تتضمن نقطة النهاية الخاصة بك مثل هذا الحقل المحدد للنوع، فإن discriminator غير مناسب - يكفي استخدام oneOf وحده.
أيضًا، إذا كان مخططك بسيطًا أو يحتوي على عدد قليل من الاختلافات، فقد لا تحتاج إلى discriminator على الإطلاق.
2. هل يجب استخدام Discriminator مع oneOf؟
نعم. يجب استخدام Discriminator مع oneOf أو anyOf أو allOf. لا يمكنه تعريف المخططات بمفرده - بل يشرح فقط كيفية التمييز بين المخططات المحتملة المتعددة.
الخاتمة
discriminator هي ميزة اختيارية في مواصفات OpenAPI تستخدم لتعزيز تجربة المستخدم لـ oneOf/anyOf/allOf.
عندما تحتوي مواصفات نقطة النهاية الخاصة بك بالفعل على حقول تستخدم لتحديد الأنواع، يمكنك تكوين discriminator في Apidog لجعل وثائق API أوضح وأكثر ذكاءً.
بالطبع، إذا وجدت التكوين مزعجًا أو كان المخطط بسيطًا نسبيًا، يمكنك استخدام تركيب المخطط مثل oneOf فقط.
