Geonovum / KP-APIs

26 stars 40 forks source link

Versioning en data #215

Open frankvanes opened 4 years ago

frankvanes commented 4 years ago

Wellicht is het slim om iets te zeggen over data en API versies. Stel, je biedt een API aan en maakt wijzigingen in de data die wordt uitgewisseld in het API verzoek of antwoord, maar niet in de interface specificatie (bv je accepteert andere waarden voor request parameters of geeft net iets andere data terug in de representaties van de resources). Dit heeft geen impact op de OAS specificatie (tenzij je ALLES met enums specificeert) maar kan wel clients breken. In dat geval zal je mijns inziens wel een nieuwe (mogelijk major) versie van de API moeten introduceren.

Wellicht ook goed om te kijken wat Zalando doet in haar API design principes mbt x-extensible-enum: https://opensource.zalando.com/restful-api-guidelines/#112

joostfarla commented 4 years ago

Zeker een goed idee om iets op te nemen over o.a. het omgaan met enumeraties en eventuele (externe) waardelijsten. Deze parkeer ik even voor de design rule extensions.

lvanderree commented 4 years ago

Ik verwees net in een ander (al gesloten ticket) ook naar de zalando standaarden mbt versionning: https://github.com/Geonovum/KP-APIs/issues/157#issuecomment-630045465

tdonker commented 3 years ago

In de Werkgroep API Strategie van de NL energy sector zijn we momenteel aan het onderzoeken hoe om te gaan met enumeraties. Een interessante oplossing voor het 'enumeratie probleem' is de Code Lists aanpak gebaseerd op de OASIS UBL standaard:

http://docs.oasis-open.org/codelist/ns/genericode/1.0/

kern van deze aanpak is dat enumeraties niet meer onderdeel zijn van je service contract (wsdl of OAS spec), maar de enumeraties zijn opvraagbaar via Code Lists die bijvoorbeeld via een API beschikbaar worden gesteld. Voordeel is o.a. dat de Code Lists dynamisch kunnen worden onderhouden en producer en consumer ontkoppeld zijn. Caching van Code Lists is wellicht mogelijk en past binnen de REST constraints. Verder zijn er geen versionerings discussies over het contract indien enumeraties worden toegevoegd (minor change?) of worden verwijderd (major change?).

Een praktijkvoorbeeld lijkt: https://www.kadaster.nl/zakelijk/registraties/basisregistraties/informatiemodel-kadaster/waardelijsten

Ik ben benieuwd of de Code List aanpak onder de aandacht is van het kennisplatform KP APIs.

fsamwel commented 3 years ago

Een dynamische codelijst is een oplossing voor een ander probleem dan een enumeratie. Code lijsten bestaan in de basisregistraties al heel veel, bijvoorbeeld de BRP gemeentelijke tabellen voor landen, gemeenten, nationaliteiten, enz.

Een enumeratie gebruik je m.i. wanneer er echt logica bij de client is die de vaste waarden gebruikt, vergelijkbaar met wanneer je een Boolean gebruikt (dat is een enumeratie met 2 mogelijke waarden). if (enumveld===ENUMWAARDE) then ...

Een codelijst gebruik je wanneer een code opgeslagen wordt in de registraties en gebruikt wordt voor (formele) uitwisseling, maar de bijbehorende omschrijving opgezocht moet kunnen worden. Een codelijst kan elk moment wijzigen, maar zal over het algemeen geen codes verwijderen, wel code/omschrijving rijen toevoegen of het omschrijvingen wijzigen of een einddatum op een code/omschrijving zetten.

wmeijers commented 3 years ago

De Genericode standaard is oorspronkelijk 'bedacht' door OASIS om het beheer van enumeraties te vereenvoudigen, definities expliciet te maken en om ze te kunnen verwijderen uit de UBL interfaces. Ze hebben als bijkomend voordeel dat je aan de enumeratie metadata kan koppelen (zoals formele [business] definities, beschrijving, etc.). De (Genericode) codelijst wordt dus wel degelijk gebruikt voor het beheer van enumeraties. In mijn optiek is een enumeratie alles wat je kan uitdrukken in een discrete opsomming van (string-) waarden en komen die voor in drie 'smaken':

  1. Waarden die zelden of nooit zullen wijzigen (boolean, dagen van de week, geslacht, etc.). Deze kan je in principe gewoon in een interface opnemen omdat de kans dat er 'breaking changes' zullen optreden heel klein is;
  2. Waarden die af en toe wijzigen. Hier is het een beetje afhankelijk van de 'dynamiek' van de corresponderende interface in verhouding tot de wijzigingen op de enumeratie. Als de interface stabiel is en/of veel afnemers kent en/of de enumeratie wijzigt onevenredig vaak zou je dit met codelijsten kunnen oplossen, maar als het 'past' kan je de enumeraties hier ook gewoon in de interface opnemen en wijzigingen laten meelopen in de reguliere interface lifecycle;
  3. Waarden die frequent (kunnen) wijzigen of waarbij het uit oogpunt van formele definities belangrijk is om metadata mee te sturen. Deze wil je zeker niet als enumeratie in de interface. Maar je wil de waarden ervan ook liever niet via een 'out of band' kanaal (lees: documentatie) gaan doorgeven wegens foutgevoeligheid. In dat geval is een dynamische codelijst met een separaat opvraag-kanaal een goede oplossing. De afnemer bepaalt op die manier zelf hoe hij in sync. wil blijven.

Een variant die wij helaas intern vaak tegenkomen is het simpelweg los laten van de enumeratie waarden op de interface. Met andere woorden: de interface levert een string en de interpretatie ervan wordt overgelaten aan producer en consumer (b.v. middels design documentatie). Je hebt hier in ieder geval qua interface geen breaking changes, maar de kans op run-time fouten als de producer plotseling nieuwe waarden gaan sturen is natuurlijk levensgroot aanwezig.

tdonker commented 3 years ago

Zoals Frank van Es al aangeeft in de aanmaak van dit issue, is de x-extensible-enum aanpak van Zalando een interessante optie. Een enumeratie set die kan worden uitgebreid, wordt aangegeven met de term 'x-extendible-enum', zodat clients worden uitgenodigd tot defensive programming om breaking changes te voorkomen als nieuwe enumeraties worden toegevoegd in de response.

Een enumeratie set die fixed is, wordt dan geïdentificeerd met het reguliere type 'enum'.

Het x-extensible concept van Zalando is ook besproken in de OpenAPI-Specification community: https://github.com/OAI/OpenAPI-Specification/issues/1552

en OpenAPI-Specification community zoekt daarin contact met de Zalando community: https://github.com/zalando/restful-api-guidelines/issues/412

Zijn er bij het KP APIs nog initiatieven om de x-extensible-enum op te nemen in de API design rules extensions?

wmeijers commented 3 years ago

De 'x-extensible-enum' geeft i.d.d. op een efficiënte manier aan dat je te maken hebt met een "categorie 2" enumeratie (m.a.w. een enumeratie die 'kan' wijzigen) en dat de wijzigingen niet per definitie zichtbaar zijn in het schema. Het scheelt dus schema-versie updates op het moment dat de enumeratie wordt aangepast en waarschuwt de cliënt dat hier defensief te werk moet worden gegaan. Het lost uiteraard NIET het probleem op dat de cliënt niet zeker is van de waarden die het kan verwachten, anders dan die waarden die expliciet in het schema zijn vermeld.

Je 'zou' dus tot de volgende onderverdeling kunnen komen: Categorie 1 ('fixed'): 'enum'; Categorie 2 ('semi-fixed'): 'x-extensible-enum'; Categorie 3 ('volatile'): Code List;

Ik vraag mij wel af hoe tooling hiermee om zal gaan. Ten eerste is 'x-extensible-enum' niet standaard JSON (maar "zou" in theorie door tools genegeerd moeten worden). Ten tweede zullen tools die validatie tegen het schema doen wellicht met warnings (of misschien zelfs met fouten?) kunnen komen als je deze constructie gaat toepassen.