Uw API ontwikkelen met versiebeheer

Aangepaste connectors voor Azure Logic Apps, Microsoft Power Automate of Microsoft Power Apps moeten een OpenAPI-specificatiebestand bieden. Dit OpenAPI-specificatiebestand definieert afzonderlijke ingangspunten die bewerkingen worden genoemd. Elke bewerking heeft een unieke operationId en een unieke combinatie van urlPath en 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"
        }
    }
}

Deze bewerkingen kunnen toenemen en in de loop van de tijd veranderen naarmate er functies worden toegevoegd of uitgebreid. Sommige wijzigingen zijn slechts toevoegingen en verbreken niet noodzakelijkerwijs het contract tussen clients en servers. Het toevoegen van nieuwe parameters, het retourneren van meer gegevens of het toestaan van meer flexibele invoer kan in deze categorie vallen.

Veel wijzigingen kunnen echter leiden tot het verbreken van het contract, zoals beschreven in de OpenAPI-specificatie. Het verwijderen van parameters, het niet langer ondersteunen van bepaalde invoer of het wijzigen van de betekenis en het gedrag van een invoer, uitvoer of de bewerking zelf, vallen in de categorie 'breaking change' (wijzigingen die fouten veroorzaken).

Als u een API veilig wilt ontwikkelen, is het belangrijk dat u een patroon volgt dat door clients kan worden genavigeerd. Het is de verantwoordelijkheid van de API om compatibiliteit met eerdere versies te onderhouden, de bedoeling te communiceren, en kenmerken voor versiebeheer aan te geven. Het is de verantwoordelijkheid van de client om bewerkingen die verouderd of verlopen zijn, of waarvoor mogelijk nieuwere versies beschikbaar zijn, weer te geven of te verbergen. Op deze manier kunnen bewerkingen in de loop van de tijd toenemen of zich ontwikkelen zonder kwetsbaarheid te veroorzaken van de toepassingen die er afhankelijk van zijn.

API-aantekening

OpenAPI kent geen intrinsieke ondersteuning voor operationeel versiebeheer. Om ons doel te verwezenlijken, wordt veel werk gedaan via het object x-ms-api-annotation, dat zowel op globale als operationele schaal wordt toegepast. Het globale object bevat eigenschappen die op de API als geheel van toepassing zijn:

{
    "x-ms-api-annotation": {
        "status": "Preview"
    }
}
Eigenschap Waarden Standaardinstelling Beschrijving
status "Preview" "Production" "Preview" Status van de API als geheel, van preview-versie tot productiefase, zoals gedicteerd door gebruik en stabiliteit

Op operationele schaal bevat dit object meer gedetailleerde eigenschappen. Er zijn ook aanvullende eigenschappen buiten het object om die van toepassing zijn op en deelnemen aan het ontwikkelproces van het versiebeheer:

{
    "deprecated": true,
    "x-ms-api-annotation": {
        "status": "Production",
        "family": "MyOperation",
        "revision": 2
    }
}
Eigenschap Waarden Standaardinstelling Beschrijving
deprecated null false true false Geeft aan of de bewerking is afgeschaft
x-ms-visibility null "" "Important" "Advanced" "Internal" "" Beoogde zichtbaarheid en opvallendheid van deze bewerking, waar null of "" een status Normaal impliceert
status "Preview" "Production" "Production" Status van de bewerking: deze kan verschillen van de status van de API zelf, maar indien niet gespecificeerd, wordt deze overgenomen van de API-status op het hoogste niveau
family {algemene naam van bewerking} operationName De naam die van toepassing is op elke revisie van deze bewerking
revision numeriek (1, 2, 3 enz.) 1 Revisie van de opgegeven operationele familie
expires ISO8601-datum (geen) Optionele hint voor client om beoogd einde van ondersteuning aan te geven

Afgeschaft kan worden ingesteld op true als clients deze bewerking niet langer willen gebruiken. Deze eigenschap is aanwezig in de specificatie Vaste OpenAPI-velden.

Zichtbaarheid is een indicator van de beoogde relatieve opvallendheid van de bewerking. De zichtbaarheid "Important" geeft aan dat de bewerking boven aan de lijst moet staan, duidelijk zichtbaar. Een normale zichtbaarheid (aangegeven door null of een lege tekenreeks "") is standaard. Dit betekent dat de bewerking in de lijst wordt weergegeven, waarschijnlijk na de belangrijke bewerkingen. Een zichtbaarheid "Advanced" betekent dat de bewerking ergens onder aan de lijst voorkomt of mogelijk in eerste instantie verborgen achter een expando-besturingselement. Geavanceerde bewerkingen kunnen lastiger zijn om te gebruiken, minder populaire of minder toepasbaar. Zichtbaarheid "Internal" geeft aan dat de bewerking voor de gebruiker zichtbaar moet zijn en alleen intern moet worden gebruikt. Interne bewerkingen zijn programmatisch zinvol en waardevol, maar niet bedoeld voor eindgebruikers. Interne bewerkingen kunnen ook als zodanig worden gemarkeerd zodat ze tijdens het afschaffingsproces in elk soort gebruikersinterface verborgen zijn zonder dat ze feitelijk uit de API worden verijderd, omdat dit kan resulteren in een 'breaking change' (wijziging die fouten kan veroorzaken).

Status geeft de stabiliteit van de API of bewerking aan. "Preview" geeft aan dat de bewerking of API nieuw is en potentieel onbewezen. Preview is een indicator waarop productiesystemen bij het aannemen van een afhankelijkheid bedacht moeten zijn. Als de bewerking of API eenmaal meer is ingeburgerd en bewezen heeft dat het voldoet aan de normen voor betrouwbaarheid, slagingspercentage en schaalbaarheid, kan deze bewust worden geüpgraded naar status "Production".

De volgende metrieke vereisten zijn over het algemeen van toepassing op bewerkingen die een status "Production" nastreven:

  • een slagingspercentage van 80% gedurende een periode van drie weken
    • gedefinieerd als het percentage HTTP-responscodes binnen het 2xx-bereik
  • 99,9% betrouwbaarheid gedurende een periode van drie weken
    • gedefinieerd als percentage van de HTTP-responscodes in het niet-5xx bereik (502, 504 en 520 zijn van deze berekening uitgesloten)

Family geeft de relatie aan tussen bewerkingen die conceptueel dezelfde bewerking, maar verschillende revisies zijn, met mogelijke wijzigingen die fouten veroorzaken. Meerdere bewerkingen delen dezelfde naam voor family als ze als revisies van elkaar moeten worden beschouwd en geordend op basis van hun unieke revisienummers.

Revision geeft de ontwikkelingsvolgorde aan van de bewerking binnen de reeks (family) bewerkingen. Elke bewerking binnen een reeks (family) heeft een revisie die een integrale index vormt die de volgorde bepaalt. Een lege revisie wordt beschouwd als revisie 1. Als nieuwere revisies van een bewerking beschikbaar zijn, moeten ze prominenter worden weergegeven en doelbewuster aanbevolen. Er moet nog wel een selectie van potentieel oudere versie mogelijk zijn die nog niet zijn afgeschaft.

Vervaldatum is optioneel en duidt op een deadline met een potentieel einde van de levensduur, waarbij ondersteuning voor de bewerking niet langer wordt gegarandeerd. Dit moet alleen worden ingesteld voor afgeschafte bewerkingen en wordt momenteel niet in een interface weergegeven.

Operationele levensduur

Bewerkingen hebben een voorspelbare levensduur die kunnen worden getoond door middel van voorbeelden.

Beginpunt

Bewerkingen hoeven in eerste instantie niets over revisies aan te geven. Op deze bewerkingen zijn standaardwaarden toegepast en deze worden dus beschouwd als revisie 1 in een reeksnaam die equivalent is met de operationId.

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

Dit is equivalent aan de meer expliciete definitie:

{
    "/{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
            }
        }
    }
}

Initiëring van de bewerking

Bij de meeste ontwikkelingen van een API gaat het om het optellen van een bewerking. Bijvoorbeeld nieuwe methoden en revisies van bestaande methoden. Als we veilig een nieuwe revisie willen initiëren, passen we de OpenAPI-specificatie als volgt aan:

{
    "/{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
            }
        }
    }
}

Belangrijk

GetItems V2 heeft een unieke operationId en wordt in eerste instantie vermeld als preview. Voor GetItems V1 geldt een geavanceerde zichtbaarheid en deze wordt dus minder duidelijk weergegeven.

Afschaffing van bewerking

Soms blijven bestaande V1-ingangspunten voor onbepaalde tijd behouden als ze waardevol blijven en er geen dwingende reden bestaat ze te onderdrukken. Veel V2-ingangspunten zullen echter het V1-ingangspunt doelbewust vervangen. Om dit op een veilige manier te doen, moet alle verkeer naar de oorspronkelijke bewerking nominaal nul bereiken. Zodra telemetrie deze omstandigheid heeft bevestigd, kan de volgende wijziging worden aangebracht:

{
    "/{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
            }
        }
    }
}

Belangrijk

GetItems V1 is nu als afgeschaft gemarkeerd. Dit is de laatste overgang voor het afschaffen van bewerkingen. GetItems V2 heeft GetItems V1 nu volledig vervangen.

Waar is dit voor nodig?

Er zijn talloze redenen om te voldoen aan operationeel versiebeheer. In de eerste plaats zorgt dit ervoor dat clients als Azure Logic Apps en Power Automate correct blijven werken wanneer gebruikers connectorbewerkingen in hun gegevensstromen integreren. Op bewerkingen moet versiebeheer met behulp van de bovenstaande methode worden toegepast indien:

  • Er wordt een nieuwe revisie van een bewerking toegevoegd
  • Met een bestaande bewerking worden parameters toegevoegd of verwijderd
  • Een bestaande bewerking wijzigt de invoer of uitvoer aanzienlijk

Strikt gesproken

Er kunnen situaties zijn waarin u geen versiebeheer nodig hebt—maar u moet wel uiterst zorgvuldig te werk gaan als u dit doet en veelvuldig testen om ervoor te zorgen dat u geen randgevallen over het hoofd hebt gezien waarbij gebruikers onverwacht worden verbroken. Hier ziet u de korte lijst met gevallen waarbij u het zonder versiebeheer kunt stellen:

  • Er is een nieuwe bewerking toegevoegd.

    Hierdoor worden bestaande clients niet specifiek onderbroken.

  • Er is een nieuwe optionele parameter toegevoegd aan een bestaande bewerking.

    Hierdoor worden bestaande oproepen niet onderbroken, maar moeten ze zorgvuldig worden overwogen.

  • Het gedrag van een bestaande bewerking verandert op subtiele wijze.

    Dit kan ertoe leiden dat bestaande bellers niet worden verbroken op basis van de aard van de wijziging en waarvan gebruikers afhankelijk zijn. Dit is de meest precaire situatie, omdat een aanzienlijk verschil in de acceptatie van de invoer, de generatie van uitvoer, de timing of de verwerking van negatieve invloed kan zijn op het gedrag van de bewerking, en wel op een manier waardoor het risico van de wijziging zich moeilijk laat vaststellen.

Het wordt altijd aangeraden het zekere voor het onzekere te nemen en een revisie te itereren als u niet-triviale wijzigingen aan de API aanbrengt.

Feedback geven

We stellen feedback over problemen met ons connectorplatform of ideeën voor nieuwe functies zeer op prijs. Om feedback te geven, gaat u naar Problemen melden of hulp krijgen met connectoren en selecteer uw feedbacktype.