API mit Versionskontrolle weiterentwickeln

Benutzerdefinierte Konnektoren für Azure Logic Apps, Microsoft Power Automate oder Microsoft Power Apps müssen eine OpenAPI-Spezifikationsdatei bereitstellen. Diese OpenAPI-Spezifikation definiert einzelne Einstiegspunkte, die als Vorgänge bezeichnet werden. Jeder Vorgang besitzt einen eindeutigen operationId-Wert und eine eindeutige Kombination aus urlPath und HttpVerb.

{
    "/items": {
        "get": {
            "summary": "Get rows",
            "description": "This operation gets a list of items.",
            "operationId": "GetItems"
        },
        "post": {
            "summary": "Insert row",
            "description": "This operation inserts an item.",
            "operationId": "PostItem"
        }
    }
}

Diese Vorgänge können sich im Laufe der Zeit vergrößern und ändern, wenn Funktionen hinzugefügt oder erweitert werden. Einige Änderungen sind lediglich Hinzufügungen und verletzen nicht unbedingt den Vertrag zwischen Clients und Servern. Das Hinzufügen neuer Parameter, das Zurückgeben weiterer Daten oder das Zulassen flexiblerer Eingaben kann in diese Kategorie fallen.

Allerdings können viele Änderungen tatsächlich gegen den in der OpenAPI-Spezifikation beschriebenen Vertrag verstoßen. Das Entfernen von Parametern, das Beenden der Unterstützung bestimmter Eingaben oder das Ändern der Bedeutung und des Verhaltens einer Eingabe, einer Ausgabe oder des Vorgangs selbst fällt in die „Breaking Change“-Kategorie.

Für eine ordnungsgemäße Weiterentwicklung der API muss ein Muster befolgt werden, dem auch die Clients folgen können. Die API muss die Abwärtskompatibilität gewährleisten, die Absicht mitteilen und Versionsattribute beschreiben. Der Client muss Vorgänge anzeigen oder ausblenden, die veraltet oder abgelaufen sind oder für die neuere Versionen verfügbar sind. Auf diese Weise können Vorgänge im Laufe der Zeit wachsen und sich entwickeln, ohne dass Anwendungen, die auf ihnen basieren, übermäßig anfällig werden.

API-Anmerkung

OpenAPI bietet keine systeminterne Unterstützung für die Vorgangsversionsverwaltung. Unser Ziel wird im Wesentlichen durch das x-ms-api-annotation-Objekt erreicht, das sowohl im globalen Gültigkeitsbereich als auch im Vorgangsbereich angewendet wird. Das globale Objekt enthält Eigenschaften, die für die gesamte API gelten:

{
    "x-ms-api-annotation": {
        "status": "Preview"
    }
}
Eigenschaft Werte Standard Beschreibung
Status "Preview" "Production" "Preview" Status der API als Ganzes — beginnend in der Vorschau und eskaliert bis zur Produktion, je nachdem, wie es Nutzung und Stabilität erfordern

Dieses Objekt enthält im Vorgangsbereich detailliertere Eigenschaften. Es gibt auch zusätzliche Eigenschaften außerhalb des Objekts, die angewendet werden und bei der Entwicklung der Versionsverwaltung beteiligt sind:

{
    "deprecated": true,
    "x-ms-api-annotation": {
        "status": "Production",
        "family": "MyOperation",
        "revision": 2
    }
}
Eigenschaft Werte Standard Beschreibung
veraltet null false true false Gibt an, ob der Vorgang veraltet ist.
x-ms-visibility null "" "Important" "Advanced" "Internal" "" Die beabsichtigte Sichtbarkeit und Augenfälligkeit des Vorgangs, wobei null oder "" einen normalen Zustand bedeutet
Status "Preview" "Production" "Production" Status der Operation — dies kann sich vom Status der API selbst unterscheiden, wird aber, wenn nicht angegeben, vom API-Status der obersten Ebene übernommen
Familie {allgemeiner Operationsname} operationName Der Name, der auf jede Revision des Vorgangs angewendet wird
Revision numerisch (1, 2, 3...) 1 Die Revision der angegebenen Vorgangsfamilie
Läuft ab Datum der ISO8601-Einladung (keine) Ein optionaler Hinweis an den Client, der das voraussichtliche Ende des Supports angibt

Deprecated kann auf true festgelegt werden, wenn die Verwendung des Vorgangs für Clients nicht mehr erwünscht ist. Diese Eigenschaft ist in der Spezifikation fester OpenAPI-Felder vorhanden.

Visibility ist ein Indikator für die beabsichtigte relative Augenfälligkeit des Vorgangs. Die Sichtbarkeit "Important" gibt an, dass der Vorgang am Anfang der Liste stehen sollte, um augenfällig angezeigt zu werden. Die Sichtbarkeit normal (angegeben durch null oder die leere Zeichenfolge "") ist die Standardeinstellung und bedeutet, dass der Vorgang in der Liste angezeigt wird, wahrscheinlich nach den wichtigen Vorgängen. Die Sichtbarkeit "Advanced" gibt an, dass der Vorgang möglicherweise am Ende der Liste angezeigt wird oder sogar zunächst hinter einem Expando-Steuerelement ausgeblendet ist. Vorgänge mit der Sichtbarkeit „Advanced“ sind möglicherweise schwieriger zu verwenden, weniger beliebt oder in selteneren Fällen anwendbar. Die Sichtbarkeit "Internal" gibt an, dass der Vorgang nicht für Benutzer verfügbar gemacht werden und nur intern verwendet werden sollte. Vorgänge mit der Sichtbarkeit „Internal“ sind für das Programm nützlich und wertvoll, jedoch nicht für Endbenutzer vorgesehen. Vorgänge können auch als „Internal“ gekennzeichnet werden, damit sie während der Veralterung nicht auf der Benutzeroberfläche angezeigt werden, ohne sie aus der API zu entfernen, da dies einen Breaking Change verursachen würde.

Status gibt die Stabilität der API oder des Vorgangs an. "Preview" gibt an, dass der Vorgang oder die API neu und möglicherweise nicht erprobt ist. „Preview“ ist ein Indikator, den Produktionssysteme bei der Annahme von Abhängigkeiten berücksichtigen sollten. Nachdem der Vorgang oder die API umfassender eingeführt wurde und die Erfüllung der Standards für Zuverlässigkeit, Erfolgsrate und Skalierbarkeit nachgewiesen wurde, kann er bzw. sie bewusst auf den Status "Production" aktualisiert werden.

Für Vorgänge, für die der Status "Production" angestrebt wird, gelten im Allgemeinen die folgenden Metrikanforderungen:

  • 80 % Erfolgsrate für einen Zeitraum von drei Wochen,
    • definiert als Prozentsatz der HTTP-Antwortcodes im Bereich 2xx
  • 99,9 % Zuverlässigkeit in einem Zeitraum von drei Wochen,
    • definiert als Prozentsatz der HTTP-Antwortcodes im Bereich außerhalb von 5xx (502, 504 und 520 sind aus dieser Berechnung ausgeschlossen)

Family gibt die Beziehung zwischen Vorgängen an, die konzeptionell derselbe Vorgang sind, für die jedoch unterschiedliche Revisionen vorhanden sind, die potenziell Breaking Changes beinhalten. Für mehrere Vorgänge wird derselbe Vorgangsfamilienname verwendet, wenn es sich um Revisionen des gleichen Vorgangs handelt. Sie werden dann durch eindeutige fortlaufende Revisionsnummern unterschieden.

Revision gibt die Entwicklungsreihenfolge des Vorgangs innerhalb der Vorgangsfamilie an. Jeder Vorgang in einer Vorgangsfamilie weist eine Revision auf, bei der es sich um eine integrale Sequenz mit Index handelt. Eine leere Revision gilt als Revision 1. Wenn neuere Revisionen eines Vorgangs verfügbar sind, sollten diese von den Clients augenfälliger angezeigt und expliziter empfohlen werden. Die Clients sollten jedoch die Auswahl potenziell älterer Versionen, die noch nicht veraltet sind, weiterhin zulassen.

Expires ist optional und gibt ein potenzielles Ende der Lebensdauer an, ab dem die Unterstützung für den Vorgang nicht mehr garantiert wird. Dies sollte nur für veraltete Vorgänge festgelegt werden, und es wird derzeit auf keiner Benutzeroberfläche wiedergegeben.

Vorgangslebensdauer

Vorgänge verfügen über eine vorhersagbare Lebensdauer, die anhand eines Beispiels ermittelt werden kann.

Startpunkt

Vorgänge liefern zunächst nicht unbedingt Informationen zu Revisionen. Für diese Vorgänge werden Standardwerte angewendet, und sie werden daher in einem Vorgangsfamiliennamen, der dem Wert für operationId entspricht, als Revision 1 betrachtet.

{
    "/{list}/items": {
        "get": {
            "summary": "Get rows",
            "description": "This operation gets a list of items.",
            "operationId": "GetItems"
        }
    }
}

Dies entspricht der expliziteren Definition:

{
    "/{list}/items": {
        "get": {
            "summary": "Get rows",
            "description": "This operation gets a list of items.",
            "operationId": "GetItems",
            "deprecated": false,
            "x-ms-api-annotation": {
                "status": "Production",
                "family": "GetItems",
                "revision": 1
            }
        }
    }
}

Vorgangsinitiierung

Bei den meisten Weiterentwicklungen einer API handelt es sich um das Hinzufügen eines Vorgangs, beispielsweise um neue Methoden und neue Revisionen vorhandener Methoden. Damit eine neue Revision ordnungsgemäß initiiert werden kann, wird die OpenAPI-Spezifikation wie folgt angepasst:

{
    "/{list}/items": {
        "get": {
            "summary": "Get rows (V1 - downplayed)",
            "description": "This operation gets a list of items.",
            "operationId": "GetItems",
            "deprecated": false,
            "x-ms-visibility": "advanced",
            "x-ms-api-annotation": {
                "status": "Production",
                "family": "GetItems",
                "revision": 1
            }
        }
    }
    "/v2/{list}/items": {
        "get": {
            "summary": "Get rows (V2 - new hotness)",
            "description": "This operation gets a list of items.",
            "operationId": "GetItems_V2",
            "deprecated": false,
            "x-ms-api-annotation": {
                "status": "Preview",
                "family": "GetItems",
                "revision": 2
            }
        }
    }
}

Wichtig

Beachten Sie, dass „GetItems V2“ über einen eindeutigen operationId-Wert verfügt und zunächst im Vorschauversionsstatus aufgeführt ist. Beachten Sie auch, dass die Sichtbarkeit von „GetItems_V1“ jetzt „advanced“ lautet und das Element somit nicht augenfällig angezeigt wird.

Kennzeichen eines Vorgangs als veraltet

Manchmal bleiben vorhandene V1-Einstiegspunkte für unbegrenzte Zeit erhalten, wenn sie weiterhin einen Wert bereitstellen und es keinen überzeugenden Grund gibt, sie einzustellen. Viele V2-Einstiegspunkte ersetzen jedoch den V1-Einstiegspunkt vorsätzlich. Um dies ordnungsgemäß zu erreichen, sollte der gesamte Datenverkehr für den ursprünglichen Vorgang nominal Null erreichen. Wenn die Telemetrie diesen Umstand bestätigt, kann die folgende Änderung vorgenommen werden:

{
    "/{list}/items": {
        "get": {
            "summary": "Get rows (deprecated)",
            "description": "This operation gets a list of items.",
            "operationId": "GetItems",
            "deprecated": true,
            "x-ms-api-annotation": {
                "status": "Production",
                "family": "GetItems",
                "revision": 1
            }
        }
    }
    "/v2/{list}/items": {
        "get": {
            "summary": "Get rows",
            "description": "This operation gets a list of items.",
            "operationId": "GetItems_V2",
            "deprecated": false,
            "x-ms-api-annotation": {
                "status": "Production",
                "family": "GetItems",
                "revision": 2
            }
        }
    }
}

Wichtig

Beachten Sie, dass „GetItems_V1“ nun als veraltet markiert ist. Dies ist der letzte Übergang beim Festlegen von Vorgängen als veraltet. „GetItems_V2“ hat jetzt „GetItems_V1“ vollständig ersetzt.

Gründe für den Aufwand

Es gibt viele Gründe für die Versionsverwaltung von Vorgängen. Auf diese Weise wird in erster Linie sichergestellt, dass Clients wie Azure Logic Apps und Power Automate weiterhin korrekt funktionieren, wenn Benutzer Konnektoroperationen in ihre Datenflüsse integrieren. Vorgänge sollten mit der obigen Methode versioniert werden, wenn Folgendes gilt:

  • Es wird eine neue Revision eines Vorgangs hinzugefügt.
  • Durch einen vorhandenen Vorgang werden Parameter hinzugefügt oder entfernt.
  • Ein vorhandener Vorgang ändert die Eingabe oder Ausgabe erheblich

Mögliche Ausnahmen

Möglicherweise gibt es Fälle, in denen Sie ohne Versionsverwaltung auskommen. Sie sollten jedoch dabei vorsichtig sein und zahlreiche Tests durchführen, um sicherzustellen, dass Sie keine Grenzfälle übersehen haben, in denen Benutzer unerwartet beeinträchtigt werden könnten. Hier ist eine umsichtige kurze Liste, wann Sie ohne sie auskommen können:

  • Ein neuer Vorgang wird hinzugefügt.

    Dadurch werden vorhandene Clients nicht beeinträchtigt.

  • Einem vorhandenen Vorgang wird ein neuer optionaler Parameter hinzugefügt.

    Vorhandene Aufrufe werden dadurch nicht verhindert, dies muss jedoch sorgfältig überlegt werden.

  • Durch einen vorhandenen Vorgang wird das Verhalten geringfügig geändert.

    Dadurch werden vorhandene Aufrufer möglicherweise nicht beeinträchtigt, abhängig von der Art der Änderung und den betroffenen Benutzern. Dies ist der komplizierteste unter diesen Fällen, da ein bedeutender Unterschied beim Akzeptieren von Eingaben, bei der Ausgabegenerierung, beim Timing oder bei der Verarbeitung das Verhalten des Vorgangs so beeinflussen kann, dass das Risiko der Änderung schwierig zu bestimmen ist.

Es empfiehlt sich immer, vorsichtig zu bleiben und eine Revision zu durchlaufen, wenn Sie eine nicht triviale API-Änderung vornehmen.

Feedback senden

Wir freuen uns sehr über Feedback zu Problemen mit unserer Connector-Plattform oder neuen Feature-Ideen. Wenn Sie Feedback geben möchten, gehen Sie zu Probleme melden oder Hilfe zu Connectors und wählen Sie einen Feedbacktyp aus.