Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aanpassingen en aanvullingen nav #29 #67

Merged
merged 5 commits into from
Sep 16, 2020
Merged

Aanpassingen en aanvullingen nav #29 #67

merged 5 commits into from
Sep 16, 2020

Conversation

melsk-r
Copy link
Contributor

@melsk-r melsk-r commented Sep 7, 2020

N.a.v. #29 zijn de volgende aanpassingen en aanvullingen aangebracht:

Ik stel een aantal toevoegingen voor op de richtlijnen voor berichtontwerp:

De identificatie van een resource zit, wanneer die is opgenomen in de resource anders dan in _links.self, en gebruikt wordt als path-parameter van het resource-endpoint, altijd op het hoogste niveau van de resource in de vorm en inhoud zoals die wordt opgenomen in de uri (path-parameter) van de resource.

Zie DD5.10.

We nemen geen waarden op met een speciale betekenis die afwijkt van de normale betekenis van het gegeven.

* bijvoorbeeld datum "0000-00-00" om aan te geven dat een datum onbekend is

* bijvoorbeeld landcode "0000" om aan te geven dat het land onbekend is

Zie DD5.11.

We nemen geen reden op over het leeg/afwezig zijn van een waarde van een gegeven (zoals met StUF:noValue werd gedaan), tenzij duidelijk is dat er bij de gebruikers behoefte is om dit te weten.

Zie DD5.12.

Wanneer het gevuld zijn van een datum functionele betekenis heeft, ook wanneer deze volledig onbekend is, wordt een indicator opgenomen om dit aan te geven. Bijvoorbeeld of een persoon overleden is kan niet worden afgeleid uit het bestaan van een overlijdensdatum wanneer die datum onbekend is. Daarvoor kan een boolean "indicatieOverleden" worden gedefinieerd.

Zie DD5.13.

Eigenschappen die functioneel alleen een waarde Ja/aan/waar of Nee/uit/onwaar kunnen hebben, worden gedefinieerd als boolean. We gebruiken dus geen enumeratie zoals [J,N] voor dit soort situaties.

Zie DD2.4.

Wanneer een gegeven in het informatiemodel gedefinieerd is als enumeratie, maar de enumeratiewaarde door gebruikers van de API alleen gebruikt wordt om als tekst te tonen aan eindgebruikers (mensen), dan als string (niet als enumeratie) definiëren in de API.
Wanneer de enumeratiewaarde gebruikt wordt in code (algoritmes), dan betekenisvolle maar bondige code.

Ratio
Opnemen van de enumeratie in de API is een vorm van tight coupling

Zie DD2.5.

We gebruiken als enumeratiewaarden betekenisvolle waarden. Dus niet M en V, maar man en vrouw.

Was al opgenomen onder DD2.3.

De lengte van enumeratiewaarden wordt beperkt. Bijvoorbeeld "Opstalhouder Nutsvoorzieningen op gedeelte van perceel" krijgt als code "nutsvoorzieningen_gedeelte".

Zie DD1.13.

Enumeratiewaarden worden opgenomen in snake_case.

DD1.4 aangepast.

We vermijden het gebruik van afkortingen in propertynamen. Propertynamen moeten zoveel mogelijk zelfverklarend zijn.

Zie DD1.14.

Gegevens in een resource moeten kunnen worden gebruikt en geïnterpreteerd zonder domeinkennis of complexe algoritmes.

DD1.1 is aangescherpt n.a.v. deze opmerking.

We gebruiken geen oneOf of anyOf constructies voor polymorfe gegevens. Wanneer er veel overlap is en geen strijdigheid tussen de verschillende mogelijke types, worden ze platgeslagen tot één resource of één object. Alternatief is voor elk type een property op te nemen, met daarin de eigenschappen van dat type. In beide gevallen nemen we ook een type property op waaruit de gebruiker kan lezen welk type het betreft.

DD5.4 is aangescherpt n.a.v. deze opmerking.

Wanneer er voor een begindatum of einddatum al een functioneel gegeven bestaat, gebruiken we die. Denk aan datumOntbindingHuwelijk of datumAanvangAdreshouding.

Zie DD5.14.

Voor einddatums moet er altijd expliciet in de naam staan of het "tot" of "totEnMet" is.

Zie DD1.15

Als queryparameters voor het historisch opvragen gebruiken we "peildatum", "datumvan" en "datumtotenmet"

Zie DD4.3

Wanneer er geen functioneel gegeven bestaat in het model voor einddatum, maar daar is wel behoefte aan (omdat historie getoond wordt) gebruiken we "datumTot". Bijvoorbeeld in BRP wordt alleen de begindatum van een verblijfplaats geregistreerd, geen einddatum, dus is datumTot=datumAanvang van de volgende verblijfplaats.

Zie DD5.15.

Wanneer er een gegevenswoordenboek (gegevenscatalogus, informatiemodel) bestaat, gebruiken we voor corresponderende resource of voor corresponderende properties in een resource de naam zoals die in het gegevenswoordenbook staat, met inachtneming van de naamgevingsrichtlijnen zoals die in dit document staan benoemd, zoals gebruik (Upper)snakeCase.

Van de naam in het gegevenswoordenboek kan worden afgeweken in o.a. de volgende situaties:

* Weglaten van redundatie in de naam. Bijvoorbeeld "geboortedatum" in een gegevensgroep geboorte nemen we op als "datum".

* Uitschrijven van afkortingen. Bijvoorbeeld "BSN" nemen we op als "burgerservicenummer".

* Toevoegen van context, bijvoorbeeld wanneer het gegeven in een andere context wordt gebruikt dan in het gegevenswoordenboek. Bijvoorbeeld het opnemen van gegeven "identificatie" van een woonplaats bij een nummeraanduiding wordt property "woonplaatsIdentificatie"

* Een van het gegeven via een algoritme afgeleide property. Bijvoorbeeld "leeftijd" van "geboortedatum".

Zie DD1.16

Wanneer er in de naam van een property wordt afgeweken (anders dan toepassen snakeCase) van de naam van het corresponderende gegeven in het gegevenswoordenboek, wordt de naam van dat gegeven in het gegevenswoordenboek opgenomen in attribuut "title" in de definitie van het property in API. In alle andere gevallen wordt title niet opgenomen in de definitie van een property.

Zie DD1.17. Aan bovenstaande beschrijving heb ik lowerCamelCase en UpperCamelCase als uitzonderingen toegevoegd.
Ik vraag me af of snakeCase hier wel terecht wordt genoemd. Volgens mij is dat nl. alleen van toepassing op enumeratiewaarden.

We nemen bij een property een description op die semantisch overeenkomt met de beschrijving in het gegevenswoordenboek. Deze kan ingekort, vereenvoudigd, of uitgebreid zijn, maar mag de betekenis van het gegeven niet laten afwijken van de betekenis van het corresponderende gegeven in het gegevenswoordenboek.

De description kan worden weggelaten wanneer evident is dat de gebruikers van de API uit de propertynaam weten wat bedoeld wordt (bijvoorbeeld huisnummer).

Zie DD5.16.

In de description van een property mag geen logica (algoritme) worden beschreven voor het samenstellen de inhoud van het property.

Ratio
Opnemen van providerlogica veroorzaakt tight coupling tussen de bron-implementatie en de API.

Zie DD5.17

Er is geen directe koppeling tussen de definitie en structuur van gegevens in een gegevenswoordenboek (informatiemodel) en de definitie en structuur van de corresponderende resource en/of propertie in een API.
Voorbeelden:

* Een resource mag meer gegevens bevatten dan het corresponderende object uit het gegevenswoordenboek. Er mogen bijvoorbeeld gegevens uit gerelateerde objecten aan de resource worden toegevoegd. Bijvoorbeeld bij een nummeraanduiding wordt de woonplaatsnaam opgenomen.

* Een resource mag minder gegevens bevatten dan het corresponderende objecttype. In de resource worden alleen gegevens opgenomen waar behoefte aan is bij de gebruikers van de API.

* Verschillende elementen uit het object mogen worden samengevoegd tot éen property van de resource. Bijvoorbeeld aanschrijfwijze is samengesteld uit o.a. voornamen, tussenvoegsel en geslachtsnaam.

* Een element uit een model mag worden opgesplitst in meerdere properties in de resource. Bijvoorbeeld een mogelijk onbekende overlijdensdatum kan worden opgenomen als overlijdensdatum én indicatieOverleden.

* Een abstract objecttype mag als (concrete) resource worden gedefinieerd. Bijvoorbeeld adresseerbaar object wordt resource adresseerbareObjecten.

* Gegevens uit verschillende (gegevens)groepen mogen worden platgeslagen in de resource of in een gegevensgroep. Bijvoorbeeld Gemeente van inschrijving uit groep Inschrijving, functie adres uit groep Verblijfplaats en postcode uit groep Adres worden opgenomen in verblijfplaats.

* Een resource mag gegevens opnemen in een andere representatievorm.
  
  * Bijvoorbeeld Indicatie geheim kan waarden 0 (niet geheim) of 7 (geheimhouding) hebben in het informatiemodel, maar in de API wordt dit opgenomen als boolean.
  * Bijvoorbeeld enumeratie Type openbare ruimte wordt opgenomen als string, wanneer deze waarde alleen voor mensenogen bedoeld is en niet door computercode geïnterpreteerd hoeft te worden.

Ratio

* koppeling met de implementatie van de provider registratie beperkt de evolvability van zowel de achterliggende systemen, als van de applicaties die de API gebruiken als van de API zelf.

* ontwerp van de resource gericht op de informatiebehoefte en het gebruik is eenvoudiger in gebruik en verkleint kan op verkeerd gebruik.

Zie DD5.18

Wanneer in een API (comfort)gegevens worden opgenomen die authentiek zijn opgeslagen in een andere bron, worden deze bij voorkeur gemodelleerd op dezelfde manier als in de bron. Wanneer mogelijk wordt hergebruik gemaakt van de API specificatie van de andere bron (via $ref).
Bijvoorbeeld het adres (BAG) van een ingeschreven persoon (BRP) of vestiging (HR). Bijvoorbeeld de naam en geboortedatum (BRP) van een eigenaar in BRK of functionaris in HR.

Zie DD5.19

Wanneer er meerdere componenten zijn met meerdere dezelfde properties, moet er hergebruik worden gemaakt via een allOf constructie). Dit sluit aan op object oriëntatie in de verschillende programmeeromgevingen.

  • Bijvoorbeeld een woonadres en een postadres zijn identiek, behalve dat postadres ook een postbusnummer kent. Dan is postadres een extensie op woonadres.
  • Bijvoorbeeld een natuurlijk persoon en een niet-natuurlijk persoon hebben beide een naam en een adres, maar beide hebben ook eigen gegevens (natuurlijk persoon heeft geboortedatum, niet-natuurlijk persoon heeft eigenaar), dan zijn beide een extensie op een bovenliggende component "Persoon".
  • Bijvoorbeeld bij een zakelijkGerechtigde worden alleen minimale identificerende gegevens van een persoon opgenomen (alleen naam en identificatie), maar bij de persoon (resource) worden meer eigenschappen van de persoon opgenomen (zoals adres). Dan gebrukt zakelijkGerechtigde component "persoonBeperkt" en is de uitgebreide persoon een extensie hierop.

Zie DD5.20

Bij gebruik van allOf staat de component die hergebruikt wordt altijd eerst, en staan de toegevoegde properties als tweede.
Bijvoorbeeld correct gebruik van allOf:

    NaamPersoon:
      allOf:
        - $ref: "#/components/schemas/Naam"
        - description: "Gegevens over de naam van de persoon"
          properties:
            aanhef:
              type: "string"

Bijvoorbeeld fout gebruik van allOf:

	NaamPersoon:
	      allOf:
	        - description: "Gegevens over de naam van de persoon"
	          properties:
	            aanhef:
	              type: "string"
	        - $ref: "#/components/schemas/Naam"

Ratio
Afwijken van deze regel leidt tot problemen bij het genereren van code uit de API specificaties.

Zie DD5.21

Bij gebruik van allOf is er altijd exact één component waarnaar gerefereerd wordt en één gedefinieerd object met ten minste één property.
Bijvoorbeeld fout gebruik van allOf, want overerving uit twee componenten:

    NaamPersoon:
      allOf:
        - $ref: "#/components/schemas/Naam"
        - $ref: "#/components/schemas/Aanschrijfwijze"
        - description: "Gegevens over de naam van de persoon"
          properties:
            aanhef:
              type: "string"

Bijvoorbeeld fout gebruik van allOf, want heeft geen eigen properties:

    NaamPersoon:
      allOf:
        - $ref: "#/components/schemas/Naam"
        - description: "Gegevens over de naam van de persoon"

Ratio
Afwijken van deze regel leidt tot problemen bij het genereren van code uit de API specificaties.

Zie DD5.22

Eigenschappen die functioneel alleen een waarde Ja/aan/waar of Nee/uit/onwaar kunnen hebben, worden gedefinieerd als boolean. We gebruiken dus geen enumeratie zoals [J,N] voor dit soort situaties.

### DD2.5 Gebruik zo mogelijk string i.p.v. een enumeration
Wanneer een gegeven in het informatiemodel gedefinieerd is als een enumeratie, maar de enumeratiewaarde wordt door gebruikers van de API alleen gebruikt wordt om als tekst te tonen aan eindgebruikers (mensen), definiëer het gegeven dan als string (niet als enumeratie) in de API.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

er zitten wat taalfouten in deze zin (heb ik zeker zelf ingetypt ;) )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is gecorrigeerd.

@@ -147,6 +180,9 @@ Historie wordt aflopend gesorteerd op datum geldigheid (datumVan).
### DD4.2 Bij historie wordt alleen de actuele situatie van inOnderzoek getoond
Binnen de historie-endpoints wordt alleen de actuele situatie met betrekking tot "in Onderzoek" getoond. Er wordt geen historie getoond van de onderzoeken die in het verleden hebben plaatsgevonden.

### DD4.3 Gebruik standaard queryparameters voor datums bij historisch opvragen
Als queryparameters voor het historisch opvragen gebruiken we "peildatum", "datumvan" en "datumtotenmet"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NL API strategie heeft inmiddels gezegd dat we camelCase gebruiken voor parameters en dat hebben we overgenomen (nog niet doorgevoerd in oudere API's zoals BRP). Dus datumVan en datumTotEnMet

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is aangepast.

* De subtypes worden samengevoegd tot 1 object. Deze keuze is logisch als de subtypes grotendeels overlappen en er geen strijdigheid is tussen de verschillende mogelijke types.
* De subtypes worden volledig opgenomen als property van een object, met daarin de eigenschappen van dat type. In het response is altijd maar 1 van deze properties gevuld. Deze keuze is logisch als de subtypes weing gemeenschappelijke properties hebben.

In beide gevallen nemen we ook een type property op waaruit de gebruiker kan lezen welk type het betreft.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hier kan je de term "discriminator" toevoegen

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ik heb hem toegevoegd.

@@ -220,3 +260,130 @@ Dit betekent dat er in de berichtspecificaties geen gebruik gemaakt wordt van de

### DD5.9 Properties die gebruik maken van Booleans worden alleen geretourneerd als de waarde 'true' is
In diverse situaties worden booleans opgenomen als er sprake is van indicatoren. Deze booleans worden alleen geretourneerd als de waarde van de boolean ook informatief is. Dit soort properties worden dus alleen opgenomen als de waarde van de Boolean 'true' is.

### DD5.10 Identificatie van een resource zit altijd op het hoogste niveau van de resource
De identificatie van een resource zit, wanneer die is opgenomen in de resource anders dan in _links.self, en gebruikt wordt als path-parameter van het resource-endpoint, altijd op het hoogste niveau van de resource in de vorm en inhoud zoals die wordt opgenomen in de uri (path-parameter) van de resource.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Het punt is dat je deze identificatie op het hoogste niveau opneemt. Ik weet niet of het punt ook moet zijn dat deze identificatie altijd moet worden opgenomen. Bijvoorbeeld in /ingeschrevenpersonen/{burgerservicenummer}/partners/{id} is in de resource partners geen veld "id" opgenomen. Dit is namelijk puur een technische identificatie, geen functioneel gegeven (zoals bsn en kvknummer dat wel zijn). Misschien moet deze zin hiervoor een beetje herschreven worden, want het kan nu op beide manieren gelezen worden. @JohanBoer mee eens?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is de volgende formulering dan wellicht beter?

Als de identificatie van de resource geen functioneel gegeven is (zoals burgerservicenummer en kvknummer) maar een technische identificatie en alleen noodzakelijk om gebruikt te kunnen worden als path parameter dan wordt deze opgenomen op het hoogste niveau van de resource. De vorm en inhoud van die identificatie property is dan zoals die wordt opgenomen in de uri (path-parameter) van de resource.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Volgens mij was het punt van Frank dat een dergelijk veld soms helemaal niet opgenomen wordt in de resource, maar alleen wordt gebruikt in de link als path parameter.
Dus als er een identificatie wordt opgenomen dan doe je dat op het hoogste niveau in de resource.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ik heb 'wanneer' vervangen door 'als' en 'anders dan in _links.self,' verwijderd.

Copy link
Collaborator

@fsamwel fsamwel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

paar kleine opmerkingen, verder helemaal oké

@melsk-r
Copy link
Contributor Author

melsk-r commented Sep 7, 2020

Kijk ook even naar mijn opmerking over DD1.17. Ik twijfel of snakecase daar van toepassing is.

@fsamwel
Copy link
Collaborator

fsamwel commented Sep 7, 2020

Kijk ook even naar mijn opmerking over DD1.17. Ik twijfel of snakecase daar van toepassing is.

Waar staat jouw opmerking?
Ik denk dat DD1.17 kan vervallen. Voortschrijdend inzicht. Kan tight coupling met huidige bron-implementatie veroorzaken. Dit hebben we in de BAG en BRK API's in niet gedaan.

@melsk-r
Copy link
Contributor Author

melsk-r commented Sep 7, 2020

In mijn eerste post had ik:

Zie DD1.17. Aan bovenstaande beschrijving heb ik lowerCamelCase en UpperCamelCase als uitzonderingen toegevoegd.
Ik vraag me af of snakeCase hier wel terecht wordt genoemd. Volgens mij is dat nl. alleen van toepassing op enumeratiewaarden.

geschreven. Als het kan vervallen dan hoeven we het daar echter niet meer over te hebben.
Ik zal hem verwijderen.

Aanpassingen n.a.v. opmerkingen van Frank.
@@ -9,7 +9,7 @@ Onderstaande Design Decisions zijn een verbijzondering van paragraaf 6.1 van de
We benoemen altijd zo duidelijk mogelijk wat iets is.

Hoofdregel is altijd:
1. propertynamen moeten zoveel mogelijk zelfverklarend zijn (lezen van de description om de betekenis te begrijpen is liefst niet nodig)
1. propertynamen moeten zoveel mogelijk zelfverklarend zijn (lezen van de description om de betekenis te begrijpen is liefst niet nodig). Gegevens in een resource moeten kunnen worden gebruikt en geïnterpreteerd zonder domeinkennis of complexe algoritmes.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deze laatste zin vind ik byzonder. Als je zeker wilt weten dat een gegeven juist geïnterpreteerd wordt borg je dat door de definitievan dat gegeven op te nemen als description. Doe je dat niet dan is de mogelijkheid om zoiets te interpreteren afhankelijk van de domeinkennis van de developer. Alhoewel wij misschien denken dat iedereen weet wat een burgerservicenummer is is het niet vanzelfsprekend dat iedere developer dat weet.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eigenlijk zou deze zin een apart punt moeten zijn, want het gaat niet alleen over de propertynaam, maar ook over de inhoud. Je moet dus ook (juist) de waarde kunnen interpreteren zonder speciale domeinkennis of algoritme. Bijvoorbeeld Als indicatieGeheim > 0, dan ... hebben we vervangen door indicatieGeheim=true. Denk ook aan mogelijkOnjuist in BAG die niet aangeeft wat onderzocht wordt, maar wat mogelijk onjuist is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ik heb DD1.18 toegevoegd.

@@ -220,3 +260,130 @@ Dit betekent dat er in de berichtspecificaties geen gebruik gemaakt wordt van de

### DD5.9 Properties die gebruik maken van Booleans worden alleen geretourneerd als de waarde 'true' is
In diverse situaties worden booleans opgenomen als er sprake is van indicatoren. Deze booleans worden alleen geretourneerd als de waarde van de boolean ook informatief is. Dit soort properties worden dus alleen opgenomen als de waarde van de Boolean 'true' is.

### DD5.10 Identificatie van een resource zit altijd op het hoogste niveau van de resource
De identificatie van een resource zit, wanneer die is opgenomen in de resource anders dan in _links.self, en gebruikt wordt als path-parameter van het resource-endpoint, altijd op het hoogste niveau van de resource in de vorm en inhoud zoals die wordt opgenomen in de uri (path-parameter) van de resource.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Volgens mij was het punt van Frank dat een dergelijk veld soms helemaal niet opgenomen wordt in de resource, maar alleen wordt gebruikt in de link als path parameter.
Dus als er een identificatie wordt opgenomen dan doe je dat op het hoogste niveau in de resource.

Aanpassingen n.a.v. opmerkingen van Johan en Frank.
@melsk-r
Copy link
Contributor Author

melsk-r commented Sep 15, 2020

@fsamwel en @JohanBoer,
Kan ik deze PR mergen?
Dan kan ik nl. kijken of ik hem op kan splitsen in Ontwerprichtlijnen en Architectuurprincipes.

@fsamwel
Copy link
Collaborator

fsamwel commented Sep 15, 2020

van mij mag je

@JohanBoer
Copy link
Collaborator

Van mij ook.

@melsk-r melsk-r merged commit 7c84a85 into VNG-Realisatie:feature/toevoegingen#29 Sep 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants