JSON, REST & clientverzoeken
Tot hier ging het over HTTP als protocol: de vorm van een request en een response. Deze pagina gaat over de manier waarop het web dat protocol in de praktijk gebruikt: JSON als taal van de body, en REST als afspraak over hoe je URL's en methoden combineert.
JSON
JSON (JavaScript Object Notation) is het standaardformaat voor gegevens in API's. Het is leesbaar voor mensen, eenduidig voor machines, en elke programmeertaal kan het lezen.
{
"id": 42,
"naam": "Robin",
"actief": true,
"score": 17.5,
"rollen": ["student", "beheerder"],
"adres": {
"stad": "Antwerpen",
"postcode": "2000"
},
"afgestudeerd": null
}
| Type | Schrijfwijze | Let op |
|---|---|---|
| String | "tekst" | Altijd dubbele aanhalingstekens |
| Getal | 42, 17.5 | Geen aanhalingstekens, punt als decimaalteken |
| Boolean | true, false | Kleine letters |
| Null | null | Niet NULL of nil |
| Array | [1, 2, 3] | Volgorde telt |
| Object | {"sleutel": "waarde"} | Sleutels zijn altijd strings |
- Enkele aanhalingstekens:
{'naam': 'Robin'}is geen JSON. - Een komma na het laatste element:
{"a": 1,}. - Commentaar toevoegen: JSON kent geen
//.
Levert de server 400 Bad Request op je body, plak ze dan even in de console met JSON.parse(...) of in een validator. Meestal is het een van deze drie.
Een JSON-body zonder de header Content-Type: application/json is vragen om problemen. Zie HTTP-headers.
REST
REST is geen protocol maar een stijl: een verzameling afspraken die zegt hoe je HTTP gebruikt zoals het bedoeld is. Een API die zich eraan houdt, kan je grotendeels raden zonder de documentatie te lezen. Dat is meteen het hele punt.
URL's zijn zelfstandige naamwoorden
Een pad benoemt een ding, geen actie. De actie zit al in de methode.
| Zoals het hoort | Zoals het niet hoort |
|---|---|
GET /gebruikers | GET /getGebruikers |
POST /gebruikers | POST /maakGebruikerAan |
DELETE /gebruikers/42 | POST /verwijderGebruiker?id=42 |
GET /gebruikers/42/bestellingen | GET /haalBestellingenVanGebruiker?id=42 |
Dezelfde vijf handelingen, altijd
| Wat je wil | Methode | Pad | Verwachte statuscode |
|---|---|---|---|
| Alle gebruikers opvragen | GET | /gebruikers | 200 OK |
| Eén gebruiker opvragen | GET | /gebruikers/42 | 200 OK of 404 |
| Een gebruiker aanmaken | POST | /gebruikers | 201 Created |
| Een gebruiker volledig vervangen | PUT | /gebruikers/42 | 200 OK |
| Eén veld aanpassen | PATCH | /gebruikers/42 | 200 OK |
| Een gebruiker verwijderen | DELETE | /gebruikers/42 | 204 No Content |
Merk het patroon op: de collectie (/gebruikers) voor lijsten en nieuwe items, het item (/gebruikers/42) voor alles wat over één ding gaat.
Query-parameters horen bij de lijst, niet bij de actie
GET /producten?categorie=laptops&max_prijs=1000&sorteer=prijs&pagina=2
Filteren, sorteren en pagineren: dat is waar query-parameters voor dienen. Het id van één product hoort in het pad (/producten/42), niet in een parameter.
Alles samen in één schema. Merk op dat de collectie maar twee methoden kent en het item vier: je kan een lijst niet "vervangen" of "verwijderen", en je kan niet iets nieuws aanmaken ónder een bestaand item.
Een verzoek opbouwen: drie clients, één request
Wat je ook gebruikt, er gaat exact hetzelfde over de lijn. De server ziet geen verschil.
curl
curl -X POST https://jsonplaceholder.typicode.com/posts \
-H "Content-Type: application/json" \
-d '{"title": "Mijn post", "body": "Inhoud", "userId": 1}'
fetch() in de browser
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: 'Mijn post', body: 'Inhoud', userId: 1 }),
});
const data = await response.json();
console.log(response.status, data);
Postman
Methode POST kiezen, de URL invullen, bij Headers Content-Type: application/json toevoegen, en bij Body → raw → JSON je gegevens plakken.
Naast elkaar gezet valt op hoe letterlijk die drie op elkaar lijken:
| Onderdeel | curl | fetch() | Postman |
|---|---|---|---|
| Methode | -X POST | method: 'POST' | Keuzemenu |
| Headers | -H "..." | headers: { ... } | Tabblad Headers |
| Body | -d '...' | body: JSON.stringify(...) | Tabblad Body |
| Resultaat | Uitvoer in de terminal | response.status, await response.json() | Onderste paneel |
fetch() faalt enkel bij netwerkfouten, niet bij 404 of 500: die zijn geldige responses. Controleer dus altijd zelf de statuscode:
if (!response.ok) {
throw new Error(`Request mislukt met status ${response.status}`);
}
Alles samen ontleed
Een volledig POST-request met de bijhorende response, met bij elk onderdeel de pagina waar het uitgelegd werd:
Request
POST /api/gebruikers HTTP/1.1 ← methode + pad + versie
Host: api.voorbeeld.be ← verplichte header
Content-Type: application/json ← formaat van de body
Content-Length: 47
Authorization: Bearer eyJhbGci... ← wie je bent, bij elk request opnieuw
{"naam": "Robin", "email": "r@ap.be"} ← de body, in JSON
Response
HTTP/1.1 201 Created ← gelukt, en er is iets aangemaakt
Content-Type: application/json ← formaat van het antwoord
Location: /api/gebruikers/5 ← waar de nieuwe bron staat
{"id": 5, "naam": "Robin", "email": "r@ap.be"}
| Onderdeel | Uitgelegd in |
|---|---|
POST, en waarom niet PUT | HTTP-methoden |
/api/gebruikers | URI's en URL's |
Host, Content-Type, Authorization, Location | HTTP-headers |
201 Created | Statuscodes |
| De JSON-body | deze pagina |
- jsonplaceholder.typicode.com – doet alsof: je
POSTkrijgt netjes201en eenidterug, maar er wordt niets bewaard. - httpbin.org – kaatst je request terug als JSON, inclusief je headers en je body. Ideaal om te controleren wat je nu écht verstuurde.
Test jezelf
1. Welke aanroep past het best bij "verwijder bestelling 17"?
2. Je `fetch()` krijgt een `404` terug. Wat gebeurt er in je code?
3. Waarvoor gebruik je query-parameters in een REST-API?
- JSON gebruikt dubbele aanhalingstekens, geen komma na het laatste element en geen commentaar; stuur altijd
Content-Type: application/jsonmee. - REST gebruikt paden als zelfstandige naamwoorden en zet de actie in de methode.
- De collectie (
/gebruikers) dient voor lijsten en nieuwe items, het item (/gebruikers/42) voor alles wat over één ding gaat. - Query-parameters dienen om te filteren, sorteren en pagineren.
curl,fetch()en Postman bouwen exact hetzelfde request op;fetch()gooit geen fout bij404of500.