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

Discussiepunt: wel of geen minLength op optionele properties #131

Open
melsk-r opened this issue Feb 16, 2022 · 11 comments
Open

Discussiepunt: wel of geen minLength op optionele properties #131

melsk-r opened this issue Feb 16, 2022 · 11 comments
Assignees
Labels
question Further information is requested

Comments

@melsk-r
Copy link
Contributor

melsk-r commented Feb 16, 2022

Binnen de ZGW API's is het blijkbaar een best practice om op optionele properties geen minLength te definiëren. De gedachte die daar achter zit is dat je daarmee een ontwikkelaar de mogelijkheid geeft te achterhalen welke velden er in een response kunnen zitten door een response op te vragen waarin alle velden zitten ook als ze leeg zijn. Dit is niet mogelijk als optionele velden een minLength hebben aangezien ze dan niet meegezonden worden als ze leeg zijn.

Ik heb bij deze best practice zo mijn bedenkingen.

  • Ten eerste omdat je daarmee functionaliteit in de API stopt die alleen door de ontwikkelaar wordt gebruikt terwijl die ontwikkelaar hiervoor ook het schema kan uitlezen;
  • Ten tweede omdat je het daarmee onmogelijk maakt om ook aan optionele velden specifieke lengtes op te leggen (bijv. minLength 4 en maxLength 9).

Het komt er op neer dat je af ziet van functionaliteit die noodzakelijk kan zijn om properties te valideren alleen om de ontwikkelaar nog een extra mogelijkheid te geven te achterhalen welke properties deze kan verwachten. Ik ben helemaal voor Developer friendliness maar heb het idee dat we hiermee wat doorslaan.

Ik ben heel benieuwd hoe anderen daarover denken.

@melsk-r melsk-r added the question Further information is requested label Feb 16, 2022
@melsk-r
Copy link
Contributor Author

melsk-r commented Feb 17, 2022

Ook m.b.t. security zijn er argumenten aan te dragen die het zo strak als mogelijk definiëren van validatieregels op alle properties ondersteunen. Zie daarvoor bijv. issue #911 van HC BRP en issue #913 van HC BRP.

@fsamwel
Copy link
Contributor

fsamwel commented Feb 17, 2022

issue #911 is denk ik niet van toepassing, want die gaat over requestparameters, terwijl dit issue gaat over responseproperties.

@fsamwel
Copy link
Contributor

fsamwel commented Feb 17, 2022

te achterhalen welke velden er in een response kunnen zitten door een response op te vragen waarin alle velden zitten ook als ze leeg zijn

Kan dat een doel zijn? Daarvoor hebben we toch OAS specificaties? Gaat het hier over het bedienen van ontwikkelaars die geen OAS kunnen lezen?

@fsamwel
Copy link
Contributor

fsamwel commented Feb 17, 2022

ik kan me allerlei redenen bedenken om ook lege waarden terug te krijgen. Op dit moment in de HC API's kan je om verschillende redenen een veld niet terugkrijgen:

  • je hebt er niet om gevraagd (fields)
  • je bent er niet voor geautoriseerd
  • het heeft geen waarde in de bron (null)
  • het heeft een leegwaarde in de bron ("")
  • het heeft een onbekend waarde in de bron (bijv. "." bij geslachtsnaam, "0000" bij land, enz.)
  • het heeft een (boolean) false waarde in de bron

Wij hebben ervoor gekozen om hier geen onderscheid in te maken en in al deze gevallen het gegeven niet te leveren, omdat voor de gebruikers dit onderscheid niet relevant is en afhandelen van verschillende leegwaarden, null-waarden en onbekendwaarden ingewikkeld en foutgevoelig is. Opnemen van onbekendwaarden, "magic strings" is bovendien een vorm van tight coupling.

@fsamwel
Copy link
Contributor

fsamwel commented Feb 17, 2022

Hoe zou dit er trouwens uit moeten zien voor hele objecten? Bijvoorbeeld een persoon die geen partner heeft, moet die dan toch een heel object partner krijgen met alleen null waarden? Hoe ga je dan als gebruiker vaststellen dat de persoon geen partner heeft?

@JohanBoer
Copy link
Collaborator

JohanBoer commented Apr 25, 2022

De minLength wordt gebruikt om gegevensvalidatie te kunnen doen en in het contract (oas) af te spreken aan welke restricties een veld moet voldoen. Door deze weg tel aten kan niet alleen een lege property worden doorgegeven, maar ook een property die niet voldoet aan de restricties die er op die property gelden.
Ik ben het met Frank eens dat de OAS er is voor de ontwikkelaar om te kunnen zien hoe de response er uit kan zien en welke properties onderdeel van de responmse uitmaken.
Als een veld een minimumlengte heeft dan is een lege waarde dus doodgewoon invalide, los van de reden waarom je hem leeg opneemt.

@melsk-r
Copy link
Contributor Author

melsk-r commented May 9, 2022

Tijdens het Design Rule overleg geeft @michielverhoef aan het eens te zijn met de in dit issue geopperde bedenkingen en argumenten.

@melsk-r gaat op basis van dit issue een voorstel voor een Design Rule formuleren.

@JohanBoer
Copy link
Collaborator

JohanBoer commented May 16, 2022

De vraag is of we in de get -actie een null-waarde terug wil geven bij een optioneel veld met een minimale lengte of een pattern.
Wat belangrijk is dat we hier voorspelbaar gedrag krijgen:

  • Er moet voor gekozen worden om geen optionele velden met een null terug te geven of alle optionele velden terug te geven.
    • Het kan dus niet zo zijn dat er een deel van de optionele velden als nill wordt doorgegeven.
      • Vraag is of er een functionele reden is om een optioneel veld dat geen waarde heeft als nill door te geven.
      • Vraag is of het argument dat (consumer-)developers het "handig" vinden om alle velden geretourneerd te krijgen uit developers-perspectief zwaar genoeg weegt.
      • Vraag (uitzoekwerk voor @HenriKorver ) is in hoeverre de nillable en een pattern, enumeratioen of minlength elkaar uitsluiten.

Ook een punt van discussie is het retourneren van lege strings bij optionele velden waar een enumeration, pattern of een minlength van toepassing is.

Nog een punt van discussie is of de nillable van belang kan zijn bij het uitvoeren van een patch-actie. Als een optioneel veld een waarde heeft en vervolgens als "leeg"gewijzigd moet worden terwijl er wel een pattern, enumeration of minlength op dit veld zit, hoe wordt dit dan meegegeven in de patch-actie.
(noot. Bij de put-actie geldt weer dat je consequent moet zijn in de toepassing van de nillable. Dus of in de put alle optionele properties meegeven met een null-waarde, danwel optionele properties die geen waarde hebben niet opnemen in de request-body.

@HenriKorver opperde nog een uitzoek-actie (die hij gaat uitvoeren) op de ZGW-API's omtrent het gebruik van nillable en lege strings versus het (waarschijnlijk onterecht) afwezig zijn van minlength, enumeration of patterns. Daarbij is de vraag of de API meer ruimte toelaat dan functioneel wenselijk is.

@JohanBoer JohanBoer assigned HenriKorver and unassigned melsk-r and HenriKorver May 16, 2022
@HenriKorver
Copy link
Collaborator

HenriKorver commented May 16, 2022

Vraag (uitzoekwerk voor @HenriKorver ) is in hoeverre de nillable en een pattern, enumeratioen of minlength elkaar uitsluiten.

In onderstaand JSON Schema conflicteren null, minlength, enumeration (etc.) niet met elkaar.

{
	"$schema": "http://json-schema.org/schema#",
	"description": "Comment describing your JSON Schema",
	"type": "object",
	"properties": {
		"street_name": {
			"type": [
				"string",
				"null"
			],
			"minLength": 1
		},
		"street_type": {
			"type": [
				"string",
				"null"
			],
			"enum": [
				"Street",
				"Avenue",
				"Boulevard",
				null
			]
		},
		"city_name": {
			"type": [
				"string",
				"null"
			],
			"minLength": 1
		},
		"city_type": {
			"type": [
				"string",
				"null"
			],
			"enum": [
				"Big",
				"Small",
				null
			]
		}
	}
}

Onderstaand JSON voorbeeld valideert prima tegen bovenstaand schema.

{
	"street_name": null,
	"street_type": null,
	"city_name": "A"
}

Zie XMLSpy voor het bewijs:

afbeelding

@HenriKorver
Copy link
Collaborator

HenriKorver commented May 18, 2022

@HenriKorver opperde nog een uitzoek-actie (die hij gaat uitvoeren) op de ZGW-API's omtrent het gebruik van nillable en lege strings versus het (waarschijnlijk onterecht) afwezig zijn van minlength, enumeration of patterns. Daarbij is de vraag of de API meer ruimte toelaat dan functioneel wenselijk is.

Hieronder een random zaak die ik heb opgevraagd vanuit de referentie-implementatie van de Zaken API met Postman. Interessant om te kijken naar de diverse vormen van lege waarden:

  • null (lege waarde)
  • "" (lege string)
  • [] (lege array)
{
            "url": "https://zaken-api.vng.cloud/api/v1/zaken/58d7425e-9baa-4d47-90dd-19e9bc3914ba",
            "uuid": "58d7425e-9baa-4d47-90dd-19e9bc3914ba",
            "identificatie": "ZAAK-2019-0000001813",
            "bronorganisatie": "000000000",
            "omschrijving": "string",
            "toelichting": "string",
            "zaaktype": "https://catalogi-api.vng.cloud/api/v1/zaaktypen/f2cc91ef-c241-4516-afef-c0abf257eb3a",
            "registratiedatum": "2019-04-09",
            "verantwoordelijkeOrganisatie": "000000000",
            "startdatum": "2019-04-09",
            "einddatum": null,
            "einddatumGepland": "2019-04-20",
            "uiterlijkeEinddatumAfdoening": "2019-04-09",
            "publicatiedatum": "2019-04-09",
            "communicatiekanaal": "",
            "productenOfDiensten": [],
            "vertrouwelijkheidaanduiding": "openbaar",
            "betalingsindicatie": "geheel",
            "betalingsindicatieWeergave": "De met de zaak gemoeide kosten zijn geheel betaald.",
            "laatsteBetaaldatum": null,
            "zaakgeometrie": {
                "type": "Point",
                "coordinates": [
                    53.0,
                    5.0
                ]
            },
            "verlenging": {
                "reden": "",
                "duur": null
            },
            "opschorting": {
                "indicatie": true,
                "reden": "string"
            },
            "selectielijstklasse": "",
            "hoofdzaak": null,
            "deelzaken": [],
            "relevanteAndereZaken": [],
            "eigenschappen": [],
            "status": null,
            "kenmerken": [],
            "archiefnominatie": null,
            "archiefstatus": "nog_te_archiveren",
            "archiefactiedatum": null,
            "resultaat": null,
            "opdrachtgevendeOrganisatie": ""
        }

Observaties:

  1. De attributen "opdrachtgevendeOrganisatie" en "communicatiekanaal" hebben een lege string in plaats van een null-waarde. Dit kan omdat er geen minLength is gedefinieerd.
  2. Het attribuut "deelzaak" heeft een lege array [] in plaats van null. Lijkt me de juiste keuze (in geval je lege attributen wilt meegegeven in je respons).
  3. Het attribuut "verlenging" is interessant. Deze bevat een een genest object met twee lege attributen.
  4. Het attribuut "selectielijstklasse" is een uri maar heeft een lege string. Dit is niet consistent met "hoofdzaak" dat ook een uri is, maar null als lege waarde heeft. Ook vreemd dat de één een maxLength van 1000 heeft en de ander niet. Bovendien zou ik een minLength van minimaal 1 verwachten. Hoog tijd dus om de OAS-definitie van uri's te standaardiseren!
    (Zie ook: Wat is de maxLength van een URL in een OAS-specificatie? Geonovum/KP-APIs#261.)

afbeelding

@JohanBoer JohanBoer assigned JohanBoer and unassigned HenriKorver May 23, 2022
@melsk-r
Copy link
Contributor Author

melsk-r commented May 24, 2022

Tijdens de bespreking kwamen we tot het in mijn ogen elegante compromis.
In plaats van het weglaten van een minLength of pattern wordt er (indien gewenst) op optionele velden een nillable property gedefinieerd. Daarnaast kan er op een get operatie een parameter worden gedefinieerd waarmee een developer aan kan geven dat hij in de response ook de velden met een null waarde terug wil krijgen.

Beiden leiden tot de volgende nieuwe Design Rules:

  • Een berichtdesigner mag een parameter toevoegen waarmee een developer er voor kan kiezen om n.a.v. een get ook alle velden met de waarde null terug te ontvangen.
  • Indien een veld geen waarde heeft dan wordt deze niet als lege waarde geleverd maar als een null waarde.

Over de wijze waarop lege arrays moeten worden uitgedrukt is nog geen duidelijkheid, dat moet nog bediscussieerd worden.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

7 participants