SchemaSafe Blog

Gangbare fouten bij het maken van JSON Schema's

JSON Schema, momenteel Draft 2020-12, is de standaardmanier om de vorm van JSON te beschrijven en te valideren. De meeste kapotte schema's bevatten geen syntaxisfouten; het zijn permissieve fouten die ongeldige gegevens doorlaten. De vier fouten die het meest naar voren komen bij codebeoordeling zijn een ontbrekend vereist array, een open additionalProperties, verkeerd gebruikte type-unies en een $ref die nergens naar verwijst.

Het vergeten van het vereiste array

Wanneer u een eigenschap toevoegt onder properties, beschrijft u alleen de vorm ervan, maar niet de verplichting ervan. Als het vereiste array die sleutel overslaat, wordt een instantie zonder het veld erfolgreich gevalideerd. Dit is een stille doorgang omdat de validator de eigenschap als optioneel behandelt. Ik heb teams gezien die APIs hebben uitgebracht waarin een kritieke identifier ontbrak in required, wat leidde tot downstream null-pointerfouten die alleen in productie verschenen.

Bijvoorbeeld, een gebruikersschema dat een id verwacht, zou moeten bevatten:

{ "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" } }, "required": ["id"] } Zonder de regel required, zou een object met alleen {"name":"Ada"} slagen, ook al behandelt de API id later als verplicht.

AdditionalProperties open laten

De standaardwaarde van additionalProperties is true. Dit laat elke sleutel die niet is gedefinieerd in properties door de validatie heen glippen. Een typefout zoals "user_name" in plaats van "username" wordt dan een stilzwijgend geaccepteerd veld, waardoor het datamodel wordt verontreinigd en latere migraties moeilijker worden. Ik heb teams zien worstelen met het schoonmaken van verdwaalde sleutels die in de database terecht zijn gekomen omdat het schema ze nooit heeft afgewezen.

Hier is een strikte versie van een productschema:

{ "type": "object", "properties": { "sku": { "type": "string" }, "price": { "type": "number", "minimum": 0 } }, "required": ["sku","price"], "additionalProperties": false } Met dit schema mislukt de validatie van een instantie met {"sku":"ABC","price":10,"extra":1}, waardoor de typefout vroegtijdig wordt opgevangen.

Het verkeerd gebruiken van type-unies

Het type-sleutelwoord verwacht een string of een array van strings. Het schrijven van "type": "string, number" is ongeldig JSON Schema; de parser behandelt de hele waarde als een enkele onbekende type, die veel validators stilzwijgend negeren, waardoor elke waarde kan worden doorgegeven. Een andere veelvoorkomende fout is het weglaten van het type geheel voor een optioneel veld, waardoor de validator het typecontrole voor die sleutel overslaat.

Voorbeeld van een nullable datumveld:

{ "type": "object", "properties": { "issuedAt": { "type": ["string","null"], "format": "date-time" } }, "required": ["issuedAt"] } Hier is null toegestaan, dus {"issuedAt":null} wordt goedgekeurd, terwijl {"issuedAt":"not-a-date"} faalt.

$ref-valstrikken en versiedrift

Een $ref die verwijst naar een ontbrekende locatie veroorzaakt dat het hele schema mislukt bij het laden, wat luidruchtig is en gemakkelijk te herkennen. Het stillere probleem is een verwijzing die wel wordt opgelost, maar naar de verkeerde definitie wijst omdat de conceptversie is gewijzigd of de mapstructuur is verschoven. In Concept 2020-12 is het trefwoord voor herbruikbare blokken verplaatst van definities naar $defs. Als u de oude sleutel behoudt, blijft het schema geldig (het oudere trefwoord wordt genegeerd), maar u verliest de mogelijkheid om definities opnieuw te gebruiken, waardoor gedupliceerde code en drift ontstaan.

Voorbeeld van een correcte verwijzing:

{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "adres": { "type": "object", "properties": { "straat": { "type": "string" }, "stad": { "type": "string" } }, "required": ["straat","stad"] } }, "type": "object", "properties": { "facturatie": { "$ref": "#/$defs/adres" }, "verzending": { "$ref": "#/$defs/adres" } }, "required": ["facturatie","verzending"] } Als u per ongeluk "$ref": "#/definities/adres" schreef, zou de verwijzing worden opgelost naar ongedefinieerd en zou de validator een fout gooien, waardoor u wordt gewaarschuwd voor de mismatch.

Valideer met voorbeelden voordat u publiceert

De goedkoopste manier om vertrouwen te krijgen is om een handvol representatieve JSON-instanties door de validator te halen voordat u de schema behandelt als een contract. Een goede testsuite bevat minstens één geldig voorbeeld dat overeenkomt met het beoogde gebruik en één ongeldig voorbeeld dat elk gewenst regel opzettelijk breekt. Als de schema het goede voorbeeld accepteert en het slechte afwijst, heeft u bewijs dat deze niet te permissief is. Ik heb teams gezien die deze stap overslaan en later ontdekken dat een ontbrekende vereiste toestond dat bestellingen zonder product-ID's erdoorheen glipten, waardoor er bezorgfouten ontstonden.

const Ajv = require('ajv'); const ajv = new Ajv({allErrors: true}); const schema = require('./user-schema.json'); const good = { "id": "123", "name": "Ada" }; const bad = { "name": "Ada" }; // ontbrekend id const validate = ajv.compile(schema); console.log('Goed voorbeeld:', validate(good) ? 'pass' : 'fail'); if (!validate(good)) console.error(validate.errors); console.log('Slecht voorbeeld:', validate(bad) ? 'pass' : 'fail'); if (validate(bad)) console.error('Ongewild goedkeuring van slecht voorbeeld'); Het uitvoeren van deze code in CI zorgt ervoor dat een permissieve fout nooit de productie bereikt.

Wat dit niet is

Deze gids belooft niet dat het volgen van deze punten uw schema immuun maakt voor elke mogelijke fout. JSON Schema is een flexibele taal en nieuwe valkuilen kunnen verschijnen wanneer u deze uitbreidt met aangepaste trefwoorden of combineert met andere tools zoals OpenAPI. Ik beweer niet dat de vier fouten die hier zijn opgesomd de enige zijn die ertoe doen; ze zijn eenvoudigweg degenen die het vaakst voorkomen in de code-reviews die ik heb gezien. Het advies hier is gebaseerd op mijn ervaring met het onderhouden van SchemaSafe en op openbaar beschikbare specificaties; het is geen vervanging voor het lezen van de officiële specificatie of voor het uitvoeren van uw eigen validatietests.

Referenties

https://ajv.js.org/json-schema.html

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse

https://json-schema.org

https://json-schema.org/draft/2020-12/json-schema-core.html

Veelgestelde vragen

Het declareren van een eigenschap in properties maakt deze niet verplicht. U moet deze opnemen in het verplichte array. Het array is een broer of zus van properties, niet genest binnenin.

Het staat standaard op true, dus onbekende sleutels worden doorgegeven. Stel additionalProperties: false in waar striktheid belangrijk is, of beperk deze met een schema voor uitbreidingsvelden. Open schema's laten typos stilzwijgend door.

Laat deze weg uit verplicht en voeg "null" toe aan het type-array, bijvoorbeeld ["string", "null"]. Het schrijven van een komma-gescheiden type-tekenreeks is ongeldig en kan de beperking tenietdoen.

Onder $defs. De oudere definities-sleutel werkt nog steeds, maar markeert een oude concept-versie. Zorg er altijd voor dat $schema vastgezet is, zodat de validator de concept-versie toepast die u bedoelde.

Probeer het product: SchemaSafe

2026-09-16 · alleen primaire bronnen · geen gefabriceerde verkeersmetrieken

Gerelateerde artikelen

JSON Schema-validatie zonder een LLM (2026)

Verken de volledige AI micro-SaaS onderwerpmatrix →

Waarom accepteert mijn schema ontbrekende velden?

Het verklaren van een eigenschap in properties maakt deze niet verplicht. U moet deze opnemen in het vereiste array. Het array is een broer of zus van properties, niet genest binnenin.

Wat doet additionalProperties standaard?

Het staat standaard op true, dus onbekende sleutels worden doorgegeven. Stel additionalProperties: false in waar striktheid belangrijk is, of beperk het met een schema voor extensievelden. Open schema's laten typfouten stil door.

Hoe markeer ik een veld als optioneel in JSON Schema?

Laat het weg uit vereiste en voeg \ toe

Waar gaan herbruikbare definities in Draft 2020-12?

Onder $defs. De oudere definitions-sleutel werkt nog steeds, maar markeert een oude versie. Zorg ervoor dat u altijd $schema vastzet, zodat de validator de versie toepast die u bedoelde.

Alleen voor besluitsondersteuning. Vervangt geen formele schemabeoordeling of gecertificeerde audits.

← Terug naar blog

Was dit resultaat nuttig?Feedback