Naar de inhoud

Kennisbank · Webdevelopment

Wat is API-ontwikkeling?

16 min leestijd
API-ontwikkeling

Een API is de manier waarop twee systemen met elkaar praten. Application Programming Interface is de volledige naam, en het komt neer op een afgesproken taal waarmee software gegevens uitwisselt.

Als je webshop een bestelling naar je boekhouding stuurt, gaat dat via een API. Als je site een betaling start bij een betaaldienst, ook. API-ontwikkeling is het bouwen en onderhouden van die ingang.

Wat API-ontwikkeling inhoudt

Bepalen welke gegevens er beschikbaar zijn, hoe je ze opvraagt, wat je terugkrijgt en wie erbij mag. Dat is de kern, en het meeste werk zit in de vragen die daaronder liggen.

Een API is een contract met iedereen die hem gebruikt. Dat contract kun je later niet zomaar veranderen, want aan de andere kant zitten systemen die je niet beheert en waarvan je vaak niet weet wie ze onderhoudt. Wie een veld hernoemt omdat de nieuwe naam mooier is, legt ergens anders een koppeling plat.

Daarom is het ontwerp belangrijker dan de code. Twee uur nadenken over de namen van je velden en de opzet van je adressen scheelt jaren gedoe.

Het werk zelf hoort bij back-end ontwikkeling, de kant van een website die de bezoeker niet ziet. Wie ook de schermen bouwt die die gegevens tonen, doet er de front-end bij en werkt daarmee full-stack.

Hoe een verzoek er in het echt uitziet

Een verzoek bestaat uit vier delen: een methode, een adres, een paar kopregels en soms een inhoud.

De methode zegt wat je wilt. GET haalt iets op, POST maakt iets aan, PUT of PATCH wijzigt, DELETE verwijdert. Het adres wijst de gegevens aan, bijvoorbeeld /klanten/482/facturen. De kopregels bevatten je legitimatie en de opmerking dat je JSON terug wilt. De inhoud is wat je meestuurt bij een POST.

Het antwoord bestaat uit een statuscode en meestal JSON. Die statuscode is het eerste waar je naar kijkt bij een storing. 200 betekent gelukt, 201 betekent aangemaakt, 400 betekent dat jouw verzoek niet klopt, 401 dat je niet bent ingelogd, 403 dat je wel ingelogd bent maar hier niet mag komen, 404 dat het niet bestaat, 429 dat je te snel gaat en 500 dat het bij de ander stukloopt.

Die codes vertellen je ook of het zin heeft om het nog eens te proberen. Bij een 500 ligt het aan de ander en is een tweede poging over een paar seconden verstandig. Bij een 400 is je verzoek zelf verkeerd en kun je het duizend keer sturen zonder dat er iets verandert.

REST, GraphQL en webhooks

REST is verreweg het meest gebruikt. Je vraagt gegevens op via een webadres en gebruikt de gewone methodes van het web. Het antwoord komt in JSON. De opzet leunt op de bestaande afspraken van HTTP, waardoor je geen nieuwe techniek nodig hebt om hem te gebruiken.

GraphQL laat de vrager zelf bepalen welke velden hij wil. Handig als je anders drie verzoeken nodig hebt, en ingewikkelder om goed te beveiligen: iemand kan een vraag stellen die je database op zijn knieën krijgt.

Webhooks werken andersom. In plaats van dat jij vraagt, stuurt het andere systeem een bericht zodra er iets gebeurt. Ideaal voor betalingen en bestellingen, want je hoeft niet elke minuut te kijken of er iets nieuws is.

Bij oudere systemen kom je SOAP tegen, met XML in plaats van JSON. In de aangiftekanalen van de Nederlandse overheid is dat nog steeds de norm. Zelf bouw je het niet meer.

Voor de meeste koppelingen tussen bedrijfssystemen is REST met webhooks de praktische combinatie.

De REST API van WordPress

Volgens het officiële REST API handboek van WordPress wisselt de API gegevens uit als JSON en gelden voor niet openbare gegevens dezelfde toegangsbeperkingen als binnen WordPress. De blokeditor gebruikt deze infrastructuur zelf.

Je vindt hem op /wp-json/. Vraag /wp-json/wp/v2/posts op en je krijgt de laatste berichten als JSON terug. Standaard krijg je er tien, met per_page kun je dat ophogen tot maximaal honderd. Wil je alleen de titel en de link, dan beperk je het antwoord met _fields, wat het verschil kan zijn tussen een antwoord van tweehonderd kilobyte en een van vier.

De blokeditor van WordPress praat er zelf mee, dus wie deze ingang helemaal dichtzet kan niets meer bewerken. Dat gebeurt vaker dan je denkt, meestal door een beveiligingsplugin die te ruim staat afgesteld.

Twee dingen wil je wel nakijken. De openbare gebruikersroute kan de weergavenaam en slug tonen van auteurs met gepubliceerde berichten. Volgens de WordPress documentatie voor gebruikers is de echte inlognaam alleen beschikbaar binnen de afgeschermde edit context. Controleer toch of je openbare auteursgegevens passen bij wat je wilt delen. Eigen velden zijn niet automatisch zichtbaar: wie met aangepaste velden werkt moet ze bewust doorzetten, anders staat de helft van de inhoud er niet in. Voor eigen routes gebruik je register_rest_route, waarbij je zelf de rechtencontrole meelevert. Meer over de rest van het beveiligingswerk staat bij het beveiligen van een WordPress-website.

Authenticatie: wie ben jij en wat mag je

Dit zijn twee vragen, en ze worden vaak door elkaar gehaald. Authenticatie stelt vast wie er aanbelt. Autorisatie bepaalt welke deuren opengaan.

Een API-sleutel is de eenvoudigste vorm: een lange reeks tekens die je meestuurt in een kopregel. Prima voor koppelingen tussen twee systemen die je allebei beheert. De sleutel is tegelijk je legitimatie en je wachtwoord, dus wie hem heeft is jou.

Application Passwords zitten sinds WordPress 5.6 uit december 2020 in de kern. Je maakt per koppeling een apart wachtwoord aan, dat je afzonderlijk kunt intrekken zonder dat je je eigen inlog hoeft te wijzigen. WordPress schakelt de functie uit op sites zonder geldig SSL-certificaat, en terecht, want zonder versleuteling gaat dat wachtwoord onbeschermd over de lijn.

OAuth 2.0 gebruik je als een gebruiker jou toegang geeft tot zijn account bij een derde partij. Je stuurt hem naar een inlogscherm van die partij, hij geeft toestemming, jij krijgt een toegangstoken terug. Zo werken de koppelingen met boekhoudpakketten en met Google.

Voor verzoeken uit de browser van een ingelogde gebruiker gebruikt WordPress de gewone cookie plus een tijdelijke code in de kopregel X-WP-Nonce. Zonder die code weigert de API, wat voorkomt dat een andere website namens jou verzoeken doet.

Koppelingen met boekhouding en betalingen

Dit is waar de meeste kleine bedrijven met API's te maken krijgen. Een bestelling die vanzelf een factuur wordt, een betaling die de status van een order bijwerkt.

Bij betaaldiensten loopt het via een omweg die je moet kennen. Bij Mollie stuurt de webhook alleen het nummer van de betaling, niet de status. Jij haalt die status vervolgens zelf op bij de API. Dat lijkt omslachtig en het voorkomt dat iemand een vals bericht stuurt waarin staat dat er betaald is. Wie de status uit het binnenkomende bericht overneemt, heeft een webshop die je met een simpel verzoek kunt leegroven.

Betalen zelf is sinds 14 september 2019 in heel Europa aan sterke klantauthenticatie gebonden, de tweestapsverificatie uit de PSD2-richtlijn. Voor je koppeling betekent dat vooral dat een betaling niet in één keer afgerond wordt: de klant verdwijnt naar zijn bank en komt terug, en je code moet met beide uitkomsten omgaan.

Aan de boekhoudkant is het patroon steeds hetzelfde. Je vraagt via OAuth toegang tot de administratie, je krijgt een toegangstoken dat kort geldig is en een verversingstoken om een nieuw exemplaar op te halen. Bij sommige pakketten is dat verversingstoken maar één keer bruikbaar. Draait je koppeling op twee plekken tegelijk, bijvoorbeeld omdat je hem ook op een testsite hebt staan, dan pakken die twee elkaars token af en valt de koppeling elke paar minuten uit.

De grootste bron van gedoe is de dubbele factuur. Een verzoek loopt vast, je code probeert het opnieuw, en de andere kant had het eerste verzoek allang verwerkt. Dat los je op met een eigen kenmerk per bestelling dat de ontvanger onthoudt, zodat een tweede poging met hetzelfde kenmerk geen tweede factuur oplevert. Wie dat overslaat, komt er meestal achter bij de btw-aangifte.

Voor elektronisch factureren gelden aparte afspraken. Leveranciers van de rijksoverheid moeten sinds 1 januari 2017 e-facturen sturen, meestal via het Peppol-netwerk. De Europese ViDA-afspraken uit 2025 breiden dat uit naar grensoverschrijdende handel vanaf 2030. Nog ver weg, en wel een reden om bij de keuze van een boekhoudpakket naar de koppelingen te kijken.

Snelheidslimieten

Vrijwel elke API begrenst hoeveel verzoeken je mag doen, per minuut of per dag. Ga je eroverheen, dan krijg je statuscode 429 terug, vaak met een kopregel Retry-After die zegt hoeveel seconden je moet wachten.

Veel API's sturen ook mee hoeveel je er nog over hebt, in kopregels die met X-RateLimit beginnen. Lees die uit en log ze. Dan zie je aankomen dat je tegen de grens loopt, in plaats van dat je het ontdekt als de koppeling stilvalt.

Waar het misgaat: een nachtelijke synchronisatie die elke keer alle klanten opnieuw ophaalt. Dat gaat goed bij tweehonderd klanten en niet bij tweeduizend. Vraag alleen op wat sinds de vorige keer gewijzigd is, met een datumfilter of een verwijzing naar de laatste bijwerking.

En bouw het opnieuw proberen fatsoenlijk. Oplopende wachttijden, dus één seconde, dan twee, dan vier, met een willekeurige uitloop erbij. Zonder die uitloop komen alle mislukte pogingen op hetzelfde moment terug en veroorzaken ze precies de piek die je wilde vermijden.

Versiebeheer, en waarom koppelingen ineens stoppen

Een wijziging is brekend of niet. Een veld toevoegen is meestal onschuldig. Een veld hernoemen, weghalen, of van tekst naar getal veranderen breekt alles wat erop rekende.

De gebruikelijke oplossing is het versienummer in het adres, zoals /v1/klanten. Wil je iets brekends doen, dan zet je /v2/ ernaast en laat je de oude een tijd meelopen. Wie dat netjes doet, kondigt het einde aan met de kopregel Sunset, een afspraak uit 2019 die een datum meegeeft waarop een adres verdwijnt.

In de praktijk gaat het hier fout doordat de aankondiging aankomt op een adres dat niemand leest. De koppeling is drie jaar geleden gebouwd door iemand die er niet meer is, de mail gaat naar info, en op de dag dat v1 uitgaat komen er geen bestellingen meer binnen. Zorg dat de ontwikkelmeldingen van je leveranciers bij een mens terechtkomen die er iets mee kan.

Aan jouw kant hoort daar één regel bij: gooi geen fout als er een veld bijkomt dat je niet kent. Anders breekt je koppeling bij elke verbetering die de ander doorvoert.

Beveiliging

Hier gaat het het vaakst mis, en de fouten zijn steeds dezelfde.

Sleutels die uitlekken. Een API-sleutel in de JavaScript van je website is voor iedereen zichtbaar. Sleutels horen op de server, in omgevingsvariabelen, en nooit in je versiebeheer. Een sleutel die ooit in een openbare repository heeft gestaan is gecompromitteerd, ook als je hem er later uithaalde, want de geschiedenis blijft staan.

Wel inloggen, niet controleren. Een systeem controleert wie je bent maar niet of je bij deze specifieke gegevens mag. Verander het nummer in het adres en je ziet de gegevens van iemand anders. Dit is een van de meest voorkomende lekken die er zijn. De enige oplossing is bij elk verzoek opnieuw vaststellen of dit account bij deze gegevens mag.

Invoer niet controleren. Wat er binnenkomt via een API is net zo onbetrouwbaar als wat er uit een formulier komt. Controleer typen, lengtes en toegestane waarden voordat je iets in je database zet.

Te veel teruggeven. Een antwoord dat velden bevat die de vrager niet nodig heeft, is een lek dat wacht op iemand die goed kijkt. Bij een lijst met bestellingen hoeft het volledige klantprofiel er niet in.

Webhooks die je zomaar gelooft. Een binnenkomend bericht kan van iedereen komen. Controleer de handtekening die de afzender meestuurt, weiger berichten met een oude tijdstempel zodat iemand een oud bericht niet kan herhalen, en haal bij twijfel de echte status op bij de bron.

Geen limiet. Zonder begrenzing kan iemand je hele database in stukjes ophalen. Een inlogroute zonder limiet is bovendien een uitnodiging om wachtwoorden te raden.

Wat een goede API kenmerkt

  • Voorspelbaarheid. Dezelfde opzet voor elk onderdeel, dezelfde manier van fouten teruggeven, dezelfde naamgeving.
  • Duidelijke foutmeldingen. Een code alleen is te weinig. Zeg erbij wat er mis is en wat de vrager eraan kan doen.
  • Versies. Zodat je iets kunt veranderen zonder dat je alle bestaande koppelingen breekt.
  • Documentatie met voorbeelden. Dit is het onderdeel dat het vaakst tekortschiet en dat het meeste uitmaakt. Een API zonder fatsoenlijke documentatie is een API die niemand gebruikt.
  • Paginering. Nooit tienduizend records in één antwoord.
  • Een limiet op het aantal verzoeken. Beschermt je server en dwingt netjes gebruik af.

Documentatie en een plek om te proberen

De standaard hiervoor is OpenAPI, een beschrijving van je API in een vast formaat waaruit gereedschap automatisch een leesbare pagina maakt. Het voordeel is dat de beschrijving naast de code leeft en meeverandert.

Daarnaast wil je per route een voorbeeld dat iemand kan plakken en uitvoeren, met het antwoord dat hij dan hoort te krijgen. Een lijst met veldnamen zonder voorbeeld levert vragen op die jij mag beantwoorden.

En geef een testomgeving. Zonder oefenomgeving vindt de eerste echte test plaats bij een klant die betaalt.

Wat er misgaat als je andermans API gebruikt

Lees de documentatie over foutafhandeling voordat je begint. Wat gebeurt er als de andere partij eruit ligt, en wat doe jij dan.

Zorg dat een mislukte poging niet stilletjes verdwijnt. Een koppeling die af en toe faalt zonder melding is erger dan een koppeling die het nooit doet, want dan denkt iedereen dat de administratie klopt.

Let op de kleine dingen die in het echt de meeste tijd kosten. Tijdzones, waarbij je alles in UTC opslaat en pas bij het tonen omrekent. Bedragen, die je in centen als geheel getal doorgeeft en niet als kommagetal, anders krijg je afrondingsverschillen die de boekhouder terugvindt. Datums in het vaste formaat met jaar, maand en dag. En tekens: een klant die Renée heet komt er verkeerd uit als ergens in de keten de codering niet klopt.

Houd tot slot een logboek bij van wat er heen en weer gaat. Als er iets niet klopt bij de klant, is dat het enige waarmee je het kunt terugvinden. Zet er wel een bewaartermijn op en laat sleutels en persoonsgegevens eruit, want ook een logbestand valt onder de privacyregels.

Bewaking en beheer

Een koppeling is geen project dat af is. Er verandert iets aan de andere kant, een certificaat verloopt, een server gaat over op een nieuwe PHP-versie.

Regel daarom twee dingen. Een melding als het aantal fouten boven een grens komt, zodat je het weet voordat je klant belt. En een plek waar mislukte berichten blijven staan zodat je ze opnieuw kunt aanbieden in plaats van ze kwijt te zijn.

Voor kleine koppelingen is dat geen zwaar werk. Een dagelijkse controle die kijkt of er sinds gisteren iets is doorgekomen, vangt het meeste af. Let wel op waar die controle draait: de ingebouwde planner van WordPress start pas als er bezoek op de site is, dus op een rustige site loopt hij achter.

Wanneer je helemaal geen API hoeft te bouwen

Als beide systemen al een koppeling met elkaar hebben. Een bestaande verbinding die door de leverancier wordt onderhouden is bijna altijd de betere keuze, en er zijn er meer dan mensen denken.

Als de hoeveelheid klein is. Twintig bestellingen per maand overtypen kost minder dan een koppeling bouwen en onderhouden. De rekensom die telt is niet de bouwtijd maar de tijd over drie jaar, inclusief het bijwerken als er iets verandert.

Als een koppelplatform het kan. Diensten die twee pakketten aan elkaar knopen zonder programmeerwerk zijn prima voor eenvoudige stromen. Ze worden duur en onhandelbaar zodra er logica bij komt kijken. Daar staat tegenover dat zo'n koppeling morgen draait in plaats van volgende maand.

Veelgestelde vragen over API-ontwikkeling

Wat is een API in gewone taal?

Een vaste ingang waarlangs een ander programma gegevens bij jou kan opvragen of afleveren. Vergelijk het met een balie: er is een loket, er zijn formulieren met vaste vragen, en achter de balie zie je niet hoe het werk gebeurt. Dat laatste is precies de bedoeling, want daardoor kun je je systeem verbouwen zonder dat de ander er last van heeft.

Wat betekent REST?

Representational State Transfer, een manier van werken die de bestaande afspraken van het web gebruikt in plaats van er een eigen laag bovenop te zetten. In de praktijk herken je hem aan adressen die zelfstandige naamwoorden bevatten en aan het gebruik van GET, POST, PUT en DELETE. Het is geen standaard met een keurmerk, dus twee API's die zich REST noemen kunnen behoorlijk verschillen.

Wat is JSON?

Een tekstformaat om gegevens in te versturen, met accolades, veldnamen en waarden. Het is leesbaar voor mensen en eenvoudig te verwerken voor elke programmeertaal. JSON heeft XML in nieuwe koppelingen grotendeels vervangen omdat het korter is.

Heeft mijn WordPress-website al een API?

Ja. Vraag je eigen domein op met /wp-json/ erachter en je ziet een antwoord. Daar staan de routes in die beschikbaar zijn. Wat je erin kunt zien zonder in te loggen is beperkt tot openbare inhoud, maar het is er.

Moet ik de WordPress REST API uitzetten voor de veiligheid?

Nee, en het kan ook niet zonder schade. De blokeditor gebruikt hem, dus na het uitzetten kun je zelf niets meer bewerken. Wat wel verstandig is: de route die gebruikersnamen prijsgeeft afschermen en zorgen dat eigen routes hun rechten controleren.

Wat is een API-sleutel en waar bewaar ik hem?

Een lange reeks tekens waarmee een systeem zich bekendmaakt. Bewaar hem in een omgevingsvariabele op de server of in de instellingen van je site, nooit in de code die je deelt en nooit in het stuk dat de browser krijgt. Wie de sleutel heeft kan alles wat jij mag.

Wat is een webhook?

Een bericht dat een ander systeem naar jou stuurt zodra er iets gebeurt. Jij geeft een adres op je eigen site op, zij doen daar een verzoek naartoe bij elke betaling of bestelling. Het scheelt je het voortdurend navragen en het levert je de plicht op om dat adres te beveiligen.

Wat betekent foutcode 429?

Je doet te veel verzoeken in te korte tijd en de andere kant weigert tijdelijk. Kijk in het antwoord of er een Retry-After staat en wacht dat aantal seconden. Komt het vaak voor, dan zit het probleem in je opzet: je haalt waarschijnlijk elke keer alles op in plaats van alleen wat gewijzigd is.

Wat is het verschil tussen 401 en 403?

Bij 401 klopt je legitimatie niet of ontbreekt hij. Bij 403 weet het systeem wie je bent en mag je hier niet komen. In het eerste geval controleer je je sleutel of je token, in het tweede geval de rechten van het account waar die sleutel bij hoort.

Wat kost een koppeling?

Dat hangt bijna volledig af van de API aan de andere kant. Een goed gedocumenteerde API met een testomgeving is een paar dagen werk, een slecht gedocumenteerde met eigenaardigheden kan het veelvoud kosten. Vraag daarom altijd eerst de documentatie op voordat er een prijs op tafel komt, en reken op onderhoud in de jaren erna.

Wat gebeurt er als de leverancier zijn API verandert?

Bij een nette leverancier krijg je een aankondiging en loopt de oude versie nog een tijd door. Bij de rest merk je het doordat er iets stopt. Zorg dat je meldingen krijgt bij fouten en dat de ontwikkelpost van je leveranciers bij iemand terechtkomt die weet wat hij ermee moet.

Kan ik een koppeling maken zonder programmeur?

Voor eenvoudige stromen wel, met een koppelplatform dat twee pakketten aan elkaar knoopt via kant-en-klare stappen. Zodra er voorwaarden, uitzonderingen of foutafhandeling bij komen kijken, wordt zo'n platform onoverzichtelijk en duur. Dan is zelf bouwen goedkoper en beter te onderhouden.

Is een API veilig voor persoonsgegevens?

Een API is net zo veilig als je hem maakt. Verkeer over HTTPS, per verzoek controleren of dit account bij deze gegevens mag, en alleen de velden teruggeven die nodig zijn. Stuur je gegevens naar een andere partij, dan heb je bovendien een verwerkersovereenkomst nodig en moet je weten waar die partij zijn gegevens opslaat.

Moet ik zelf een API aanbieden?

Alleen als er iemand is die hem gaat gebruiken. Een API bouwen omdat het hoort levert een stuk software op dat onderhoud kost en niets doet. Wel verstandig: zorgen dat je gegevens er doorheen zouden kunnen, zodat je niet vastzit als een klant of een leverancier er ooit om vraagt.

Dit artikel hoort bij Webdevelopment. Daar vind je meer uitleg over hetzelfde onderwerp.

Een vraag over dit onderwerp?

Vertel waar je tegenaan loopt.

Maurits denkt met je mee en geeft je een praktisch antwoord.

reactie dezelfde werkdag
Maurits van Platform Pro

Vertel kort waar je aan denkt

Nu gesloten, ik reageer de volgende werkdag

Maurits leest je bericht en neemt persoonlijk contact met je op.

Dit veld is bedoeld voor validatiedoeleinden en moet niet worden gewijzigd.
Dit veld is verborgen bij het bekijken van het formulier