Az API-verziózásról szóló viták szinte mindig a rossz végén kezdődnek: azon, hogy hová kerüljön a verziószám. Ez az egész téma legkevésbé súlyos döntése. Ami számít, az az, hogy egyáltalán mely változtatások igényelnek új verziót, és a legtöbb csapat itt téved, mégpedig a nemtörődömség irányába: kiadnak valamit, amit tisztán bővítőnek hisznek, és eltörik tőle egy kliens.
A használható gondolati modell az, hogy az API ígéret arról, mire számíthat a hívó fél. Egy változtatás akkor törő, ha érvénytelenné tesz valamit, amire egy józan hívó épített, a hívók pedig sokkal többre építenek, mint amennyit a dokumentáció kifejezetten megenged nekik.
A változtatás, ami mindenkit elkap: egy mező hozzáadása a válaszhoz. Bővítő jellegű, egy jól megírt klienst nem tud eltörni, valódi klienseket viszont rendszeresen eltör, mert némelyikük szigorúan validálja a választ, és elutasítja az ismeretlen mezőket. Hogy ez a ti hibátok-e vagy az övék, teljesen mindegy attól a pillanattól, hogy az integrációjuk áll, és csörög a telefon.
Mi számít valóban törő változtatásnak
Egyértelműen törő: egy mező eltávolítása vagy átnevezése, egy mező típusának megváltoztatása, kötelező kérésparaméter bevezetése, a validáció szigorítása, egy meglévő érték jelentésének megváltoztatása, vagy olyan státuszkód módosítása, amelyre a hívó elágazik.
A gyakorlatban törő, pedig biztonságosnak látszik: mező hozzáadása a válaszhoz, ha a kliensek szigorúan validálnak. Egy tömb sorrendjének megváltoztatása, amit soha nem ígértetek meg, a hívók viszont feltételeztek. Egy hibaüzenet megváltoztatása, amelynek a szövegére valaki karakterláncként illeszt. Egy szinkron művelet aszinkronná tétele.
Valóban biztonságos: új, opcionális kérésparaméter felvétele, új végpont hozzáadása, a validáció lazítása, és új érték felvétele egy felsorolásba, de csak akkor, ha a kliensek előre megkapták, hogy ismeretlen értékekre számítsanak, és le tudjátok ellenőrizni, hogy kezelik is őket.
A minta az, hogy a biztonság attól függ, mit tesznek ténylegesen a hívók, nem attól, mit enged meg a specifikáció. Ha minden kliens a kezetekben van, ez ellenőrizhető. Ha nincs, induljatok ki abból, hogy valaki éppen arra épít, amit mellékesnek gondoltatok, mert így van.
API-verziózási stratégiák és az áruk
Verzió az URL-ben. A legelterjedtebb megközelítés, és az az erénye, hogy nyilvánvaló: a /v1/orders és a /v2/orders láthatóan különböző erőforrás. Az ára az, hogy a teljes API verzióugrásaira ösztönöz, így egyetlen végpontot érintő változás mindent magával ránt, a klienseknek pedig egyszerre kell átállniuk.
Verzió egy fejlécben. Stabilan tartja az URL-eket, és finomabb bontást enged, cserébe láthatatlan. A verziót senki nem látja böngészőben vagy egy naplósorban, ha nem keresi, a fejlécet elhagyó hívó pedig azt kapja, ami az alapértelmezés, és ezt tudatosan kell eldöntenetek.
Dátumalapú verziózás. A hívó rögzít egy dátumot, és úgy kapja meg az API-t, ahogyan akkor viselkedett. A Stripe így dokumentálja ezt a megközelítést: minden fióknak van alapértelmezett verziója, a kérések pedig egyenként felülírhatják. Ez adja a lehető legkisebb átállási lépéseket, a kompatibilitás terhét viszont a saját kódbázisotokra tolja, amelynek innentől verziók közötti átalakításokat kell karbantartania.
Semmilyen verziózás, csak bővítő változtatás. Járható és alulértékelt út, ha komolyan el tudjátok kötelezni magatokat amellett, hogy soha nem vesztek el semmit. Az ára a felhalmozódó mezők, amelyeket nem lehet törölni, és a viselkedés, amit nem lehet javítani: lassú adó a hirtelen számla helyett.
Nincs helyes válasz, csak alku a ti átállási terhetek és az ügyfeleitek terhe között. A dátumalapú verziózás a legkíméletesebb a hívókkal és a legdrágább üzemeltetni. Az URL-verziózás pontosan fordítva működik.
Hogyan tehető elviselhetővé egy törő változtatás
Előbb bővíts, aztán szűkíts. Vegyétek fel az új mezőt a régi mellé. Töltsétek mindkettőt. Adjatok időt a klienseknek az átállásra. A régit egy későbbi verzióban vegyétek ki. Ezzel egy törő változtatásból két biztonságos lesz, és a plusz lépés szinte mindig megéri.
Mérjétek, ki mit használ. Nem lehet biztonságosan kivezetni egy verziót anélkül, hogy tudnátok, ki ül rajta. Naplózzátok minden kérésnél a verziót és a kliens azonosítóját, hogy a kivezetés bizonyítékokra épülő beszélgetés legyen, ne pedig a sötétbe kiáltott bejelentés.
Mechanizmussal jelentsétek be, ne csak e-mailben. A Deprecation és a Sunset válaszfejléc segítségével a kliens programból is felfedezheti a kivezetés dátumát, és ezt nagyobb eséllyel veszik észre, mint egy olyan címre küldött üzenetet, amit már senki nem olvas.
Adjatok reális határidőt. Az integrációkat olyan emberek tartják karban, akiknek más a prioritásuk, és a kiadási ciklusuknál rövidebb határidőt egyszerűen elszalasztják. Hat hónap szokásos egy nyilvános API-nál; ennél kevesebb is elfogadható néhány ismert partner esetében, akikkel beszéltetek.
Egy régi verzió kivezetése
A fenti mérés az, ami ezt a lépést egyáltalán lehetővé teszi. Jelentsétek be a dátumot, figyeljétek, ahogy csökken a forgalom, és keressétek meg névre szólóan azokat a hívókat, akik nem álltak át.
Számítsatok hosszú farokra. Lesznek olyan integrációk, amelyekről az ügyfélnél már senki nem emlékszik, hogy az övék, és akkor derülnek ki, amikor kikapcsoljátok a verziót. Itt segítenek a rövid próbaleállások: a végleges dátum előtt előre bejelentett időpontokban kapcsoljátok ki rövid időre a régi verziót, hogy a hiba akkor következzen be, amikor valaki számít rá, ne pedig egy zsúfolt időszak közepén.
Az őszinte álláspont az, hogy egyes hívók csak akkor mozdulnak, amikor a régi verzió megszűnik működni. Tervezzetek ezzel, ahelyett hogy meglepne titeket, és gondoskodjatok róla, hogy a hibajelenség egy világos üzenet legyen arról, mi történt, ne pedig időtúllépés.
A verzió, amire nincs szükségetek
A legtöbb belső API-nak egyáltalán nincs szüksége verziózásra, mert minden hívó a kezetekben van, és mindkét oldalt együtt tudjátok módosítani. Verzióegyeztetést tenni egy olyan felületre, amelyet két saját szolgáltatásotok használ, olyan gépezet, ami kerül valamibe, és semmitől nem véd meg.
Az a pont teszi szükségessé, amikor már nem tudjátok az összes fogyasztót egyszerre kitelepíteni, akár azért, mert másik csapathoz, másik kiadási ciklushoz vagy másik céghez tartoznak. Ez az igazi kiváltó ok, és semmi köze ahhoz, mennyire nyilvános az API. A serverless API-król szóló útmutatónk tervezési szempontjai ugyanígy érvényesek a peremhálózaton is.
A Mecanik ilyen API-kat tervez és tart karban a szoftverfejlesztési munkánk részeként. A verziószámozás sémája ritkán az érdekes döntés; az viszont mindig az, hogy melyik hívótok van még a régin.
Gyakran ismételt kérdések
Mi számít kompatibilitástörő API-változtatásnak? Egy mező eltávolítása vagy átnevezése, a típusának megváltoztatása, kötelező paraméter bevezetése, a validáció szigorítása, egy érték jelentésének megváltoztatása, vagy olyan státuszkód módosítása, amelyre a hívók elágaznak. A gyakorlatban törő az is, ha szigorúan validáló kliensek mellett új mezőt tesztek a válaszba, ha megváltoztatjátok a hívók által feltételezett tömbsorrendet, vagy ha átírtok egy hibaüzenetet, amelynek szövegére valaki illeszt.
Az URL-be vagy egy fejlécbe tegyem az API verzióját? Az URL-verziózás látható és egyszerű, de a teljes API ugrásaira ösztönöz, és arra kényszeríti a klienseket, hogy mindent egyszerre migráljanak. A fejléces verziózás stabilan tartja az URL-eket és finomabb bontást enged, viszont naplóban és böngészőben láthatatlan, és tudatos alapértelmezést kíván azoknak, akik elhagyják. Egyik sem rossz; a ti átállási terheteket cserélik el az ügyfeleitekére.
Mi az a dátumalapú API-verziózás? A hívó rögzít egy dátumot, és úgy kapja meg az API-t, ahogyan akkor viselkedett, ahogyan a Stripe teszi fiókonkénti alapértelmezett verzióval, amelyet az egyes kérések felülírhatnak. Ez adja a klienseknek a lehető legkisebb átállási lépéseket, és a kompatibilitás terhét a ti kódbázisotokba tolja, amely ezután a verziók közötti átalakításokat tartja karban.
Milyen hosszú legyen egy API kivezetési időszaka? Hat hónap szokásos egy nyilvános API-nál, és ennél kevesebb is elfogadható néhány ismert partner esetében, akikkel közvetlenül beszéltetek. Az integrációkat más prioritásokkal dolgozó emberek tartják karban, így a kiadási ciklusuknál rövidebb időablakot elszalasztják, bármilyen világosan jelentettétek is be.
Kell-e verziózni a belső API-kat? Általában nem, mert minden hívó a kezetekben van, és mindkét oldalt együtt tudjátok módosítani. A verziózás attól a ponttól válik szükségessé, ahol már nem tudjátok az összes fogyasztót egyszerre kitelepíteni, akár másik csapathoz, kiadási ciklushoz vagy céghez tartoznak. Ez a kiváltó ok, nem az, hogy nyilvános-e az API.
Hozzászólások