SchemaSafe Blog
Almindelige fejl ved oprettelse af JSON Schema
JSON Schema, aktuelt Udkast 2020-12, er den standardmæssige måde at beskrive og validerer JSON-form på. De fleste ødelagte schemata er ikke syntaksfejl; de er tilladte fejl, der godkender ugyldige data. De fire, der kommer frem mest under kodereview, er en manglende påkrævet array, en åben additionalProperties, misbrugt type-unions og en $ref, der peger ingen steder hen.
Glemmer det påkrævede array
Når du tilføjer en egenskab under properties, beskriver du kun dets form, ikke dens påkrævenhed. Hvis det påkrævede array udelader denne nøgle, validerer en instans uden feltet succesfuldt. Dette er en stille godkendelse, fordi validereren behandler egenskaben som valgfri. Jeg har set hold skibe APIs, hvor en kritisk identifikator manglede fra det påkrævede array, hvilket førte til downstream null-peger-fejl, der kun opstod i produktion.
For eksempel en brugerskema, der forventer en id, skal indeholde:
{ "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" } }, "required": ["id"] } Uden linjen med required, ville et objekt med kun {"name":"Ada"} være gyldigt, selvom API'et senere behandler id som påkrævet.
Ladelse af additionalProperties åben
Standardværdien af additionalProperties er sandt. Dette giver mulighed for, at enhver nøgle, der ikke er defineret i properties, kan slippe igennem valideringen. En tastefejl som f.eks. "user_name" i stedet for "username" bliver således en stille accepteret felt, der forurener datamodellen og gør senere migrationer sværere. Jeg har set hold bruge uger på at rydde op i vilde nøgler, der er kommet ind i databasen, fordi skemaet aldrig afviste dem.
Her er en streng version af et produktskema:
{ "type": "object", "properties": { "sku": { "type": "string" }, "price": { "type": "number", "minimum": 0 } }, "required": ["sku","price"], "additionalProperties": falsk } Med dette skema mislykkes valideringen af en instans, der indeholder {"sku":"ABC","price":10,"extra":1}, og opfangning af tastefejlen sker tidligt.
Misbrug af typeunioner
Type-nøgleordet forventer enten en streng eller en array af streng. At skrive "type": "string, number" er ugyldig JSON-skema; parseren behandler hele værdien som en enkelt ukendt type, som mange valideringer stille ignorerer, hvilket tillader enhver værdi at gå igennem. En anden almindelig fejl er at udelade typen helt for et valgfrit felt, hvilket får validereren til at springe typekontrollen for den nøgle over.
Eksempel på et nullable dato-felt:
{ "type": "object", "properties": { "issuedAt": { "type": ["string","null"], "format": "date-time" } }, "required": ["issuedAt"] } Her er null tilladt, så {"issuedAt":null} passerer, mens {"issuedAt":"not-a-date"} fejler.
$ref fælder og versionsdrift
En $ref, der opløser til en manglende placering, får hele skemaet til at fejle under indlæsningstid, hvilket er støjende og let at spotte. Det stille problem er en reference, der opløser, men peger på den forkerte definition, fordi udviklingsversionen ændrede sig eller mappenstrukturen skiftede. I Udkast 2020-12 flyttede nøgleordet for genbrugbare blokke fra definitioner til $defs. Hvis du beholder den gamle nøgle, validerer skemaet stadig (det ældre nøgleord ignoreres), men du mister evnen til at genbruge definitioner, hvilket fører til duplikeret kode og drift.
Eksempel på en korrekt reference:
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$defs": { "address": { "type": "object", "properties": { "street": { "type": "string" }, "city": { "type": "string" } }, "required": ["street","city"] } }, "type": "object", "properties": { "billing": { "$ref": "#/$defs/address" }, "shipping": { "$ref": "#/$defs/address" } }, "required": ["billing","shipping"] } Hvis du ved en fejl skrev "$ref": "#/definitions/address" ville referencen opløse til undefined, og valideren ville kaste en fejl, hvilket ville advare dig om misforholdet.
Valider med eksempler før publicering
Den billigste tillidscheck er at køre en håndfuld repræsentative JSON-eksempler gennem valideringsværktøjet, før du behandler skemaet som en kontrakt. Et godt testset indeholder mindst ét gyldigt eksempel, der matcher den ønskede brug, og ét ugyldigt eksempel, der bevidst bryder hver regel, du er interesseret i. Hvis skemaet accepterer det gode eksempel og afviser det dårlige, har du bevis for, at det ikke er for tilladt. Jeg har set hold springe over dette trin og senere opdage, at et manglende krævet tilladt ordrer uden produkt-ID'er slipper igennem og forårsager leveringsfejl.
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" }; // manglende id const validate = ajv.compile(schema); console.log('Gyldigt eksempel:', validate(good) ? 'pass' : 'fail'); if (!validate(good)) console.error(validate.errors); console.log('Ugyldigt eksempel:', validate(bad) ? 'pass' : 'fail'); if (validate(bad)) console.error('Uventet accepterede dårligt eksempel'); Kørsel af dette i CI sikrer, at en tilladt fejl aldrig når produktion.
Hvad dette ikke er
Denne vejledning lover ikke, at efterlevelse af disse punkter vil gøre dit schema immun over for enhver mulig fejl. JSON Schema er et fleksibelt sprog, og nye fælder kan opstå, når du udvider det med brugerdefinerede nøgleord eller kombinerer det med andre værktøjer som OpenAPI. Jeg hævder ikke, at de fire fejl, der er nævnt, er de eneste, der har betydning; de er blot dem, der viser sig hyppigst i de kodegennemgange, jeg har set. Råden her er baseret på min erfaring med at vedligeholde SchemaSafe og på offentligt tilgængelige specifikationer; det er ikke en erstatning for at læse den officielle specifikation eller for at køre dine egne valideringstests.
Referencer
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
Ofte stillede spørgsmål
At erklære en egenskab i properties gør den ikke nødvendig. Du skal liste den i required-arrayet. Arrayet er et søskendeelement til properties, ikke nestede inde i det.
Det standardiserer til sand, så ukendte nøgler passerer. Angiv additionalProperties: false, hvor strengthed er vigtig, eller begræns det med et schema for udvidelsesfelter. Åbne schemer lader trykfejl passere stille.
Udelad det fra required og inkluder "null" i dens typearray, f.eks. ["string", "null"] . At skrive en kommaadskilt typestreng er ugyldigt og kan annullere begrænsningen.
Under $defs . Den ældre definitions-nøgle virker stadig, men markerer en gammel udgave. Pind altid $schema, så validatoreren anvender den udgave, du havde til hensigt.
Prøv produktet: SchemaSafe
2026-09-16 · kun primærkilder · ingen fabrikerede trafikmålinger
Relaterede artikler
JSON Schema-validering uden LLM (2026)
Udforsk det fulde AI micro-SaaS emne-matrix →
Hvorfor accepterer mit schema manglende felter?
At erklære en egenskab i properties gør den ikke nødvendig. Du skal liste den i required-arrayet. Arrayet er en søskendeelement til properties, ikke indlejret i det.
Hvad gør additionalProperties som standard?
Det standardiserer til sand, så ukendte nøgler passerer. Angiv additionalProperties: falsk, hvor strengthed er vigtig, eller begræns det med et schema til udvidelsesfelter. Åbne schemer lader trykfejl glide igennem stille.
Hvordan markerer jeg et felt som valgfrit i JSON Schema?
Udelad det fra required og inkluder
Hvor placerer jeg genbrugelige definitioner i Draft 2020-12?
Under $defs. Den ældre definitions-nøgle virker stadig, men markerer en gammel udgave. Pind altid $schema, så validatoreren anvender den udgave, du havde til hensigt.
Kun til beslutningsstøtte. Er ikke en erstatning for formel schemagennemgang eller certificerede revisioner.