Arhitektura sustava: Zašto vaš API pristupnik treba mozak
API pristupnik počinje kao praktična ulazna točka: jedno ime hosta, jedna provjera autentikacije, nekoliko ruta. Zatim sustav raste. Usluge se umnožavaju, klijenti razvijaju različite potrebe, a proxy koji izgleda bezazleno postaje mjesto na kojem se tiho gomilaju poslovno ključne odluke.
Zato API pristupnik treba mozak. Ne golemu aplikaciju koja zna sve o svakoj usluzi, nego promišljeni upravljački sloj koji može donositi dosljedne odluke o prometu, identitetu, otpornosti i vidljivosti. Bez tog sloja složenost ne nestaje. Ona se prelijeva u svakog klijenta i svaku pozadinsku uslugu.
Pristupnik je više od obrnutog proxyja
Obrnuti proxy prosljeđuje zahtjeve. Promišljeni pristupnik tumači ih u kontekstu sustava.
Na primjer, klijentski zahtjev za nadzornu ploču računa može zahtijevati autentificiranog korisnika, ograničavanje brzine ovisno o zakupcu, pozive prema nekoliko internih usluga, krajnji rok i odgovor oblikovan za mobilnu aplikaciju. Ako svaki klijent mora razumjeti te pojedinosti, javni API postaje čvrsto povezan s internom arhitekturom. Preimenovanje usluge, podjela baze podataka ili promjena internog protokola postaju skupa migracija klijenata.
Pristupnik bi trebao pružati stabilan rub uz mogućnost razvoja unutarnjih dijelova. Njegov „mozak” skup je pravila i odluka o orkestraciji koje pripadaju tom rubu.
- Autentificirajte zahtjeve i uspostavite pouzdan kontekst identiteta.
- Autorizirajte široki pristup na razini API-ja prije nego što rad uđe u sustav.
- Usmjeravajte zahtjeve prema odgovarajućim pozadinskim mogućnostima.
- Primjenjujte ograničenja brzine, kvote, ograničenja veličine zahtjeva i vremenska ograničenja.
- Po potrebi prevodite javne ugovore u interne protokole.
- Agregirajte odgovore samo kada to klijentu smisleno pojednostavljuje rad.
- Stvarajte dosljedne zapisnike, tragove, metrike i odgovore na pogreške.
Razlika je važna jer pristupnici mogu postati i opasni. Pristupnik koji sadržava ključna pravila domene pretvara se u distribuirani monolit s osobito nezgodnim putem implementacije. Trebao bi koordinirati i provoditi međusektorska pravila, a ne postati vlasnik narudžbi, računa, zaliha ili stanja kupaca.
Zadržite vlasništvo nad domenom iza granice
Korisno je pravilo jednostavno: ako pravilo određuje istinu o poslovnom entitetu, usluga koja posjeduje taj entitet trebala bi ga provoditi. Usluga za narudžbe odlučuje može li se narudžba otkazati. Usluga za naplatu odlučuje može li se plaćanje refundirati. Pristupnik može odbiti pozivatelja kojem nedostaje potreban opseg, ali ne bi trebao duplicirati pravila za refundaciju.
Takvo razdvajanje izbjegava suptilan način kvara. Pretpostavimo da pristupnik provjerava smije li korisnik ažurirati projekt, dok usluga za projekte također ima logiku članstva u projektu. S vremenom se te provjere razilaze. Jedan put odobrava pristup, drugi ga odbija, a sigurnosne pogreške postaju teško dijagnosticirati jer obje komponente zasebno djeluju razumno.
Provjeru identiteta i grube kontrole pristupa postavite na pristupnik. Prosljeđujte provjerene tvrdnje o identitetu nizvodno u obliku kojem usluge mogu vjerovati, koristeći zaštićeno interno umrežavanje i jasnu granicu povjerenja. Dopustite uslugama da obavljaju autorizaciju na razini resursa ondje gdje imaju potrebne podatke i kontekst domene.
Usmjeravanje učinite pravilom, a ne spletom uvjetovanja
Pravila usmjeravanja zaslužuju istu pažnju kao i aplikacijski kod. Trebala bi biti pregledna, testabilna i izričita u pogledu ponašanja pri podudaranju. Definicija rute treba više od putanje i odredišta: trebala bi opisivati dopuštene metode, zahtjeve autentikacije, vremenske proračune, ponašanje pri ponovnim pokušajima te postupanje sa zaglavljima i tijelima zahtjeva.
Razmotrite PHP rubnu uslugu koja delegira internoj usluzi za profile. Pristupnik bi nadređenoj usluzi trebao zadati ograničeni krajnji rok i sačuvati ID korelacije. Ne bi trebao čekati neograničeno samo zato što je klijent bio spreman čekati.
<?php
$correlationId = $_SERVER['HTTP_X_REQUEST_ID'] ?? bin2hex(random_bytes(16));
$context = stream_context_create([
'http' => [
'method' => 'GET',
'header' => [
"X-Request-ID: {$correlationId}",
"X-User-ID: {$verifiedUserId}",
],
'timeout' => 2,
'ignore_errors' => true,
],
]);
$response = @file_get_contents(
"http://profile-service.internal/v1/profiles/{$verifiedUserId}",
false,
$context
);
if ($response === false) {
http_response_code(503);
header('Content-Type: application/json');
echo json_encode([
'error' => 'profile_service_unavailable',
'request_id' => $correlationId,
]);
exit;
}
header('Content-Type: application/json');
header("X-Request-ID: {$correlationId}");
echo $response;
Ovo je namjerno skromno. Produkcijski kod također zahtijeva pažljivu izgradnju URL-ova, obradu statusa odgovora, objedinjavanje veza gdje to izvođačko okruženje podržava i pouzdanu implementaciju autentikacije. Arhitektonska pouka je krajnji rok: svaki mrežni skok troši dio ograničenog proračuna zahtjeva.
Agregacija treba opravdati svoju složenost
Pristupnik može smanjiti broj kružnih putovanja klijenta sastavljanjem odgovora iz više usluga. To može biti vrijedno za nadzorne ploče, stranice proizvoda i mobilne klijente koji rade na promjenjivim mrežama. No agregacija također povećava povezanost i proširuje područje utjecaja kvara ovisnosti.
Prije dodavanja složene krajnje točke zapitajte se treba li klijentu doista jedinstven prikaz ili samo želi manje zahtjeva. Ako je riječ o potonjem, HTTP/2, predmemoriranje ili namjenski backend-for-frontend mogu biti bolji odgovor. Ako je složeni odgovor opravdan, izričito odlučite što se događa kada jedna ovisnost zakaže.
- Ne uspijevajte cijeli odgovor kada je svaka komponenta nužna.
- Vratite djelomične podatke samo kada ugovor jasno označava odsutne odjeljke.
- Koristite predmemorirane ili zastarjele, ali prihvatljive podatke samo ondje gdje točnost to dopušta.
- Postavite zasebne vremenske proračune za svaki nizvodni poziv; ne dopustite da jedna spora ovisnost potroši cijeli zahtjev.
Paralelni pozivi mogu smanjiti latenciju, ali samo kada pristupnik ima kontrole konkurentnosti. Neograničeno grananje pretvara zauzet pristupnik u umnoživač nizvodnog opterećenja. Spora baza podataka tada može pokrenuti više veza koje čekaju, više ponovnih pokušaja i naposljetku širi prekid rada.
Ponovni pokušaji značajka su pouzdanosti samo kada su ograničeni
Ponovni pokušaji često izgledaju kao otpornost, a ponašaju se kao pojačavanje. Ponovni pokušaj neuspjelog čitanja može biti razuman ako je operacija idempotentna, kvar je vjerojatno prolazan i pokušaj se uklapa u krajnji rok. Ponovni pokušaj stvaranja plaćanja bez ključa idempotentnosti može stvoriti dvostruke naplate.
Na pristupniku bi pravila za ponovne pokušaje trebala biti uska: malen broj pokušaja, odgoda s varijacijom i jasna pravila za prihvatljive pogreške. Klijent također može pokušati ponovno, stoga koordinirajte vlasništvo nad ponovnim pokušajima umjesto da dopustite svakom sloju ponavljanje istog zahtjeva. Prekidanje krugova i odbacivanje opterećenja jednako su važni. Ponekad je najzdraviji odgovor brz, razumljiv neuspjeh koji štiti ostatak sustava.
Promatranje je dio posla pristupnika
Pristupnik vidi put zahtjeva na način na koji pojedinačne usluge ne mogu. Trebao bi generirati ili prihvatiti provjereni ID zahtjeva, proslijediti kontekst praćenja, zabilježiti rutu i ishod nadređene usluge te mjeriti latenciju po ovisnosti. Zapisnici bi trebali izbjegavati tajne, autorizacijska zaglavlja, sirove vjerodajnice i nepotrebne osobne podatke.
Korisno operativno pitanje nije samo „Je li pristupnik vratio 500?” Nego: „Koja ruta nije uspjela, koji je poziv prema nadređenoj usluzi potrošio proračun, za koju verziju implementacije i koliko je zahtjeva bilo pogođeno?” Dobra telemetrija pristupnika pretvara incident iz nagađanja u ograničenu istragu.
Dajte rubu mozak, a ne drugi poslovni sustav
Najbolji API pristupnici su disciplinirani. Usklađuju zajednička pravila, štite usluge od nesigurnog prometa i klijentima predstavljaju stabilne ugovore. Ne gomilaju znanje o domeni niti skrivaju svaku arhitektonsku slabost iza još jedne rute.
Zamislite pristupnik kao kontrolora zračnog prometa sustava. Trebaju mu svijest, pravila, ograničenja i jasni signali. Ali ne bi trebao upravljati zrakoplovima. Kada ta granica ostane jasna, pristupnik postaje multiplikator učinka za performanse, održivost i sigurnije promjene.