Ako vytvoriť verziu rozhrania REST API

Ak nie ste veľmi oboznámení s API, možno by vás zaujímalo ... prečo všetok ten rozruch okolo verzií API?

Ak vás zmeny API spálili, pravdepodobne ste ten pravý. Ak ste udržiavateľom rozhrania API, môžete sa tiež trápiť pri pokuse postaviť náročné otázky, ako sú tieto:

# Is this version 2 of just products or of the entire API? /v2/products # What catalyzed the change between v1 and v2? How are they different? /v1/products /v2/products

Na tieto otázky týkajúce sa správy verzií nie je ľahké odpovedať. To nie je vždy jasné, o tom, čo v1alebo v2odkazuje. Nemali by sme robiť iba druhú verziu koncového bodu, keď sa už zdá, že prvá nestačí.

Existujú jasné dôvody, prečo musí vaše rozhranie API mať verzie, a existujú jasné stratégie, ako efektívne prechádzať zmenami API.

Zistil som však, že väčšina vývojárov - vrátane mňa samej, kým som sa ťažko nepoučila z niektorých ponaučení - nevie o týchto dôvodoch a stratégiách.

Tento článok sa snaží poukázať na dôvody verzovania a stratégie jeho dosiahnutia. Budeme predpokladať kontext REST API, pretože je to štandard pre mnoho rozhraní API, a zameriame sa na aspekt správy verzií .

Čo je správa verzií?

Mali by sme začať s nastavením úrovne na to, čo sa myslí pod pojmom „Verzia API“. Tu je naša pracovná definícia:

Verzovanie API je prax transparentného riadenia zmien vo vašom API.

Správa verzií je efektívna komunikácia okolo zmien vo vašom API, takže zákazníci vedia, čo od nich môžu očakávať. Poskytujete údaje verejnosti nejakým spôsobom a pri zmene spôsobu poskytovania údajov musíte komunikovať.

To, v jadre, je správa dátových kontraktov a prelomenie zmien. Prvý je hlavným stavebným prvkom vášho API a druhý ukazuje, prečo je potrebná verzia.

Dátové zmluvy

API je aplikačné programové rozhranie a rozhranie je spoločnou hranicou výmeny informácií. Zmluva o údajoch je jadrom tohto rozhrania.

Zmluva o údajoch je dohoda o podobe a všeobecnom obsahu údajov o požiadavke a / alebo odpovedi.

Na ilustráciu zmluvy o dátach je tu základné telo odpovede JSON:

{ "data": [ { "id": 1, "name": "Product 1" }, { "id": 2, "name": "Product 2" } ] }

Je to objekt s datavlastnosťou, ktorá je poľom (zoznamom) produktov, každý s vlastnosťou ida name. Ale datavlastnosť môže mať rovnako ľahko boli povolaní body, a idvlastnosť pre každý výrobok mohol byť GUID namiesto celé číslo. Ak sa vracal jeden produkt, datamohol by to byť objekt namiesto poľa.

Tieto zdanlivo jemné zmeny by priniesli inú dohodu, inú zmluvu, pokiaľ ide o „tvar“ údajov. Tvar údajov by sa mohol vzťahovať na názvy vlastností, dátové typy alebo dokonca na očakávaný formát (JSON vs. XML).

Prečo je potrebná správa verzií?

S API môže niečo také jednoduché ako zmena názvu vlastnosti z productIdna zmeniť productIDveci pre spotrebiteľov. Nášmu tímu sa minulý týždeň stala práve táto vec.

Našťastie sme mali testy, aby sme zachytili zmeny v zmluve o API. Tieto testy by sme však nemuseli potrebovať, pretože správcovia API mali vedieť, že by to bola zlomová zmena.

Prelomové zmeny

Išlo o prelomovú zmenu dohodnutej dátovej zmluvy, pretože ich zmena nás prinútila zmeniť aj našu aplikáciu.

Čo predstavuje „zlomovú zmenu“ v koncovom bode API? Akákoľvek zmena vašej zmluvy o API, ktorá prinúti spotrebiteľa vykonať tiež zmenu.

Prelomové zmeny zapadajú predovšetkým do nasledujúcich kategórií:

  1. Zmena formátu požiadavky / odpovede (napr. Z XML na JSON)
  2. Zmena názvu vlastnosti (napr. Z namena productName) alebo dátového typu pre vlastnosť (napr. Z celého čísla na plavák)
  3. Pridanie povinného poľa k žiadosti (napr. Nová požadovaná hlavička alebo vlastnosť v tele žiadosti)
  4. Odstránenie vlastnosti odpovede (napr. Odstránenie descriptionz produktu)

Správa zmien API

Nikdy nie je múdre ani láskavé nútiť spotrebiteľov rozhrania API vykonať zmenu. Ak musíte urobiť zásadnú zmenu, na to slúži spravovanie verzií a budeme sa venovať najefektívnejším spôsobom, ako spravovať verzie vašej aplikácie a koncových bodov.

Najprv si však krátko poďme rozobrať, ako sa vyhnúť prelomovým zmenám. Mohli by sme to nazvať Správa zmien API.

Efektívne riadenie zmien v kontexte API je zhrnuté v nasledujúcich zásadách:

  • Pokračovať v podpore existujúcich vlastností / koncových bodov
  • Namiesto zmeny existujúcich, pridajte nové vlastnosti / koncové body
  • Zamyslene ukončujeme zastarané vlastnosti / koncové body

Tu je príklad, ktorý demonštruje všetky tri tieto princípy v kontexte odpovede na vyžiadanie údajov používateľa:

{ "data": { "id": 1, "name": "Carlos Ray Norris", // original property "firstName": "Carlos", // new property "lastName": "Norris", // new property "alias": "Chuck", // obsolete property "aliases": ["Chuck", "Walker"] // new property }, "meta": { "fieldNotes": [ { "field": "alias", "note": "Sunsetting on [future date]. Please use aliases." } ] } }

V tomto príklade nameišlo o pôvodnú nehnuteľnosť. Tieto firstNamea lastNamepolia sú realizované poskytnúť presnejšie možnosť, aby v prípade, že spotrebiteľ chce zobraziť "Pán Norris" s niektorými reťazcami interpoláciou, ale aby bolo nutné analyzovať namepole. Ubytovacie zariadenie však namebude priebežne podporované.

alias, na druhej strane, bude zastarané v prospech aliasespoľa - pretože Chuck má toľko aliasov - a v odpovedi je poznámka označujúca časový rámec ukončenia.

Ako vytvoríte verziu API?

Tieto princípy budú trvať dlho, kým prejdete zmenami vo vašom API bez toho, aby ste museli zavádzať novú verziu. Niekedy sa tomu však dá vyhnúť a ak potrebujete úplne nový kontrakt na dáta, budete potrebovať novú verziu vášho koncového bodu. Budete to teda musieť nejakým spôsobom oznámiť verejnosti.

Ako dodatok si všimnite, že nehovoríme o verzii základného kódového základu. Takže ak pre svoju aplikáciu používate sémantické verzovanie, ktoré podporuje aj verejné API, budete pravdepodobne chcieť tieto verzovacie systémy oddeliť.

Ako vytvoríte novú verziu vášho API? Aké sú rôzne spôsoby, ako tak urobiť? Budete musieť určiť, aký typ stratégie vytvárania verzií chcete všeobecne použiť, a potom pri vývoji a údržbe rozhrania API budete musieť určiť rozsah každej zmeny verzie.

Rozsah

Poďme sa najskôr zaoberať rozsahom. Ako sme skúmali vyššie, niekedy dôjde k narušeniu kontraktov na dáta zlomovou zmenou, čo znamená, že budeme musieť poskytnúť novú verziu kontraktu na dáta. To by mohlo znamenať novú verziu koncového bodu alebo by to mohlo znamenať zmenu v globálnejšom rozsahu aplikácie.

Môžeme uvažovať o úrovniach zmeny rozsahu v rámci stromovej analógie:

  • List - Zmena izolovaného koncového bodu bez vzťahu k iným koncovým bodom
  • Pobočka - zmena skupiny koncových bodov alebo zdroja, ku ktorému sa pristupuje prostredníctvom niekoľkých koncových bodov
  • Kmeň - zmena na úrovni aplikácie, ktorá zaručuje zmenu verzie pre väčšinu alebo všetky koncové body
  • Koreň - zmena ovplyvňujúca prístup ku všetkým prostriedkom API všetkých verzií

Ako vidíte, pri prechode z listu na koreň sa zmeny stávajú čoraz účinnejšími a globálnejšími.

Rozsah listu sa dá často vybaviť prostredníctvom efektívneho riadenia zmien API. Ak nie, jednoducho vytvorte nový koncový bod pomocou novej zmluvy o údajoch o zdrojoch.

Vetva je trochu zložitejšie, v závislosti na tom, ako veľa koncových bodov sú ovplyvnené zmenou zmluvy Údaje o zdroje sa jedná. Ak sú zmeny relatívne obmedzené na jasnú skupinu súvisiacich koncových bodov, môžete v tom potenciálne prechádzať zavedením nového názvu prostriedku a príslušnou aktualizáciou svojich dokumentov.

# variants, which has a breaking change, is accessed on multiple routes /variants /products/:id/variants # we introduce product-variants instead /product-variants /products/:id/product-variants

Trup sa odkazuje na zmeny na úrovni aplikácie, ktoré sú často výsledkom zmeny jednej z nasledujúcich kategórií:

  • Formát (napr. Z XML do JSON)
  • Špecifikácia (napr. Z interného na JSON API alebo Open API)
  • Požadované hlavičky (napr. Na autentifikáciu / autorizáciu)

Bude to vyžadovať zmenu vašej celkovej verzie API, takže by ste mali starostlivo naplánovať a uskutočniť prechod dobre.

Zmena typu root vás prinúti ísť o krok ďalej v zaistení toho, aby o tejto zmene vedeli všetci zákazníci všetkých verzií vášho API.

Typy spravovania verzií API

Keď sa obrátime na rôzne typy verzií API, budeme chcieť na vyhodnotenie typov využiť tieto štatistiky týkajúce sa rôznych rozsahov zmien API. Každý prístup má svoju vlastnú skupinu silných a slabých stránok pri riešení zmien na základe ich rozsahu.

Existuje niekoľko spôsobov správy verzie vášho API. Najbežnejšie je spravovanie verzií cesty URI.

Cesta URI

//www.example.com/api/v1/products //api.example.com/v1/products

Táto stratégia spočíva v uvedení čísla verzie do cesty URI a často sa vykonáva s predponou „v“. Dizajnéri API to častejšie používajú na označenie verzie svojej aplikácie (tj. „Kufra“) ako verzie koncového bodu („list“ alebo „vetva“), čo však nie je vždy bezpečný predpoklad.

Verzia cesty URI znamená riadené vydania verzií aplikácií, ktoré budú vyžadovať jeden z dvoch prístupov: udržiavanie jednej verzie pri vývoji novej alebo nútenie spotrebiteľov čakať na nové zdroje, kým nebude vydaná nová verzia. Znamená to tiež, že budete musieť preniesť všetky nezmenené koncové body z verzie na verziu. Pre API s relatívne nízkou volatilitou je to však stále slušná voľba.

You would likely not want to relate your version number to that of the endpoint or resource, because it would easily result in something like a v4 of products but a v1 of variants, which would be rather confusing.

Query Params

//www.example.com/api/products?version=1

This type of versioning adds a query param to the request that indicates the version. Very flexible in terms of requesting the version of the resource you'd like at the "leaf" level, but it holds no notion of the overall API's version and lends itself to the same out-of-sync issues mentioned in the above comment on endpoint-level versioning of the URI path.

Header

Accept: version=1.0

The header approach is one that provides more granularity in serving up the requested version of any given resource.

However, it's buried in the request object and isn't as transparent as the URI path option. It's also still hard to tell whether 1.0 refers to the version of the endpoint or the API itself.

Integrating Types

Each of these approaches seem to have the weakness of either favoring a "leaf" or "trunk" scope, but not supporting both.

If you need to maintain the overall API version and also provide support for multiple versions of resources, consider a blend of the URI Path and Query Params types, or a more advanced Header approach.

# URI path and query params combo //api.example.com/v1/products?version=1 //api.example.com/v1/products?version=2 # Extended headers, for //api.example.com/products Accept: api-version=1; resource-version=1 Accept: api-version=1; resource-version=2

Conclusion

We've covered a lot of ground here, so let's recap:

  • API versioning is the practice of transparently managing changes to your API.
  • Managing an API boils down to defining and evolving data contracts and dealing with breaking changes.
  • Najefektívnejším spôsobom, ako vyvinúť svoje API bez porušenia zmien, je dodržiavať efektívne zásady riadenia zmien API.
  • Pre väčšinu API je verzovanie v ceste URI najpriamočiarejším riešením.
  • V prípade zložitejších alebo nestálych rozhraní API môžete spravovať rôzne rozsahy zmien pomocou integrácie prístupov URI cesty a parametrov dotazu.

Hoci tieto princípy by mali poskytovať jasný smer v tom, ako efektívne riadiť zmeny vo vašich API, vývoj API je potenciálne viac ako umenie ako veda. Na vytvorenie a udržanie spoľahlivého API je potrebné premýšľanie a nadhľad.