Informatievlaanderen / generieke-hypermedia-api

Bouwen van een specificatie van generieke bouwblokken voor API’s in Vlaanderen
8 stars 4 forks source link

Paginering #1

Open pietercolpaert opened 6 years ago

pietercolpaert commented 6 years ago

Voor het pagineren van datasets kunnen verschillende standaarden gevolgd worden:

Er kan een algoritme geschreven worden om meteen alle standaarden te verwerken en zeker te zijn dat, als een pagina een volgende heeft, de volgende pagina gevonden kan worden. Een draft van zo’n algoritme komt hier: https://github.com/pietercolpaert/extract-page-controls

nvdk commented 6 years ago

JSONAPI specifieert pagination op volgende manier:

Pagination links MUST appear in the links object that corresponds to a collection. To paginate the primary data, supply pagination links in the top-level links object. To paginate an included collection returned in a compound document, supply pagination links in the corresponding links object.

The following keys MUST be used for pagination links:

first: the first page of data last: the last page of data prev: the previous page of data next: the next page of data

Een concreet voorbeeld:

links : {
  next : "/exports/?page[number]=1&page[size]=10"
  last : "/exports/?page[number]=1&page[size]=10"
  first : "/exports/?page[size]=10"
  self : "/exports/?page[size]=10"
}

De invulling van de query parameters is relatief vrij (voorbeelden staan op de website), de query parameter page is gereserveerd voor paginatie.

rubensworks commented 6 years ago

Streaming kan ook een nuttig alternatief zijn voor expliciete paginering, aangezien dit al native support heeft in vele HTTP libraries.

jensscheerlinck commented 6 years ago

In vebrand met pagination:

Ook standaardisatie nodig rond input parameters voor paginatie?

Rond steaming

Mogelijk te ondersteunen:

nvdk commented 6 years ago

het lijkt met niet wenselijk om de input parameters te standardiseren, aangezien dit eerder limiterend werkt. Niet voor alle data(bronnnen) zal paginering werken met offsets bijvoorbeeld. Het gebruik van links om naar volgende en vorige pagina('s) te gaan biedt hier meer vrijheid.

Mbt streaming: dit wordt in de praktijk nog niet veel gebruikt en standardiseren hierop lijkt me eerder voorbarig.

bertvannuffelen commented 6 years ago

stel dat we afspraken van de hypermedia links willen maken, leggen we dan ook vast de voorkeursterminologie:

"_links": {
     "_self" : "...",
    }

of

"links" : {
   "self" : " ...", 
    ...
   }

of is dit vrij te kiezen.

bertvannuffelen commented 6 years ago

ivm de discussie of header versus payload. Ik prefereer een afspraken kader voor de payload dan de header links. Het voordeel is dat hypermedia links in de payload ook kunnen gebruikt worden voor andere relaties. En dat we die relaties kunnen semantisch beschrijven (via een json-ld context).

Met de header aanpak kunnen we enkel de voorgedefinieerde ondersteunen. Voor mij zou dit enkel aangeraden worden om die toe te voegen als die ook in de payload zitten.

Voor het argument: "maar headers kunnen ook andere relaties ondersteunen". Je kan die wel niet eenvoudig mappen op de semantiek. Met een json-ld context is er een generiek machinaal toepasbare methode om de semantiek te koppelen aan de payload. En dat is niet mogelijk met de header aanpak.

pietercolpaert commented 6 years ago

Ik zou geen voorkeur-strategie opleggen omdat ik merk dat we daar geen concensus in zullen vinden. Wel zou ik zoveel mogelijk versies proberen ondersteunen (zowel in HTML met <link rel=...> als in JSON op deze manieren).

bertvannuffelen commented 6 years ago

Kunnen we dan de verschillende aanvaarde varianten oplijsten. Want ik denk dat dit een begin is om het verhaal concreter te maken.

pietercolpaert commented 6 years ago

Zie https://github.com/Informatievlaanderen/generieke-hypermedia-api/blob/master/paginering.md

sophiekemper commented 6 years ago

In het lijstje van gekende varianten kunnen we ook de paginering opnemen die voorkomt in alle samples van Spring Boot en Spring HATEOS: "meta": { "totalElements": 71, "totalPages": 15, "number": 1, "numberOfElements": 5, "size": 5, "first": true, "last": false }

Uiteraard is het gebruik van booleans voor 'first' of 'last' geen goede manier van werken, maar een variant waarbij we die first en last weglaten en daarnaast het links-element van JSON API opnemen zou een aanvaardbare manier van werken kunnen zijn.

pietercolpaert commented 6 years ago

@sophiekemper Ik denk dat we best de beste niet conflicterende en goed gedocumenteerde specificaties enkel ondersteunen. HAL, JSON API en HYDRA komen daarbij het dichtste bij.

bertvannuffelen commented 6 years ago

kunnen we json-API en Hal syntax niet annoteren met een standaard json-ld context? en dan enkel stap 1 en 2 overhouden?

Maar dan moeten we wel een uitbreiding aan json-ld voorzien dat om kan met substructuren ("links", "_links").

Dan kunnen we ook nederlandstalige paginatie toelaten:

{"@context" : {
    "eerste" :  "hydra:first"
  },
  ...
  "_links": {
     "eerste" : "/api/v10/resources?limit=1"
     ...
 } 
}
jensscheerlinck commented 6 years ago

Zou er eventueel zo kunnen uitzien zonder uitbreiding geloof ik (JSON-LD 1.1):

{
  "@context": {
     "hydra": "http://www.w3.org/ns/hydra/core#",
     "first": { "@id": "hydra:first", "@type": "@id" },
     "last": { "@id": "hydra:last", "@type": "@id" },
     "next": { "@id": "hydra:next", "@type": "@id" },
     "prev": { "@id": "hydra:previous", "@type": "@id" },
     "_links": "@nest",
     "links": "@nest", 
     "href": "@id",
  }
}

Indien keys nederlandstalig zouden worden (eerste, volgende, vorige, laatste) zou de response strikt genomen niet meer aan de JSON API of HAL spec voldoen?

bertvannuffelen commented 6 years ago

@jensscheerlinck inderdaad de "@nest" van json-ld 1.1 werkt.

Dat betekent dus wel dat hiervoor we moeten aligneren op json-ld 1.1 wat nog een draft is.

ivm nederlandstalige keys: de engelse termen zijn in de JSON-API specification ook de technische identificatoren, dus ja dan worden ze incompatibel. zie http://jsonapi.org/format/#fetching-pagination.

HAL specifieert enkel "_links" en laat de rest vrij.

Echter de Hydra aanpak geeft nog meer vrijheid omdat de betekenis niet vast hangt aan een technische term maar aan de interpretatie door de json-ld context.

bertvannuffelen commented 6 years ago

Ivm met de tekst:

kunnen we ons baseren op een draft specificatie zoals Hydra, of moeten we een eigen json-ld context definiëren?

bertvannuffelen commented 6 years ago

Ivm met de tekst op sectie Semantisch

Als je json-API paginering ondersteunt dan veronderstel ik dat je hele API json-API is. Je zal waarschijnlijk nooit half kiezen. Dus de vraag rijst: is JSON-API een specificatie die aan alle-afspraken voldoet?

bertvannuffelen commented 6 years ago

Ivm met de tekst. De voorbeelden en het algorithme matching niet.

het voorbeeld json-API heeft links -> first -> waarde en het voorbeeld HAL heeft _links -> first -> href -> waarde. terwijl het algoritme stelt dat stap 3: _links -> first -> waarde stap 4: links -> first -> href -> waarde

bertvannuffelen commented 6 years ago

ivm het algoritme:

waarom stap 3 en 4 niet samen nemen in 1: (links|_links) -> first -> (waarde|href).

bertvannuffelen commented 6 years ago

ivm het algoritme:

waarom niet previous als synoniem in alle stappen ondersteunen?

bertvannuffelen commented 6 years ago

tenslotte moeten we ook afspraken maken over de paramaters in de API request (page/limit/offset...)? O is dit niet noodzakelijk omdat de hypermedia navigatie controls meer als voldoende zijn.

Beslissing graag opnemen in de tekst.

jensscheerlinck commented 6 years ago

@bertvannuffelen

kunnen we ons baseren op een draft specificatie zoals Hydra, of moeten we een eigen json-ld context definiëren?

Terechte vraag. In de veronderstelling dat de huidige Hydra properties nodig voor paginering (collecties, next, prev...) vrij stabiel zijn zouden we een eigen 'applicatieprofiel' voor paginering kunnen definiëren, eventueel gebaseerd op de draft specificatie voor paginering die momenteel gelinkt staat.

tenslotte moeten we ook afspraken maken over de paramaters in de API request (page/limit/offset...)? O is dit niet noodzakelijk omdat de hypermedia navigatie controls meer als voldoende zijn.

Momenteel is dit out of scope gelaten van de specificatie, aan de hand van deze opmerking:

Als je json-API paginering ondersteunt dan veronderstel ik dat je hele API json-API is. Je zal waarschijnlijk nooit half kiezen. Dus de vraag rijst: is JSON-API een specificatie die aan alle-afspraken voldoet?

Hier heb ik niet meteen zicht op omdat ik JSON API niet voldoende ken hiervoor. Misschien heeft @nvdk hier een idee over?

De voorbeelden en het algorithme matching niet.

Aangepast + andere suggesties verwerk ik later nog.

Opmerking: deze specificatie doet geen uitspraken over de paginering strategie van een server. Zo kunnen onder meer cursor-, offset- of pagina gebaseerde paginering strategieën gebruikt worden.