Preoblikujte svoje API-je za sljedeće desetljeće, a ne samo za sljedeći kvartal
Većina preoblikovanja API-ja ne uspijeva iz razumljivog razloga: planiraju se oko sljedećeg izdanja, a ne oko sljedećih deset godina promjena. Nekoliko se krajnjih točaka preimenuje, polje odgovora se uredi i posao se proglasi dovršenim. U međuvremenu temeljni ugovor ostaje isprepleten s tablicama baze podataka, konvencijama okvira i pretpostavkama koje će postati skupe čim proizvod naraste.
Trajan API nije onaj koji se nikada ne mijenja. To je onaj koji se može mijenjati promišljeno, bez iznenađivanja klijenata ili prisiljavanja svake interne odluke u javni prikaz. To zahtijeva tretiranje API-ja kao dugotrajne granice proizvoda, a ne kao tankog HTTP omotača oko aplikacijskog koda.
Počnite s ugovorom, a ne s kontrolerom
Kontroleri su često najuočljivije mjesto za početak, ali rijetko su pravo središte dizajna. Trebali bi prevesti vanjski zahtjev u aplikacijsku operaciju i rezultat ponovno prevesti u stabilan odgovor. Ako kontroleri sadrže poslovna pravila, ORM upite, rubne slučajeve autorizacije i oblikovanje odgovora, „jednostavna” promjena krajnje točke postaje rizična jer je svaka briga povezana sa svakom drugom brigom.
Zapišite što API obećava prije mijenjanja pojedinosti implementacije. Koristan ugovor odgovara na nekoliko jednostavnih pitanja: kojem se resursu pristupa, koje su operacije podržane, kojim poljima upravlja klijent, koja se polja vraćaju i koje su pogreške značajne pozivateljima?
Na primjer, ruta usmjerena na bazu podataka poput POST /order_items potiče korisnike da razmišljaju u smislu tablice. Akcija usmjerena na zadatak možda je bolje izražena kao POST /orders/{id}/items, gdje servis upravlja provjerama zaliha, pravilima određivanja cijena i prijelazima stanja. URL nije važan dio; granica jest. Klijenti bi trebali tražiti poslovni ishod, a ne orkestrirati internu perzistenciju.
Ne dopustite da sheme baze podataka postanu javne sheme
Najbrži način za stvaranje krhkog API-ja jest izravna serijalizacija ORM modela. Djeluje učinkovito sve dok preimenovanje stupca, promjena normalizacije ili novi interni odnos ne postane javni događaj koji narušava kompatibilnost. Sheme baze podataka optimiziraju pohranu i integritet. API sheme optimiziraju jasnoću, kompatibilnost i upotrebljivost za klijente. Preklapaju se, ali nisu isti dizajn.
Uvedite eksplicitne modele zahtjeva i odgovora, čak i u malom PHP servisu. Transformator odgovora, klasa resursa ili namjenski DTO čini mapiranje vidljivim i provjerljivim. Također timu daje sigurno mjesto za dodavanje ponašanja kompatibilnosti dok se domena ispod njega mijenja.
final class OrderResponse
{
public static function fromOrder(Order $order): array
{
return [
'id' => (string) $order->id,
'status' => $order->status->value,
'total' => [
'amount' => $order->totalInCents,
'currency' => $order->currency,
],
'createdAt' => $order->createdAt->format(DATE_ATOM),
];
}
}
Ovo mapiranje namjerno izbjegava izlaganje naziva stupaca ili prikaza novca specifičnog za bazu podataka. Interno se narudžba može premjestiti s cjelobrojnih centi na namjenski vrijednosni objekt ili shema može podijeliti ukupne iznose u više zapisa. Javni ugovor može ostati stabilan.
Promjene učinite aditivnima kad god je moguće
Kompatibilnost se manje odnosi na izbjegavanje promjena, a više na odabir najmanje ometajućeg slijeda. Dodajte novo polje prije uklanjanja starog. Prihvatite i stari i novi oblik ulaza tijekom definiranog prijelaza. Uvedite novu krajnju točku kada postojeći resurs znači nešto bitno drukčije, umjesto da jednu rutu preopterećujete dvosmislenim zastavicama.
Verzioniranje može pomoći, ali nije zamjena za discipliniranu evoluciju. Putanja poput /v2 pruža jasnu granicu za uistinu nekompatibilne ugovore. Također stvara obvezu održavanja: ako verzija jedan ostane dostupna, treba vlasništvo, testove, dokumentaciju i plan povlačenja. Izbjegavajte stvaranje novih glavnih verzija za kozmetičke promjene odgovora koje su mogle biti aditivne.
Ukidanje treba operativni plan
Polje nije ukinuto zato što to kaže radni zadatak. Klijentima je potrebna zamjena, jasan put migracije, dovoljno obavijesti i način da prepoznaju preostalu upotrebu. Ako API ima autentikaciju, zapisnici i metrike trebali bi operaterima omogućiti utvrđivanje koji identiteti klijenata još uvijek pozivaju krajnju točku ili ovise o starom parametru. Bez te vidljivosti uklanjanje je nagađanje.
- Zajedno dokumentirajte staro ponašanje i njegovu zamjenu.
- Vratite zamjensko polje ili krajnju točku prije najave uklanjanja.
- Pratite upotrebu prema klijentu, ruti i relevantnom obliku zahtjeva.
- Odredite datum pregleda umjesto da ukinuto ponašanje ostavite neograničeno.
- Uklonite kod kompatibilnosti tek nakon što dokazi pokažu da je to sigurno.
Postavite poslovna pravila iza aplikacijskih servisa
Preoblikovanje radi dugovječnosti obično znači stvaranje jasnijih razdjelnica. Kontroler ne bi trebao odlučivati kako se narudžba odobrava; trebao bi pozvati aplikacijski servis poput ApproveOrder. Taj servis koordinira autorizaciju, validaciju, domenska pravila, perzistenciju i nuspojave. Infrastrukturni sloj zatim implementira pristup repozitoriju, objavljivanje u redu čekanja ili vanjske HTTP pozive iza sučelja koja odgovaraju potrebama aplikacije.
Ovo nije argument za razrađene apstrakcije oko svake klase. Ovo je argument za postavljanje promjenjivosti tamo gdje pripada. Pružatelji plaćanja, pristup bazi podataka, posrednici poruka i objekti zahtjeva okvira vjerojatno će se mijenjati neovisno o vašim temeljnim poslovnim pravilima. Njihove pojedinosti zadržite na rubovima.
Dobit je praktična. Domensko se pravilo može testirati bez pokretanja web poslužitelja ili kontejnerizirane baze podataka. Migracija baze podataka može se postaviti bez istodobnog redefiniranja API odgovora. Novi asinkroni tijek rada može se uvesti bez prisiljavanja klijenata da zahtjeve onečišćuju pojedinostima implementacije.
Dizajnirajte putanje neuspjeha jednako pažljivo kao i putanje uspjeha
Klijenti svoje ponašanje grade oko pogrešaka jednako kao i oko uspješnih odgovora. Predvidljiv API razlikuje neispravan unos, nedostajuće resurse, zabranjene radnje, sukobe i privremene neuspjehe. Ne bi trebao propuštati stogove poziva, SQL poruke ili formate iznimki okvira kao slučajne ugovore.
Koristite dosljedan oblik pogreške i stabilne strojno čitljive kodove. Klijent može prikazati prijateljsku poruku za inventory_unavailable, dok razvojni programer može pregledati identifikator zahtjeva u zapisnicima. Tekst namijenjen ljudima može se razvijati; kod treba ostati smislen i dokumentiran.
Za operacije koje se mogu ponoviti, razmislite o dvostrukim zahtjevima. Mrežno vremensko ograničenje ne dokazuje da poslužitelj nije dovršio posao. Za važne operacije stvaranja ili operacije slične plaćanju, ključ idempotentnosti može omogućiti poslužitelju da prepozna ponovljeni pokušaj i vrati izvorni ishod umjesto stvaranja dvostrukog zapisa. To ponašanje mora biti podržano trajnom pohranom i eksplicitnim životnim ciklusom ključeva; predmemorija lokalna procesu nije dovoljna u skaliranoj implementaciji.
Preoblikujte i put isporuke
Dizajn API-ja pouzdan je samo onoliko koliko je pouzdan način na koji stiže u produkciju. Migracije baze podataka trebale bi biti kompatibilne i s trenutačno postavljenom aplikacijom i s verzijom koja se uvodi. Sigurniji je obrazac proširi, migriraj, suzi: dodajte nullable stupac ili novu tablicu, postavite kod koji zapisuje novi prikaz, pažljivo popunite postojeće podatke, prebacite čitanja i tek kasnije uklonite zastarjele strukture.
Docker može lokalna i implementacijska okruženja učiniti dosljednijima, ali spremnik ne uklanja operativne razlike. Konfiguraciju držite u varijablama okruženja ili upravljanoj konfiguraciji, pokrećite migracije sheme kao namjeran korak implementacije i neka zdravstvene provjere odražavaju može li servis sigurno primati promet. Ne pretpostavljajte da ponovno pokretanje spremnika čini migraciju podataka sigurnom ili povratnom.
Rad na performansama slijedi isto načelo: mjerite na granici. Pratite latenciju krajnje točke, stopu pogrešaka, broj upita u bazu podataka, kašnjenje reda čekanja i veličinu tereta. Elegantno interno preoblikovanje koje jedan upit pretvara u pedeset i dalje je regresija. Koristite paginaciju za neograničene kolekcije, odaberite samo potrebne podatke i spriječite slučajne petlje lijenog učitavanja prije nego što postanu problemi opterećenja u produkciji.
Gradite za razgovore koje će vaš budući tim voditi
Najbolje dugoročno preoblikovanje API-ja pojeftinjuje buduće odluke. Inženjerima daje stabilan ugovor o kojem mogu raspravljati, testove koji opisuju ponašanje, granice koje zadržavaju promjene i korake implementacije koji poštuju stvarne podatke. Također čini kompromise vidljivima: kod kompatibilnosti je namjeran, verzioniranje ima cijenu, a operativna sigurnost dio je isporuke značajki.
Izdanje sljedećeg tromjesečja je važno. Ali API stječe povjerenje tijekom godina, kroz male promjene koje ostaju razumljive i sigurne. Preoblikujte prema tom povjerenju: zaštitite ugovor, izolirajte implementaciju, promatrajte stvarnu upotrebu i neka svaka promjena ostavi sustav lakšim za razvoj nego što ste ga zatekli.