Ga naar hoofdinhoud

Endpoints

Uitgangspunten

Bij de ontwikkeling van headless endpoints hanteren we de volgende uitgangspunten. NB: dit zijn uitgangspunten en niet keiharde regels. In specifieke gevallen kan met onderbouwing hiervan afgeweken worden.

U1 Endpoints houden zich aan gangbare conventies voor REST

Zie bv Best practices for RESTful web API design.

Dit betekent o.a.:

  • Verwijzingen hebben de vorm van een absoluut pad naar het betreffende endpoint.
  • Idempotentie van endpoints is af te leiden van hun verb.
  • De API is stateless.

Gezien het generieke karakter van de API, wordt geen poging gedaan om een meervoudsvorm van entiteiten te genereren en in afwijking van gangbare conventies is de naam van een entiteit in een endpoint path daarom altijd in enkelvoud.

U2 De inhoud van een endpoint is tot in volledig detail strongly-typed

Concreet betekent dit dat er geen inhoud wordt teruggegeven die niet expliciet in de OpenAPI specificatie is opgenomen.

U3 Endpoints zijn te autoriseren op basis van route

De autorisatie op een endpoint moet volledig af te leiden zijn uit de route van het endpoint en is onafhankelijk van overige parameters in de querystring of de body van de request.

U4 Input gelijk aan output is geen wijziging

De output van een GET-request kan worden gebruikt als input voor het overeenkomstige PUT-request. Als deze input volledig identiek is, dan is de operatie een no-op.

U5 Geen input is geen wijziging

Als in de input voor een wijziging een bepaalde eigenschap wordt weggelaten, dan betekent het dat deze eigenschap niet wijzigt. Verwijderen/leegmaken is altijd een expliciete actie.

U6 Aanpassingen zijn niet brekend

Aanpassingen die we maken in iprox.headless zorgen niet voor brekende wijziging in de API die iprox.headless aanbiedt, zodat bestaande applicaties gebouwd op iprox.headless zonder wijziging kunnen upgraden. Eventueel kan er implementatie informatie bestaan die aanduidt hoe deze compatibiliteit gerealiseerd moet worden.

U7 Endpoints zijn synchroon

De bewerking die een endpoint uitvoert is synchroon. Dit betekent dat direct na het uitvoeren van het endpoint, het resultaat hiervan zowel via individuele bevraging als in lijstvorm beschikbaar is.

U8 Endpoints zijn transactioneel

Bewerkingen via endpoints zijn ofwel een volledig succes, ofwel worden in het geheel niet doorgevoerd.
NB: dit is niet hoe iprox.cms werkt. Als je vanuit pagina wijzigen een veld aanpast en op publiceren drukt en vervolgens blijkt server-side dat er nog iets niet valide is aan het item (voorbeeld: de wijziging van de HTML levert WCAG-issues op), dan wordt het veld wel opgeslagen, maar de pagina niet gepubliceerd. Via de headless API zou het resultaat dus zijn dat de bewerking in zijn geheel niet is doorgevoerd.

Endpoints in versie 4.x headless

Endpoints in 4.x hebben default het formaat:

/<status>/<site>/<selectie>/<type>

Hierbij is:

  • status = content of preview, waarbij content gepubliceerde content is en preview de meest recente versie in het CMS.
  • site = de alias van de site. Deze kan hard-coded in het endpoint path staan (default) of een path parameter zijn (bij BundleSites).
  • selectie = ofwel een item ID ofwel een item alias ofwel list (voor een lijst van items) ofwel facet (voor een lijst van facetten).
  • type = ofwel een paginatype ofwel item (levert geen pagina-inhoud) ofwel changelog (levert wijzigingsinformatie).

Dit endpoint formaat is in nieuwere versies van headless te genereren door het gebruik van een optie van de generator (nog te implementeren). Hiermee wordt invulling gegeven aan uitgangspunt U6.

Endpoints in nieuwe versie headless

Endpoints hebben het formaat:

/<status>/<site>/<type>[/<id>][/<sub-type>[/<sub-id>]]

Deze vorm van endpoints slaat beter aan bij uitgangspunt U1 en is makkelijker uit te breiden.

Endpoints

Onderstaand overzicht bevat alle endpoints van headless.

  1. GET /<status>/<site>/<type>/<id> vraagt 1 item.
  2. GET /<status>/<site>/<type> vraagt lijst van items.
  3. GET /<status>/<site>/<type>/facet vraagt facetten bij lijst van items.
  4. GET /<status>/<site>/changelog vraagt lijst van wijzigingen.
  5. GET /<status>/<site>/item/<id>/<sub-type> vraagt lijst van kinderen.
  6. GET /<status>/<site>/asset/<path> vraagt specifiek asset.
  7. POST /<status>/<site>/item/<parentId>/<type> maakt nieuw item/pagina.
    NB 1: dit endpoint kan ook gebruikt worden om pagina's te verplaatsen of kopiëren. Hiervoor heb je ook rechten nodig op de bron dus dit is een afwijking van uitgangspunt U3.
  8. PUT /<status>/<site>/<type>/<id> wijzigt een bestaand item.
    NB 1: dit endpoint is niet in alle situaties idempotent, bv niet als de wijziging een cluster verwijdert.
    NB 2: dit endpoint kan ook gebruikt worden om een item te verbergen.
  9. POST /<status>/<site>/item/<id>/lock lockt een pagina voor bewerken.
  10. GET /<status>/<site>/item/<id>/version vraagt lijst van versies.
  11. GET /<status>/<site>/<type>/<id>/version/<version-id> vraagt specifieke versie.
  12. PUT /<status>/<site>/<type>/<id>/version/<version-id> haalt specifieke versie terug.
  13. DELETE /<status>/<site>/item/<id> verwijdert een item.
  14. PUT /<status>/<site>/asset/<path> uploadt een asset.

Bij endpoints die content wijzigen, geeft status aan of deze wijziging direct gepubliceerd moet worden (content) of niet (preview).

De eerste 6 endpoints van bovenstaand overzicht zijn ook beschikbaar in versie 4.x. Voor de volledigheid volgen hier de paths in versie 4.x.

  1. GET /<status>/<site>/<id>/<type> vraagt 1 item.
  2. GET /<status>/<site>/list/<type> vraagt lijst van items.
  3. GET /<status>/<site>/facet/<type> vraagt facetten bij lijst van items.
  4. GET /<status>/<site>/list/changelog vraagt lijst van wijzigingen.
  5. GET /<status>/<site>/<id>/<sub-type> vraagt lijst van kinderen.
  6. GET /asset/<site>/<path> vraagt specifiek asset.

Response codes

De response codes bij succes zijn:

  • 200 OK voor alle GET requests.
  • 201 Created voor POST requests die nieuwe inhoud aanmaken. Bevat in de response headers een verwijzing naar de locatie van hetgeen is aangemaakt.
  • 202 Accepted is momenteel niet relevant (conform uitgangspunt U87), maar in de toekomst mogelijk voor requests die via een background job worden afgehandeld, zoals het kopiëren van een tak.
  • 204 No Content voor alle andere requests die een bewerking doen.

De response codes bij geen succes zijn:

  • 400 Bad Request voor alle requests waar op basis van het formaat van de request en/of zijn body duidelijk is dat de request niet kan worden afgehandeld.
  • 401 Unauthorized als authenticatie nodig is, maar niet (succesvol) is.
  • 403 Forbidden als authenticatie succesvol is, maar de gebruiker onvoldoende rechten heeft.
  • 404 Not Found als de entity aangeduid in het path niet is gevonden.
  • 409 Conflict als de bewerking om een andere reden dan hierboven genoemd niet mogelijk is. Bijvoorbeeld doordat een andere gebruiker het item gelockt heeft. Of omdat een cluster verwijderd wordt dat niet (meer) bestaat.
  • 413 Content Too Large als de te plaatsen content (file) te groot is.
  • 500 Internal Server Error als de request juist is, maar de afhandeling faalt. Dit is nooit verwacht gedrag.
  • 501 Not Implemented als een bepaalde functionaliteit (nog) niet ondersteund wordt.

Als de code van headless een response code 400 Bad Request, 409 Conflict of 501 Not Implemented wordt teruggegeven, dan moet dit altijd gepaard gaan met een body van het type ProblemDetails, zodat de gebruiker weet wat er niet goed was aan zijn request (of aan de omstandigheden, zoals bij locking).

In gevallen waar de bewerking onverwacht faalt, zoals 500 Internal Server Error, wordt vermeden om foutdetails te lekken over de API.

Andere response codes zoals 405 Method Not Allowed kunnen wel door het systeem teruggegeven worden, maar zullen nooit vanuit code van headless gemaakt worden.