In unserem vorherigen Artikel „Was tun, wenn eine API mehrere Parameterstrukturen hat“ haben wir besprochen, dass Sie oneOf, anyOf oder allOf in Apidog verwenden können, um verschiedene Parameterstrukturen zu definieren, wenn eine API diese erfordert.
Sobald Sie die Parameterstrukturen mithilfe dieser Schema-Kompositionen eingerichtet haben und Ihre Parameter ein Feld enthalten, das den Datentyp identifiziert, können Sie die Dokumentation noch klarer gestalten, indem Sie die discriminator-Funktion der OpenAPI-Spezifikation verwenden, um intuitiver zwischen den Schemas zu unterscheiden.
Was ist ein Diskriminator?
In OpenAPI besteht die Rolle des discriminator darin, „Polymorphismus“ aus der objektorientierten Programmierung zu implementieren.
Einfach ausgedrückt, verwendet es eine gemeinsame Eigenschaft und deren eindeutigen Wert, um klar anzuzeigen, welches spezifische Schema in der oneOf- oder anyOf-Liste verwendet werden soll.
Zum Beispiel müssen wir in einem Tiergeschäft ein Schema verwenden, um Haustiere zu beschreiben. (Und Katzen und Hunde haben unterschiedliche Eigenschaften.)
Das Schema für Hunde ist:
{
"name": "Hotdog",
"age": 3,
"weight": 25.5,
"petType": "dog",
"breed": "Golden Retriever",
"isVaccinated": true,
"walkingSchedule": "Morning and Evening",
"favoriteToys": ["Frisbee", "Tennis Ball"],
"trainingLevel": "Intermediate"
}Das Schema für Katzen ist:
{
"name": "Meow",
"age": 2,
"weight": 4.2,
"petType": "cat",
"isVaccinated": true,
"isIndoor": true,
"litterBoxType": "Enclosed",
"scratchingPostHeight": 120,
"favoriteSleepingSpot": "Balcony"
}Wie Sie sehen können, haben beide Schemas zwar gemeinsame Felder wie petType, name, age usw., aber Hunde haben spezifische Felder wie breed, walkingSchedule usw., während Katzen spezifische Felder wie isIndoor, litterBoxType usw. haben.
Wenn Sie beim Entwurf Ihrer API-Dokumentation nur oneOf verwenden, um diese Schemas zu definieren, kann die Dokumentation technisch zwischen den dog- und cat-Schemas unterscheiden. Die Zuordnung jedes Typs ist jedoch nicht sehr klar. Leser müssen zwischen den beiden Schema-Tabs wechseln, um sie zu vergleichen, was bei vielen Parametern verwirrend wird.

Durch Hinzufügen eines discriminator zeigt die Dokumentation ein Dropdown-Menü an, in dem Leser den Wert von petType (dog oder cat) auswählen können. Nach der Auswahl zeigt die Seite automatisch das korrekte Schema mit den relevanten Feldern an. Dies macht den Vergleich mehrerer Tabs überflüssig und verdeutlicht die Unterschiede zwischen den einzelnen Schemas erheblich.

Ein discriminator wird typischerweise zusammen mit oneOf oder anyOf verwendet. oneOf definiert die möglichen Objektschemas, und der discriminator weist den Parser an, wie er das anzuwendende Schema basierend auf dem ausgewählten Typ bestimmen soll.
Dies macht komplexe Objekte klarer und hilft Tools, Typen beim Rendern von Dokumentationen oder Generieren von Code automatisch zu unterscheiden.
Konfigurationseigenschaften des discriminator
Ein discriminator enthält zwei Haupteigenschaften:
- propertyName: Gibt den Feldnamen an, der zur Unterscheidung von Typen verwendet wird, wie z.B.
petTypeim obigen Beispiel. - mapping: Definiert die Zuordnungsbeziehung zwischen Feldwerten und spezifischen Schemas, wie z.B.
"dog", das dem Hunde-Schema entspricht, und"cat", das dem Katzen-Schema entspricht.
Konfigurationsbeispiel in OpenAPI:
discriminator:
propertyName: petType
mapping:
dog: '#/components/schemas/Dog'
cat: '#/components/schemas/Cat'Diskriminator in Apidog konfigurieren
Apidog unterstützt die Konfiguration des discriminator auf zwei Arten:
- GUI + JSON-Schema
- Direkter Import der OpenAPI-Spezifikationen
Methode 1: GUI + JSON-Schema
Zuerst erstellen Sie die Schemas in Apidog, wie z.B. Dog und Cat:

Öffnen Sie den Endpunkt, an dem Sie diese Schemas verwenden möchten, und gehen Sie zum Editor für den Anforderungs- oder Antwortkörper.
Wählen Sie das Feld aus, das Sie als Schema-Komposition definieren möchten, und wählen Sie Erweiterte Einstellungen → Schema-Kompositionen → oneOf.

In oneOf referenzieren Sie die benötigten Schemas, wie z.B. Dog und Cat.

Nun haben Sie mehrere mögliche Schemas über oneOf definiert. Als Nächstes müssen Sie den discriminator hinzufügen, um anzugeben, wie diese Schemas unterschieden werden sollen. Klicken Sie auf JSON Schema, um in den Code-Modus zu wechseln:

Fügen Sie die discriminator-Konfiguration an der entsprechenden Stelle hinzu (auf derselben Ebene wie oneOf), zum Beispiel:
"discriminator": {
"propertyName": "petType",
"mapping": {
"dog": "#/definitions/190704823",
"cat": "#/definitions/190704706"
}
}Die Werte in mapping, wie z.B. #/definitions/190704823, sind eindeutige IDs, die intern von Apidog für Schemas generiert werden. Den entsprechenden definitions-Pfad für jedes Schema finden Sie im JSON-Schema-Konfigurationspanel.

Nach Abschluss der Konfiguration speichern Sie diese. In der API-Dokumentation können Sie Objekttypen intelligent basierend auf dem Wert des Feldes petType wechseln.

Methode 2: Direkter Import der OpenAPI-Spezifikationen
Dies ist ein standardisierterer Ansatz, der besonders für Teams geeignet ist, die an "Design-First"-Workflows gewöhnt sind.
Schreiben Sie Ihre OpenAPI-Spezifikationen inklusive discriminator und importieren Sie diese dann in Apidog.
Zum Beispiel ist in den OpenAPI-Spezifikationen die Definition des discriminator wie folgt:
Pet:
oneOf:
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Cat'
discriminator:
propertyName: petType
mapping:
dog: '#/components/schemas/Dog'
cat: '#/components/schemas/Cat'Diese Definition besagt klar:
- Über
oneOfwird angegeben, dass das Objekt vom TypDogoderCatsein kann. - Über
discriminatorwird angegeben, dass der spezifische Typ basierend auf dem Wert des FeldespetTypebestimmt wird. - Über
mappingwird klar angegeben, dass"dog"demDog-Schema und"cat"demCat-Schema entspricht.
Die vollständigen OpenAPI-Spezifikationen sind wie folgt:
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'Nach Fertigstellung der OpenAPI-Spezifikationen verwenden Sie die Import-Funktion in Apidog. Apidog parst alle Spezifikationen, erstellt automatisch entsprechende Schemas und Endpunkte und erkennt die discriminator-Konfiguration korrekt (hier wird enum hinzugefügt, um Parameterwerte zu sperren).

Häufig gestellte Fragen
1. Wann sollte man einen Diskriminator verwenden?
Sie sollten einen discriminator nur dann verwenden, wenn Ihr Endpunkt bereits ein Feld enthält, das die Schemas identifiziert. Im obigen Beispiel existiert das Feld petType im API-Design und wird verwendet, um zwischen Haustiertypen zu unterscheiden.
Der discriminator weist Tools lediglich an, wie das korrekte Schema basierend auf dem Wert dieses Feldes ausgewählt werden soll.
Wenn Ihr Endpunkt kein solches typidentifizierendes Feld enthält, ist ein discriminator nicht angebracht – die alleinige Verwendung von oneOf ist ausreichend.
Auch wenn Ihr Schema einfach ist oder nur wenige Variationen aufweist, benötigen Sie möglicherweise überhaupt keinen Diskriminator.
2. Muss ein Diskriminator mit oneOf verwendet werden?
Ja. Ein Diskriminator muss zusammen mit oneOf, anyOf oder allOf verwendet werden. Er kann keine Schemas eigenständig definieren – er erklärt nur, wie zwischen mehreren möglichen Schemas unterschieden wird.
Fazit
discriminator ist eine optionale Funktion in der OpenAPI-Spezifikation, die verwendet wird, um die Benutzererfahrung von oneOf/anyOf/allOf zu verbessern.
Wenn Ihre Endpunkt-Spezifikationen bereits Felder enthalten, die zur Identifizierung von Typen verwendet werden, können Sie den discriminator in Apidog konfigurieren, um die API-Dokumentation klarer und intelligenter zu gestalten.
Wenn Sie die Konfiguration als aufwendig empfinden oder das Schema relativ einfach ist, können Sie natürlich auch vollständig nur Schema-Kompositionen wie oneOf verwenden.
