Udvikling af din API med versionsstyring
Brugerdefinerede connectorer til Azure Logic Apps, Microsoft Power Automate eller Microsoft Power Apps skal levere en OpenAPI-specifikationsfil. Denne OpenAPI-specifikation definerer individuelle indgangspunkter kaldet handlinger eller operationer. Hver handling har et unikt operationId samt en unik kombination af urlPath og 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"
}
}
}
Disse handlinger kan vokse og ændre sig over tid, efterhånden som funktioner tilføjes eller udvides. Nogle ændringer er blot additive og afbryder ikke nødvendigvis den kontrakt, der findes mellem klienter og servere. Tilføjelse af nye parametre, returnering af flere data eller tilladelse af mere fleksible input kan høre ind under denne kategori.
Mange ændringer kan dog faktisk afbryde den kontrakt, der er beskrevet i OpenAPI-specifikationen. Fjernelse af parametre, der ikke længere understøtter bestemte input, eller ændring af betydningen og funktionsmåden af et input, et output eller selve handlingen hører under kategorien "afbrydelsesændring".
For at kunne udvikle en API på en sikker måde er det vigtigt at følge et mønster, som klienter kan navigere i. Det er API'ens ansvar at opretholde bagudkompatibilitet, kommunikere intentionen og skitsere attributterne for versionsstyring. Det er klientens ansvar enten at vise eller skjule de handlinger, der er udfaset, udløbet eller som kan have nyere versioner tilgængelige. På denne måde kan handlinger vokse og udvikle sig over tid, uden at det medfører unødig skrøbelighed af programmer, der er afhængige af dem.
API-note
OpenAPI har ikke indbygget understøttelse af operativ versionsstyring. For at opnå vores mål udføres meget af arbejdet via objektet x-ms-api-annotation, som anvendes både i globalt omfang og i handlingsmæssigt omfang. Det globare objekt indeholder egenskaber, som gælder for API'en som helhed:
{
"x-ms-api-annotation": {
"status": "Preview"
}
}
| Egenskab | Værdier | Standard | Beskrivelse |
|---|---|---|---|
| status | "Preview" "Production" |
"Preview" |
Status for API'en som helhed starter som en forhåndsversion og eskalerer til produktion i henhold til forbrug og stabilitet |
I driftsomfang indeholder objektet mere detaljerede egenskaber. Der er også yderligere egenskaber uden for objektet, som gælder for og er omfattet af udviklingsprocessen for versionsstyring:
{
"deprecated": true,
"x-ms-api-annotation": {
"status": "Production",
"family": "MyOperation",
"revision": 2
}
}
| Egenskab | Værdier | Standard | Beskrivelse |
|---|---|---|---|
| udfaset | null false true |
false |
Angiver, om handlingen er udfaset |
| x-ms-visibility | null "" "Important" "Advanced" "Internal" |
"" |
Tilsigtet synlighed og fremtrædelse af denne handling, hvor null eller "" implicerer en Normal tilstand |
| status | "Preview" "Production" |
"Production" |
Status for handlingen, som kan variere fra tilstanden af selve API'en, men hvis den ikke angives, nedarves den fra det øverste statusniveau for API'en |
| familie | {almindeligt handlingsnavn} | operationName | Det navn, der gælder for hver revision af denne handling |
| revision | numerisk (1,2,3...) | 1 |
Revision af den angivne driftsmæssige familie |
| udløber | ISO8601-dato | (ingen) | Valgfrit tip til klienten, der angiver det forventede ophør af understøttelse |
Udfaset kan angives til true, når det ikke længere er ønskværdigt, at klienterne bruger denne handling. Denne egenskab findes i specifikationen fastgjorte felter i OpenAPI.
Synlighed er en indikator på den tilsigtede relative fremtrædelse af handlingen. Synligheden "Important" angiver, at handlingen skal være øverst på listen, så den har en fremtrædende visning. Synligheden normal (angivet med null eller en tom streng "") er standarden og betyder helt enkelt, at handlingen vil blive vist på listen, sandsynligvis efter handlingerne Important. Synligheden "Advanced" angiver, at handlingen kan være placeret nederst på listen eller indledningsvist tilmed skjult bag et expando-kontrolelement. Handlingerne Advanced kan være sværere at bruge eller mindre populære eller simpelthen have et mindre anvendelsesområde. Synligheden "Internal" angiver, at handlingen ikke skal vises for brugerne, og at den kun skal bruges internt. Interne handlinger er programmatisk nyttige og værdifulde, men er ikke tiltænkt slutbrugerne. Interne handlinger kan også blive markeret som sådan for simpelthen at skjule dem fra en hvilken som helst brugergrænseflade under udfasningsprocessen, uden at de rent faktisk fjernes fra API'en, hvilket ellers ville medføre en afbrydelsesændring.
Status angiver stabiliteten af API'en eller handlingen. "Preview" angiver, at handlingen eller API'en er ny og muligvis uprøvet. Preview er en indikator, som produktionssystemer skal være forsigtige med i forhold til at antage, at der er en afhængighed. Når handlingen eller API'en er blevet mere etableret og har bevist, at den opfylder standarderne for pålidelighed, succesrate og skalerbarhed, kan den direkte opgraderes til statussen "Production".
Følgende krav til metrikværdi gælder normalt for handlinger, der søger statussen "Production":
- 80 % succesrate i en periode på tre uger
- defineret som procent af HTTP-svarkoder i området 2xx
- 99,9 % pålidelighed opretholdt i periode på tre uger
- defineret som procent af HTTP-svarkoder i området, der ikke er 5xx (502, 504 og 520 er ikke omfattet af denne beregning)
Familie angiver relationen mellem handlinger, der konceptuelt er den samme handling, men som er forskellige revisioner med potentielle afbrydelsesændringer imellem dem. Flere handlinger deler samme familienavn, hvis de skal anses for at være revisioner af hinanden, og de sorteres efter deres entydige revisionsnumre.
Revision angiver udviklingsrækkefølgen af handlingen i familien af handlinger. Hver handling i en serie har en revision, der er et integreret indeks, som angiver rækkefølgen. En tom revision anses for at være revision 1. Når nyere versioner af en handling er tilgængelige, skal klienterne vise dem mere fremtrædende og anbefale dem mere bevidst, men stadigt tillade valg af eventuelle ældre revisioner, der endnu ikke er udfaset.
Udløber er valgfri og angiver en potentiel deadline for ophør af levetid, hvor understøttelse af handlingen ikke længere garanteres. Dette skal kun angives for udgåede handlinger og afspejles i øjeblikket ikke i nogen grænseflader.
Driftsmæssig levetid
Der er en forudsigelig levetid for handlinger, der kan vises med eksempler.
Startpunkt
Indledningsvist angiver handlinger ikke nødvendigvis noget om revisioner. Der er anvendt standarder for disse handlinger, og de anses derfor som revision 1 i et familienavn, der svarer til operationId.
{
"/{list}/items": {
"get": {
"summary": "Get rows",
"description": "This operation gets a list of items.",
"operationId": "GetItems"
}
}
}
Dette svarer til den mere eksplicitte 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
}
}
}
}
Initiering af handling
De fleste udviklinger af en API medfører tilføjelse af en handling. For eksempel nye metoder og nye revisioner af eksisterende metoder. For at initiere en ny revision sikkert justerer du specifikationen af OpenAPI på følgende måde:
{
"/{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
}
}
}
}
Vigtigt
Bemærk, at GetItems v2 har et unikt operationId, og at den indledningsvist vises med statussen som forhåndsversion.
Bemærk også, at GetItems v1 nu har avanceret synlighed, så den vises ikke som fremtrædende.
Udfasning af handling
Nogle gange forbliver eksisterende V1-indgangspunkter på ubestemt tid, hvis de fortsætter med at levere værdi, og der ikke er nogen tungtvejende årsag til at lade dem udgå. Men mange V2-indgangspunkter tilsidesætter bevidst V1-indgangspunktet. For at kunne gøre det på en sikker måde bør al trafik nå nominelt nul for den oprindelige handling. Når telemetrien bekræfter dette tilfælde, kan følgende ændring foretages:
{
"/{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
}
}
}
}
Vigtigt
Bemærk, at GetItems V1 nu er markeret som udfaset. Dette er den endelige overgang for udfasede handlinger. GetItems V2 har nu fuldstændigt erstattet GetItems V1.
Hvorfor tage sig af det?
Der er mange grunde til at overholde driftsmæssig versionsstyring. Det vil primært sikre, at klienter som Azure Logic Apps og Power Automate fortsat fungerer korrekt, når brugerne integrerer connectorhandlinger i deres dataflow. Versionsstyring af handlinger bør benytte ovenstående metode, når:
- Der tilføjes en ny revision af en handling
- Der tilføjes eller fjernes parametre for en eksisterende handling
- Input eller output ændres markant for en eksisterende handling
Praktisk talt
Der kan være tilfælde, hvor du ikke behøver at bruge versionsstyring, men du skal være forsigtig med det og udføre masser af test for at sikre, at du ikke har overset grænsetilfælde, hvor brugerne utilsigtet afbrydes. I alle tilfælde er her den forsigtige, korte liste over, hvornår du ikke behøver at bruge det:
Der er tilføjet en helt ny handling.
Dette afbryder ikke specifikt eksisterende klienter.
Der føjes en ny valgfri parameter til en eksisterende handling.
Dette afbryder ikke eksisterende kald, men skal overvejes nøje.
Funktionsmåden af en eksisterende handling ændres diskret.
Dette afbryder muligvis ikke eksisterende kald baseret på typen af ændringen, og hvad brugerne sætter deres tillid til. Dette er den mest usikre af alle, da en markant forskel i accepten af input, generering af output, timing eller behandling kan påvirke handlingens funktionsmåde på måder, der kan gøre det svært at vurdere risikoen af ændringen.
Det anbefales altid at være på den sikre side og oprette en revision, når du foretager en hvilken som helst ændring af API, som ikke er triviel.