Skip to content
Udgivet

Driftssikre API-integrationer

En API-integration ser ofte enkel ud i et udviklingsmiljø: send et request, modtag et succesfuldt svar, og gem resultatet. Produktion er mindre ryddelig.

Requests får timeout, efter den modtagende tjeneste allerede har gennemført handlingen. Webhooks ankommer to gange eller i forkert rækkefølge. Adgangstokens udløber. Ét system accepterer en ændring, mens et andet afviser den. En leverandør ændrer et felt, bliver langsommere eller er utilgængelig.

En driftssikker integration er designet omkring de forhold. Det succesfulde request er kun én vej gennem systemet. Det vanskelige arbejde er at gøre fejl synlige, kontrollerede og mulige at rette.

Driftssikker API-integration med webhooks, køer, retries, dubletbeskyttelse, overvågning og alarmer

Definér kontrakten før forbindelsen bygges

To systemer har brug for mere end et endpoint og en API-nøgle. De har brug for en fælles forståelse af data og adfærd.

Dokumentér:

  • Hvilket system der ejer hvert datafelt
  • Hvilke events der opretter, opdaterer eller sletter poster
  • Påkrævede og valgfrie felter
  • Tilladte værdier og formater
  • Hvordan poster matches mellem systemerne
  • Hvad der sker, når data mangler eller er ugyldige
  • Forventede statuskoder og timeouts
  • Rate limits og brugsbegrænsninger
  • Krav til godkendelse og rettigheder
  • Forventninger til versionering og varsling af ændringer

Ejerskab er særligt vigtigt. Hvis en kundes e-mailadresse ændres i både et CRM- og bookingsystem, hvilken værdi vinder så? Uden et tydeligt svar kan en teknisk succesfuld synkronisering stadig overskrive korrekte oplysninger.

Behandl kontrakten som vedligeholdt projektdokumentation. Når et af systemerne ændres, bør integrationen gennemgås i forhold til den.

Antag at timeouts er tvetydige

En timeout betyder ikke altid, at en handling fejlede.

Forestil dig et request om at oprette en ordre. Den modtagende tjeneste opretter ordren, men svaret går tabt, før dit system modtager det. Hvis requestet gentages blindt, kan kunden få to ordrer.

Derfor skal integrationer skelne mellem:

  • Et request, der med sikkerhed fejlede før behandling
  • Et request, der muligvis blev gennemført uden bekræftelse
  • Et request, der blev gennemført succesfuldt
  • Et request, der blev afvist på grund af ugyldigt input

Brug rimelige timeouts for forbindelse og svar, så en langsom leverandør ikke optager applikationsressourcer uden grænse. Efter et tvetydigt resultat bør den eksterne tilstand kontrolleres, eller handlingen gentages med idempotensbeskyttelse, frem for at antage at intet skete.

Gør vigtige handlinger idempotente

En idempotent handling kan gentages uden at skabe et andet resultat efter den første succesfulde udførelse.

Ved oprettelse og betalingslignende handlinger bør der bruges en stabil idempotensnøgle eller ekstern reference, som identificerer forretningshandlingen. Gem referencen sammen med både lokale og eksterne poster. Hvis samme handling modtages igen, returneres eller afstemmes det eksisterende resultat frem for at oprette en dublet.

Gode idempotensnøgler repræsenterer handlingen og ikke det enkelte netværksforsøg. En ny nøgle for hvert retry fjerner beskyttelsen.

Idempotens er også nyttig ved behandling af webhooks. Gem leverandørens event-id, og undgå at behandle samme event to gange. Hold kontrollen og den efterfølgende tilstandsændring i en sikker transaktion, hvor det er muligt, så to workers ikke kan behandle dubletten samtidig.

Kvitter hurtigt for webhooks

Webhook-endpoints bør validere det indgående request, registrere tilstrækkelige oplysninger til sikker behandling og svare hurtigt.

Lad ikke leverandøren vente, mens applikationen sender mails, opdaterer flere systemer, genererer dokumenter eller udfører langsomme beregninger. Læg eventet i en kø eller anden holdbar behandlingsmekanisme, og håndtér derefter forretningsarbejdet separat.

Et nyttigt webhook-flow er:

  1. Modtag requestet over HTTPS.
  2. Kontrollér leverandørens signatur eller godkendelsesmetode.
  3. Validér grundlæggende struktur og nødvendige identifikatorer.
  4. Gem eventet, eller læg det sikkert i kø.
  5. Returnér det forventede succes-svar.
  6. Behandl eventet asynkront.
  7. Registrér resultat og eventuelt opfølgende arbejde.

Returnér en fejl, når eventet ikke kan accepteres sikkert. Hvis succes returneres, før eventet er gemt, kan data gå tabt, fordi leverandøren mener, leveringen er afsluttet.

Forvent dubletter og forkert rækkefølge

Webhook-leverandører gentager ofte levering, og netværksadfærd kan ændre ankomstrækkefølgen.

Antag ikke, at et event ankommer præcis én gang eller i samme rækkefølge, som det skete. Brug event-id’er, tidsstempler, versioner eller kontrol af den aktuelle tilstand til at beslutte, om et event skal ændre lokale data.

Et ældre “ordre afventer”-event bør eksempelvis ikke overskrive en nyere “ordre gennemført”-tilstand, blot fordi det ankommer senere. I nogle integrationer er den sikreste reaktion at hente den aktuelle autoritative post fra leverandøren i stedet for at anvende eventets payload direkte.

Gentag kun når et retry kan hjælpe

Retries er nyttige ved midlertidige fejl som timeout, rate limit eller driftsstop. De er ikke nyttige ved ugyldigt input, manglende rettigheder eller et request, der bryder en forretningsregel.

Klassificér fejl før retry:

  • Midlertidig: netværksfejl, timeouts, rate limits og udvalgte serverfejl
  • Permanent indtil ændring: ugyldige data, godkendelsesfejl, manglende rettigheder og ikke-understøttede handlinger
  • Tvetydig: timeout eller afbrudt svar, efter det eksterne system muligvis har behandlet requestet

Brug eksponentiel backoff, så gentagne forsøg får større mellemrum. Tilføj lidt tilfældighed, så mange fejlede jobs ikke prøver igen samtidig. Begræns antallet af forsøg, registrér den endelige fejl, og flyt uløste jobs til et sted, hvor de sikkert kan undersøges og genafspilles.

Et uendeligt retry-loop er ikke robusthed. Det er et skjult driftsstop, der bruger ressourcer.

Brug køer til at isolere eksterne fejl

Eksterne tjenester bør ikke styre svartiden for uvedkommende brugerrequests.

Køer gør det muligt for applikationen at acceptere lokalt arbejde, behandle integrationer separat, styre samtidighed og gentage midlertidige fejl. De gør det også lettere at sætte behandlingen på pause, når en leverandør er ustabil, uden at tage hele applikationen offline.

Køjobs bør indeholde nok kontekst til at identificere forretningshandlingen, men undgå at kopiere unødvendige følsomme data til payloads. Gør jobs idempotente, fordi en worker kan stoppe, efter den eksterne handling lykkes, men før køen registrerer afslutning.

Overvåg kølængde, behandlingstid, antal retries og fejlede jobs. En kø kan absorbere et kort driftsstop, men en voksende backlog bliver til sidst et brugerproblem.

Hold logs nyttige og sikre

Integrationslogs bør kunne besvare praktiske spørgsmål:

  • Hvilken forretningshandling udløste requestet?
  • Hvilke lokale og eksterne poster var involveret?
  • Hvornår blev det forsøgt?
  • Hvilket endpoint og hvilken handling blev brugt?
  • Hvilken status eller fejlkategori opstod?
  • Blev handlingen forsøgt igen?
  • Hvad skete der ved det sidste forsøg?

Brug en korrelations-id på tværs af requests, køjobs og webhook-behandling, så ét flow kan spores gennem systemet.

Log ikke adgangstokens, hemmeligheder, fulde betalingsoplysninger eller unødvendige persondata. Logs har ofte bredere adgang og længere opbevaring end applikationsdata. Registrér nok til at diagnosticere problemet uden at skabe et nyt sikkerheds- eller privatlivsproblem.

Overvåg resultater og ikke kun oppetid

En integration kan være online og samtidig producere forkerte eller ufuldstændige data.

Nyttig overvågning omfatter:

  • Succes- og fejlrater for requests
  • Svartid
  • Rate-limit-svar
  • Kølængde og ældste ventende job
  • Antal retries og permanente fejl
  • Webhook-levering og behandlingsforsinkelse
  • Udløb af godkendelse
  • Forskelle mellem forventede og faktiske poster
  • Forretningsresultater som manglende bookinger eller usendte bekræftelser

Alarmér på forhold, der kræver handling. En enkelt midlertidig fejl kræver måske ikke en alarm, mens en voksende kø, gentagne godkendelsesfejl eller en manglende eventstrøm gør.

Lav et enkelt driftsbillede, som viser integrationens tilstand uden at kræve læsning af rå logs.

Tilføj afstemning

Selv en velbygget eventbaseret integration kan overse noget. Leverandører har driftsstop, konfigurationsændringer og leveringsfejl. Lokale fejl opstår også.

Afstemning sammenligner systemerne med faste mellemrum og retter forskelle. Den kan eksempelvis kontrollere, at hver betalt ordre findes i økonomisystemet, hver bekræftet booking nåede CRM-systemet, eller hvert importeret produkt fortsat matcher kilden.

Afstemningsprocessen bør skabe en tydelig rapport, automatisk rette sikre forskelle og markere tvetydige tilfælde til gennemgang. Den er det sidste sikkerhedsnet, når realtidsbehandling ikke skaber den forventede tilstand.

Test bevidst fejlsituationer

Integrationstest bør dække mere end et succesfuldt svar.

Test:

  • Timeouts før og efter ekstern behandling
  • Dubleret webhook-levering
  • Events, der ankommer i forkert rækkefølge
  • Ugyldige signaturer og udløbne adgangsoplysninger
  • Rate limiting
  • Midlertidigt driftsstop hos leverandøren
  • Ugyldige og ufuldstændige payloads
  • Afbrudt queue worker
  • Delvis lokal databasefejl
  • Genafspilning af en fejlet handling

Testene afslører, om retries skaber dubletter, om logs indeholder nok information, og om gendannelse kan ske uden manuel redigering i databasen.

Praktisk tjekliste til driftssikkerhed

Før en integration betragtes som klar, bør det bekræftes, at:

  • Dataejerskab og regler for matching er dokumenteret
  • Timeouts og rate limits håndteres
  • Vigtige handlinger er idempotente
  • Webhooks verificeres, gemmes og behandles sikkert
  • Dubletter og forkert rækkefølge forventes
  • Retries er begrænsede og klassificeret efter fejltype
  • Fejlede jobs kan undersøges og genafspilles
  • Logs understøtter sporing uden at afsløre hemmeligheder
  • Overvågning dækker tekniske og forretningsmæssige resultater
  • Afstemning kan finde manglende eller inkonsistente data
  • Fejlscenarier er testet

Driftssikre integrationer fjerner ikke fejl. De gør fejl forudsigelige nok til at blive opdaget, forstået og rettet, uden at kontrollen over det bredere system går tabt.

Flere artikler