API-first: integracija je odluka u arhitekturi, ne posao na kraju
Integracija se retko planira — pojavi se kao zahtev pri kraju projekta, kada je najvažnija odluka već doneta ćutke. API-first je suprotan redosled: ugovor postoji pre implementacije.
Ukratko
- API-first znači da ugovor o komunikaciji postoji pre implementacije, a korisnički interfejs je samo jedan od klijenata tog ugovora.
- API dodat na kraju preslikava interne tabele umesto poslovnih pojmova, pa svaka izmena baze puca kod klijenta.
- Svaka integracija koja dovoljno dugo radi jednom isporuči istu poruku dvaput — idempotentnost nije luksuz nego uslov ispravnosti.
- Izbor između pollinga, webhook-a i toka događaja je odluka o ceni i trenutnosti, ne stvar ukusa.
- Point-to-point integracije rastu kvadratno s brojem sistema; čvorište i jasan ugovor su jedini način da se to zaustavi.
Integracija se retko planira. Skoro uvek se pojavi kao zahtev pri kraju projekta — kada softver već radi, kada su ekrani gotovi, i kada neko konačno pita „a kako ovo da povežemo sa ostatkom firme“. Tada je kasno. Ne zato što je tehnički nemoguće, nego zato što je najvažnija odluka već doneta ćutke: sistem je izgrađen kao da mu je jedini korisnik čovek koji gleda u ekran.
API-first je suprotan redosled. Ugovor o tome kako se sa sistemom razgovara postoji pre nego što je napisan ijedan red implementacije, a korisnički interfejs je samo jedan od klijenata tog ugovora — ravnopravan s drugim sistemom, s mobilnom aplikacijom, s noćnim poslom koji sinhronizuje podatke. To nije stil rada tima za backend, nego odluka u arhitekturi koja određuje koliko će vas svaka buduća integracija koštati.
Šta „API-first“ zapravo znači
Razlika nije u tome da li sistem ima API. Danas ga ima gotovo sve. Razlika je u tome šta je bilo prvo.
Kada je interfejs prvi, API se dodaje kao omotač oko onoga što je ekran već radio. Takav API govori jezikom baze — vraća redove tabela, traži interne identifikatore, otkriva kako je podatak fizički smešten. Kada je ugovor prvi, API govori jezikom posla: „kreiraj porudžbinu“, „rezerviši zalihu“, „izdaj otpremnicu“. Prvi opisuje kako sistem radi iznutra; drugi opisuje šta sistem znači spolja.
Zvuči kao nijansa dok ne dođe prvi klijent. Onog trenutka kada drugi sistem počne da zove vaš API, vi ste objavili obećanje. To obećanje — ugovor — određuje šta klijent sme da očekuje i šta vi smete da promenite a da ga ne slomite. Ako je ugovor slučajni odraz vaše šeme baze, svaka izmena šeme je i izmena ugovora, i svaki refaktor puca kod nekog drugog.
Zašto „dodaćemo API kasnije“ uvek daje pogrešan API
„Dodaćemo API kasnije“ zvuči kao odlaganje troška. U stvari je to odluka da API bude preslikavanje internih tabela umesto poslovnih pojmova, jer u trenutku dodavanja jedino što postoji jesu tabele. Klijent onda mora da zna vašu šemu da bi uradio bilo šta, a vi ne smete da je promenite jer je klijent zavisan od nje. Napravili ste zavisnost u pogrešnom smeru.
Contract-first pristup okreće to naopako. Prvo se opiše ugovor — putanje, oblici poruka, značenja polja — kao dokument koji i čovek i mašina mogu da pročitaju. Taj opis je predmet dogovora pre implementacije. Tim koji gradi klijent i tim koji gradi server rade paralelno naspram istog papira, umesto da jedan čeka drugog. Kada implementacija stigne, ona popunjava ugovor koji je već proveren, a ne obrnuto.
Verzionisanje je deo istog razmišljanja. Ugovor sme da se menja, ali ne sme da se slomi ispod klijenta koji već radi. Pravila su jednostavna i vredi ih napisati:
- Dodavanje je bezbedno. Novo opciono polje ili nova putanja ne diraju postojeće klijente.
- Uklanjanje i preimenovanje nije. Svako polje koje neko čita jeste obećanje; kad ga uklonite, prekršili ste ga.
- Značenje se ne menja u tišini. Ako „cena“ odjednom uključuje PDV a ranije nije, to je prelomna izmena iako se oblik poruke nije promenio.
- Prelomna izmena dobija novu verziju. Stara verzija živi dok se poslednji klijent ne preseli, ne dok vama ne dosadi da je održavate.
Idempotentnost, ponovni pokušaji i poruka koja stigne dvaput
Svaka integracija koja dovoljno dugo radi jednom isporuči istu poruku dvaput. To nije greška koju treba ispraviti, nego osobina mreže koju treba prihvatiti. Klijent pošalje zahtev, server ga uredno obradi, ali odgovor se izgubi na putu nazad. Klijent ne zna da je uspelo, pa pokušava ponovo. Bez zaštite, upravo ste kreirali dve porudžbine, dva računa, dve isporuke iste robe.
Idempotentnost je svojstvo da isti zahtev, ponovljen, ima isti efekat kao da je poslat jednom. Postiže se ključem koji klijent dodeli svakom pokušaju: server pamti šta je uradio za taj ključ i pri ponovljenom zahtevu vraća isti odgovor umesto da posao izvrši drugi put. Bez toga, svaki mehanizam ponovnih pokušaja — a on je neophodan, jer mreže otkazuju — postaje mašina za dupliranje.
Pravilo koje sprečava duple račune: svaki zahtev koji nešto menja nosi jedinstven ključ koji klijent generiše. Server pamti ishod za taj ključ i pri ponavljanju vraća isti odgovor, a ne novi posao. Ponovni pokušaj tada postaje bezopasan, a ne opasan.
Webhook, polling ili tok događaja
Kako klijent saznaje da se nešto promenilo? Tri odgovora su u opticaju, i nijedan nije univerzalno tačan — svaki rešava drugu vrstu problema i naplaćuje drugu cenu.
| Pristup | Kako radi | Kada je pravi | Cena |
|---|---|---|---|
| Polling | Klijent u razmacima pita „ima li novog“ | Promene su retke, klijent jednostavan, trenutnost nije bitna | Prazni upiti troše resurse; kašnjenje je jednako razmaku pitanja |
| Webhook | Server pozove klijenta čim se nešto desi | Događaji su retki ali hitni, a klijent može da primi poziv | Klijent mora biti dostupan; isporuka se mora ponavljati i potvrđivati |
| Tok događaja | Klijent čita neprekidan tok svojim tempom | Mnogo događaja, više potrošača, potrebna istorija | Traži infrastrukturu i disciplinu u redosledu i ponavljanju |
Polling je najlakši za napraviti i najskuplji da bude trenutan — što češće pitate, to više praznih odgovora dobijate. Webhook prebacuje trošak na trenutak događaja, ali uvodi novu obavezu: šta ako klijent nije dostupan kada pozovete. Tok događaja je najmoćniji kada više sistema mora da čuje istu promenu i kada je bitan redosled, ali traži najviše discipline. Greška je birati po modi, a ne po prirodi saobraćaja.
Semantika grešaka i ograničenja brzine
Kod za grešku nije dekoracija — to je poruka pozivaocu šta da uradi sledeće. Klijent koji ne razume razliku između „tvoj zahtev je pogrešan“ i „ja sam trenutno pao“ ponaša se pogrešno u oba slučaja: ili odustaje kada je trebalo da pokuša ponovo, ili uporno ponavlja nešto što nikad neće uspeti.
- 400 — zahtev je neispravan; ponavljanje bez izmene daje isti rezultat, nema svrhe pokušavati ponovo.
- 409 — sukob s trenutnim stanjem; resurs već postoji ili je promenjen otkad ste ga poslednji put videli. Poziva na proveru stanja, ne na slepo ponavljanje.
- 429 — previše zahteva; usporite i pokušajte kasnije, po mogućstvu s razmakom koji raste.
- 5xx — server je zakazao; ponavljanje ima smisla, ali samo uz idempotentni ključ da se posao ne udvostruči.
Ograničenje brzine i backpressure su druga strana istog problema. Sistem koji nema granicu prima onoliko saobraćaja koliko mu klijent pošalje, sve dok se ne sruši pod teretom. Jasno ograničenje s porukom 429 nije prepreka nego poklon: govori klijentu tačno koliko sme, umesto da ga pusti da otkrije granicu tako što obori oba sistema.
Osmatranje: ne možete da debagujete ono što ne vidite
Integracija koja se ne vidi ne može da se popravi. Kada dve firme spore ko je kriv što porudžbina nije stigla, jedini argument koji nešto vredi jeste zapis: koji zahtev je poslat, kada, s kojim sadržajem, kakav je odgovor stigao. Bez toga imate dve strane koje se zaklinju da su u pravu i nijedan način da se utvrdi ko jeste.
Praktično, svaki poziv treba da nosi identifikator koji se provlači kroz oba sistema, tako da se jedna transakcija može ispratiti od početka do kraja. Kada agent u NG Commerce prosledi porudžbinu ka skladištu, mora se videti gde je stala ako nije stigla. Bez osmatranja, svaka integracija je crna kutija koja radi dok radi, a ćuti kada stane.
Point-to-point ili čvorište
Prva integracija je laka. Povežete dva sistema direktno i sve radi. Druga je isto laka. Problem počinje oko petog sistema, kada shvatite da svaki novi mora da se poveže sa svakim postojećim. Deset sistema povezanih svaki sa svakim daje četrdeset pet veza, i svaka od njih je zaseban ugovor koji neko mora da održava. Broj veza raste kvadratno, a tim linearno — jednačina koja se uvek završi zastojem.
Čvorište prekida taj rast. Umesto da svaki sistem poznaje svaki drugi, svi govore sa jednom tačkom koja poznaje ugovore. Kada NG Operations planira proizvodnju, a KickOff WMS vodi skladište, oni ne moraju da znaju jedan za drugog — dovoljno je da svaki zna ugovor prema čvorištu. Novi sistem se tada priključuje jednom vezom, a ne sa svima odjednom.
Poslednji deo koji svi preskoče jeste dokumentacija. Ugovor koji nije opisan tako da ga tuđi programer razume bez sastanka nije proizvod, nego usmena tradicija. Dobar API dokument nije formalnost posle isporuke — on je deo proizvoda kao i sam kod. Ako razmišljate o povezivanju sistema koji već koristite, pogledajte kako pristupamo integracijama ili nas kontaktirajte s konkretnim slučajem — odluka o arhitekturi se donosi na početku, ne na kraju.
Razgovarajmo o vašem slučaju
Opišite nam proces koji vas najviše košta. Na kratkom razgovoru kažemo da li se isplati automatizovati i šta bi to konkretno značilo.
Česta pitanja
Šta znači API-first pristup?
API-first znači da se ugovor o komunikaciji sa sistemom definiše pre implementacije, a korisnički interfejs se tretira kao samo jedan od klijenata tog ugovora. Cilj je da API govori jezikom posla — porudžbina, zaliha, račun — a ne jezikom interne baze. Time se izbegava da svaka izmena baze slomi klijente koji zavise od nje.
Zašto je loše dodati API na kraju projekta?
Kada se API dodaje na kraju, jedino što postoji jesu interne tabele, pa API postaje njihov odraz umesto opisa poslovnih pojmova. Klijenti tada moraju da poznaju vašu šemu baze da bi radili, a vi je ne smete menjati bez lomljenja. Zavisnost nastaje u pogrešnom smeru i skupo se plaća pri svakom refaktoru.
Šta je idempotentnost i zašto je bitna kod integracija?
Idempotentnost znači da isti zahtev, poslat više puta, ima isti efekat kao da je poslat jednom. Bitna je jer svaka integracija pre ili kasnije isporuči istu poruku dvaput — obično zato što se odgovor izgubi i klijent pokuša ponovo. Bez idempotentnog ključa, ponovni pokušaj kreira dupli račun ili duplu isporuku.
Kada koristiti webhook, a kada polling?
Polling je dobar kada su promene retke i trenutnost nije bitna, jer je jednostavan ali troši resurse na prazne upite. Webhook je pravi kada su događaji hitni i klijent može da primi poziv, ali uvodi obavezu ponovne isporuke ako klijent nije dostupan. Tok događaja se koristi kada više sistema mora da čuje istu promenu i bitan je redosled.
Zašto point-to-point integracije postaju problem?
Kod point-to-point pristupa svaki novi sistem mora da se poveže sa svakim postojećim, pa broj veza raste kvadratno s brojem sistema. Deset sistema povezanih svaki sa svakim daje četrdeset pet zasebnih ugovora za održavanje. Čvorište zaustavlja taj rast tako što svaki sistem govori sa jednom tačkom, a novi se priključuje jednom vezom.
Nastavite dalje
- Integracije9 min čitanja
ERP integracija bez dvostrukog unosa: šta se zaista sinhronizuje
Dvostruki unos je simptom, ne bolest. Bolest je što dva sistema oba veruju da su vlasnik istog podatka. Rešenje počinje odlukom ko je vlasnik čega — i time da se to zapiše.
Pročitajte - Arhitektura10 min čitanja
Modernizacija legacy sistema bez zaustavljanja posla
Potpuno prepisivanje pada jer stari sistem ne stoji dok pišete novi. Modernizacija koja uspeva ide u malim, reverzibilnim koracima — jedan deo, iza fasade, dok posao ne staje.
Pročitajte - AI i automatizacija9 min čitanja
Automatizacija poslovnih procesa: od skripti do AI agenata
Automatizacija nije jedna tehnologija nego lestvica od pet prečaga. Vodič kroz to u čemu je svaka dobra, kako pada i zašto se proces prvo popravi pa automatizuje.
Pročitajte