REST API bouwen: ontwerp, beveiliging en deployment
Om een REST API te bouwen, maak je een lijst van de resources die je app beheert (gebruikers, bestellingen, boekingen), geef elke resource een URL zoals /orders en /orders/{id}, en gebruik HTTP-methoden voor acties: GET om te lezen, POST om te maken, PATCH om bij te werken en DELETE om te verwijderen. Geef JSON terug met betekenisvolle statuscodes, valideer elke invoer, vereis authenticatie en controles per record op de server, en pagineer lijsten. Documenteer daarna de endpoints en zet de API achter HTTPS.
Deze gids behandelt de ontwerpkeuzes, een uitgewerkte set routes, prompts voor een AI-app-builder en de fouten die beveiligingslekken veroorzaken. Als API's nieuw voor je zijn, begin dan met wat een API is.
Wanneer heb je een REST API nodig?
- Je webfrontend moet gegevens opslaan en laden van een server
- Een mobiele app, partner of automatiseringstool heeft toegang nodig tot je data
- Andere diensten sturen je gebeurtenissen (webhooks)
- Je verdeelt het werk tussen een frontend- en een backendteam
REST is de meest gebruikte stijl, maar niet de enige. REST vs GraphQL legt uit wanneer één flexibel query-endpoint beter past.
Eerst ontwerpen: resources en routes
Schrijf op welke zelfstandige naamwoorden in je app voorkomen en wat mensen ermee doen. Voor een eenvoudige boekingsapp:
| Methode | Route | Wat het doet | Succescode |
|---|---|---|---|
GET | /api/bookings | Lijst van de boekingen van de aanroeper (gepagineerd) | 200 |
POST | /api/bookings | Een boeking maken | 201 |
GET | /api/bookings/{id} | Eén boeking ophalen | 200 |
PATCH | /api/bookings/{id} | Enkele velden wijzigen | 200 |
DELETE | /api/bookings/{id} | Een boeking annuleren | 204 |
GET | /api/health | Health check voor monitoring | 200 |
Deze komen overeen met create, read, update en delete; zie wat CRUD is. Conventies die het waard zijn om te volgen:
- Meervoudige zelfstandige naamwoorden, geen werkwoorden in URL's:
/bookings, niet/getBookings. - Neste maar één niveau wanneer dat het eigendom verduidelijkt:
/bookings/{id}/notes. - Acties die geen CRUD zijn kunnen subresources zijn:
POST /bookings/{id}/cancelis duidelijker dan een magische PATCH. - Consistente naamgeving voor velden, zoals
created_atoveral.
Statuscodes en fouten
Gebruik standaard HTTP-codes zodat clients weten wat er is gebeurd zonder tekst te hoeven ontleden:
| Code | Betekenis | Gebruik wanneer |
|---|---|---|
| 200 | OK | Geslaagde lezing of update |
| 201 | Created | Een POST heeft iets aangemaakt |
| 204 | No Content | Geslaagd, zonder iets terug te geven |
| 400 | Bad Request | Invoer is niet gevalideerd |
| 401 | Unauthorized | Niet ingelogd of ongeldig token |
| 403 | Forbidden | Ingelogd, maar niet toegestaan |
| 404 | Not Found | Bestaat niet, of de aanroeper mag niet weten dat het bestaat |
| 409 | Conflict | Duplicaat, of het tijdslot is al geboekt |
| 429 | Too Many Requests | Limiet van verzoeken bereikt |
| 500 | Server Error | Er ging iets mis aan jouw kant |
Geef fouten terug in één consistente JSON-vorm, bijvoorbeeld {"error": {"code": "slot_taken", "message": "Dat tijdstip is niet meer beschikbaar."}}, en neem nooit stacktraces of databasefouten in antwoorden op.
Opties en afwegingen
| Beslissing | Eenvoudige keuze | Alternatief |
|---|---|---|
| Waar de API leeft | API-routes in je webframework | Een aparte API-service, handig voor meerdere clients of een andere taal |
| Authenticatie | Sessiecookies voor je eigen webapp | Tokens (bearer tokens of API-sleutels) voor mobiele apps en derden |
| Paginering | ?page=2&limit=20 | Cursorgebaseerd (?after=...), stabieler voor grote, wijzigende lijsten |
| Versiebeheer | Geen totdat externe gebruikers er afhankelijk van zijn | /v1/ in het pad zodra anderen erop vertrouwen |
| Documentatie | Een README met een lijst van routes | Een OpenAPI-specificatie, waarmee tools interactieve documentatie en clientcode kunnen maken |
Stap voor stap
- Maak een lijst van resources en routes zoals hierboven, inclusief wie elke route mag aanroepen.
- Modelleer de data in je database met de velden en relaties die je nodig hebt.
- Bouw eerst de leesroutes, daarna create, update en delete.
- Valideer invoer bij elke schrijfactie met een schemabibliotheek: verplichte velden, types, lengtes, toegestane waarden. Weiger onbekende velden.
- Voeg authenticatie toe, daarna autorisatie per record: het opvragen van
/bookings/42moet controleren of boeking 42 bij de aanroeper hoort, niet alleen of iemand is ingelogd. - Pagineer elke lijst en begrens het aantal items per pagina.
- Beperk het aantal verzoeken voor inloggen en dure routes. Zie rate limiting.
- Stel CORS alleen in als browsers op andere domeinen de API moeten aanroepen, en noem die origins expliciet. CORS-fouten oplossen legt de fouten uit die je tegenkomt.
- Schrijf documentatie en tests voor elke route, inclusief de foutgevallen.
- Deploy met geheimen in omgevingsvariabelen, HTTPS, logs en een health check.
Prompts voor je AI-builder
Opzetten:
Maak een REST API voor boekingen met deze routes: GET /api/health, GET /api/bookings (gepagineerd, maximaal 50 per pagina), POST /api/bookings, GET /api/bookings/:id, PATCH /api/bookings/:id, DELETE /api/bookings/:id. Sla data op in onze database. Valideer request-bodies met een schemabibliotheek en weiger onbekende velden. Geef JSON-fouten terug als {"error": {"code", "message"}} met de juiste statuscodes (400, 401, 403, 404, 409). Bewaar geheimen in omgevingsvariabelen.
Beveiliging:
Vereis inloggen op elke boekingsroute. Controleer bij elke lees-, update- en verwijderactie op de server of de boeking bij de huidige gebruiker hoort; geef 404 terug als dat niet zo is. Accepteer nooit gebruikers-ID's of rollen uit de request-body. Beperk POST /api/bookings tot 20 per minuut per gebruiker. Log fouten op de server zonder stacktraces terug te geven.
Documentatie:
Schrijf een OpenAPI-beschrijving van deze routes en een korte README met voorbeeldverzoeken en -antwoorden voor elke route.
Je API testen
Test van buitenaf, omdat aanvallers dat ook doen:
- Elke route werkt met geldige invoer en geeft de gedocumenteerde vorm en code terug
- Ontbrekende of ongeldige velden geven 400 met een duidelijke melding
- Geen token geeft 401 op elke beschermde route
- Gebruiker A die het record van gebruiker B opvraagt via ID krijgt 404 of 403
- Lijsten zijn gepagineerd; een enorme
limitwordt begrensd - Dubbele of conflicterende creates geven 409, niet 500
- Rate limits geven 429
- Foutantwoorden bevatten geen stacktraces, SQL of geheimen
- CORS staat alleen de origins toe die je bedoelt
Veelgemaakte fouten
- Wel controleren op inloggen, maar niet op eigendom. Het meest voorkomende API-lek: elke ingelogde gebruiker kan elk record lezen door het ID te wijzigen.
- De client vertrouwen. Prijzen, rollen en gebruikers-ID's uit de request-body kunnen worden aangepast.
- Volledige databaserijen teruggeven. Wachtwoordhashes en interne velden lekken. Kies zelf wat elk antwoord bevat.
- Onbegrensde lijsten. Eén verzoek voor elk record kan de hele app vertragen.
200 OKmet een foutmelding erin. Clients en monitoring zien niet dat het mislukt is.- CORS die alles toestaat bij een API die cookies gebruikt.
- Geen health check of logs, zodat je over storingen hoort van gebruikers.
Voor een bredere controle vóór de lancering, zie de beveiligingschecklist voor door AI gebouwde apps.
Een REST API bouwen in Mythex
Je kunt Mythex vragen om een API, als onderdeel van je app of als eigen service. Het docs-recept REST API backend bevat een startprompt: noem je framework en routes, vraag om duidelijke JSON-fouten, bewaar geheimen in omgevingsvariabelen en neem een Dockerfile op. Container-backends in Node, Python, C#, Java en andere talen publiceren via een Dockerfile, en Mythex verzorgt de deployment vanuit Publish (API-backends). Een project kan een website en een API-server naast elkaar draaien, en je kunt in de preview tussen beide wisselen. Bewaar sleutels als projectgeheimen, en als de API een database nodig heeft, vraag er dan om in de chat. Voor geplande taken rond je API, zie hoe je achtergrondtaken draait.
Veelgestelde vragen
Wat is een REST API?
Een REST API is een manier waarop programma's met de data van je app werken via HTTP. Elk soort data is een resource met een eigen URL, zoals /orders, en standaardmethoden voeren acties erop uit: GET om te lezen, POST om te maken, PATCH of PUT om te bijwerken en DELETE om te verwijderen. Data wordt meestal als JSON verstuurd.
In welke taal moet ik een REST API bouwen?
Gebruik wat jij of je team kunt onderhouden. Node.js met Express of Fastify, Python met FastAPI, en C#- of Java-frameworks werken allemaal goed. De ontwerpregels voor routes, statuscodes, validatie en authenticatie zijn belangrijker dan de taal.
Hoe beveilig ik een REST API?
Vereis authenticatie op elke route die niet openbaar is, controleer op de server of de aanroeper toegang heeft tot elk specifiek record, valideer alle invoer, gebruik HTTPS, beperk het aantal verzoeken en bewaar geheimen in omgevingsvariabelen. Vertrouw nooit ID's of rollen die door de client worden meegestuurd.
Heb ik een aparte backend nodig voor een REST API?
Niet altijd. Frameworks zoals Next.js kunnen API-routes naast pagina's serveren. Een aparte API-service is zinvol wanneer meerdere clients (web, mobiel, partners) hem gebruiken, of wanneer hij een eigen taal of schaalbaarheid nodig heeft.