Hvordan fremtidssikrer vi programvare mot endringer i norske offentlige API-er?
Versjoner kontrakten du er avhengig av, og legg den ustabile delen bak et lag som absorberer skjema- og endepunktsendringer. Konkret: les fra et grensesnitt der felter bare legges til, slik at et eksisterende felt aldri endrer betydning eller type og aldri forsvinner uten et hovedversjonsbytte; lagre regel- og skjemaversjonene sammen med alt du mellomlagrer; og overse felter du ikke kjenner igjen framfor å avvise dem. Registrene kommer til å fortsette å endre seg. Poenget er at endringene deres stopper ved en grense du styrer.
Hva er det som faktisk ryker når et offentlig API endrer seg?
Tolkningen, nesten alltid. Forbindelsesfeil er høylytte og fanges opp på minutter; et felt som får nytt navn fra en utgivelse til den neste er stille. Forespørselen din går gjennom, deserialiseringen gir et objekt med en null der det før var en verdi, og noe tre lag nedstrøms viser en tom streng eller hopper over en regel. Den første som legger merke til det er en kunde, og avstanden mellom endringen og meldingen er så lang tid det tar før noen ser nøye etter.
Variantene er forutsigbare når du først har sett dem. Et felt endrer type, så et tall kommer som en streng. Et enkeltobjekt blir en liste fordi kilden oppdaget et tilfelle med to av dem. En enum får en verdi og din uttømmende switch faller gjennom til en standardgren som ble skrevet som en formalitet. En nøstet struktur får ett nivå til. Ingenting av dette er eksotisk, og alt er til å leve med hvis koblingen ligger ett sted.
Den andre kategorien er at endepunkter flytter seg framfor at felter gjør det, og den er sjeldnere, men større. Avviklingen av Altinn 2 i juni 2026 er det nære eksempelet: ikke et navnebytte på et felt, men en hel plattform som sluttet å svare. En applikasjon som snakker med et normaliserende lag opplevde det som noen andres migrering. En applikasjon med endepunktsteksten spredt gjennom kodebasen opplevde det som et prosjekt.
Hvordan beskytter versjonering applikasjonskoden?
Gjennom én regel som er sterkere enn den høres ut: svarkontrakten er tilføyende. Et eksisterende felt kan ikke endre betydning, kan ikke endre type, og kan ikke fjernes uten et hovedversjonsbytte. Nye felter kan legges til når som helst. Så en klient skrevet mot dagens svar fortsetter å virke etter hvert som API-et vokser, og det eneste den må gjøre til gjengjeld er å tåle felter den ikke kjenner igjen i stedet for å avvise dem.
De maskinvendte flatene bærer den garantien uttrykkelig. Hver av dem eksponerer en schema_version, og en bruddendring krever at den flyttes, så en klient kan asserte på versjonen framfor å oppdage en endring ved å feile. Hver svarkonvolutt bærer også regelversjonen den ble evaluert under. Lagre begge sammen med alt du mellomlagrer: et mellomlagret svar med versjonene sine kan utledes på nytt, og ett uten dem er et tall uten opphav.
På din egen side: hold trådformatet ute av domenemodellen din. Tolk inn i dine egne typer ved én grense, og la resten av applikasjonen avhenge av dem. Da er en endring oppstrøms en diff i én fil framfor et søk gjennom kodebasen, og du kan teste koblingen isolert uten å sette opp hele stabelen.
Hvordan får jeg vite om en endring før den ryker i produksjon?
Følg endringsarkivet i stedet for å sammenligne oppføringer selv. GET /api/v1/changesreturnerer oppdagede endringer på tvers av register- og policykilder, filtrerbart på kilde, enhetstype, enhet, endringstype og dato, og hver rad bærer feltstien som flyttet seg sammen med verdiene før og etter. Det gjør «noe med dette selskapet er annerledes» om til en peker på nøyaktig hva, og det er forskjellen på en ny evaluering og en etterforskning.
Passer polling dårlig for deg, leverer webhook-abonnementer de samme endringene over signert HTTPS på Professional-nivået, med gjentakelser og en HMAC-signatur du verifiserer ved mottak. Uansett er mønsteret det samme: reager på en navngitt endring framfor å evaluere hele kundemassen på nytt etter en timer fordi du ikke kan se hva som flyttet seg.
For driftstilstand framfor dataendringer er det nøkkelløse funksjonsendepunktet den autoritative maskinlesbare kilden: det returnerer en status på live, gated eller dry-run per funksjon. Statussiden for funksjonalitet er den menneskelesbare ekvivalenten og sier åpent at den kan henge etter API-et, så er de to uenige, tro på endepunktet.
Gjør det første kallet
Det første kallet trenger ingen nøkkel og sier hva som er live akkurat nå. Det andre krever scopet read:changes og sier hva som har flyttet seg siden en dato du velger.
# Nøkkelløst: den autoritative maskinlesbare funksjonstilstanden.
curl -s https://www.apier.no/api/v1/capabilities// Hva som flyttet seg, og hvor. Krever scopet read:changes.
const url = new URL("https://www.apier.no/api/v1/changes");
url.searchParams.set("source", "brreg");
url.searchParams.set("from", "2026-07-01");
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.APIER_API_KEY}` },
});
const { data } = await res.json();
for (const row of data.data) {
// field_path peker på det som faktisk flyttet seg.
console.log(row.detected_at, row.entity_id, row.field_path);
}Ofte stilte spørsmål
- Hva er det som faktisk ryker når et offentlig API endrer seg?
- Som regel tolkningen, ikke forbindelsen. Et felt som får nytt navn eller ny type, et nøstet objekt som blir en liste, en enum som får en verdi switch-setningen din ikke håndterer. Dette feiler stille i utkanten av koden framfor høylytt i forespørselslaget, og derfor blir det gjerne funnet av en kunde framfor av en overvåkning.
- Hvordan beskytter versjonering meg egentlig?
- Ved å gjøre kontrakten tilføyende. Et eksisterende felt kan ikke endre betydning eller type, og kan ikke fjernes, uten et hovedversjonsbytte. Nye felter kan dukke opp når som helst. Den ene regelen gjør at en klient skrevet i dag fortsetter å virke etter hvert som API-et vokser, forutsatt at den overser felter den ikke kjenner igjen framfor å avvise dem.
- Hva bør jeg lagre sammen med et mellomlagret svar?
- Regelversjonen og skjemaversjonen fra svarkonvolutten. Begge ligger på _meta. Med dem er et mellomlagret svar mulig å utlede på nytt, og en versjonsendring er et signal om å evaluere igjen. Uten dem har du en verdi uten opphav, som går bra helt til noen spør hvorfor den avviker fra det API-et sier i dag.
- Hvordan får jeg vite om en endring før produksjon gjør det?
- Poll endringsarkivet framfor å sammenligne hele oppføringer selv. Det returnerer rader filtrerbare på kilde, enhet og dato, og hver rad bærer feltstien som flyttet seg pluss verdiene før og etter. På Professional-nivået kan du abonnere på webhook-leveranser i stedet for å polle.
- Bør jeg skrive mitt eget adapterlag hvis jeg bruker en megler?
- Et tynt et, ja. En megler absorberer endringer fra det offentlige, men applikasjonen din har fortsatt nytte av en grense mellom trådformatet og domenemodellen din. Det holder skadeomfanget av enhver endring, fra enhver leverandør inkludert denne, inne i et lag du kan teste isolert.