Blog SchemaSafe
Errori comuni di authoring dello schema JSON
JSON Schema, attualmente Draft 2020-12, è il modo standard per descrivere e convalidare la forma JSON. La maggior parte degli schemi danneggiati non sono errori di sintassi; sono errori permissivi che passano dati non validi. I quattro che si presentano più frequentemente nella revisione del codice sono una matrice richiesta mancante, proprietà aggiuntive aperte, unioni di tipo mal utilizzate e un $ref che punta nel nulla.
Dimenticare l'array richiesto
Quando aggiungi una proprietà sotto properties, stai solo descrivendo la sua forma, non richiedendone la presenza. Se l'array richiesto omette quella chiave, un'istanza senza il campo si valida con successo. Questo è un passaggio silenzioso perché il validator trata la proprietà come opzionale. Ho visto team rilasciare API dove un identificatore critico era mancante da required, portando a errori di null-pointer a valle che apparivano solo in produzione.
Ad esempio, uno schema utente che si aspetta un id dovrebbe contenere:
{ "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" } }, "required": ["id"] } Senza la riga richiesta, un oggetto con solo {"name":"Ada"} passerebbe, anche se l'API successivamente tratta id come obbligatorio.
Lasciare additionalProperties aperto
Il valore predefinito di additionalProperties è true. Ciò consente a qualsiasi chiave non definita in properties di superare la convalida. Un errore di battitura come "user_name" al posto di "username" diventa quindi un campo accettato in silenzio, inquinando il modello di dati e rendendo più difficili le migrazioni successive. Ho visto team trascorrere settimane per pulire chiavi vaganti che sono entrate nel database perché lo schema non le ha mai rifiutate.
Ecco una versione rigorosa di uno schema di prodotto:
{ "type": "object", "properties": { "sku": { "type": "string" }, "price": { "type": "number", "minimum": 0 } }, "required": ["sku","price"], "additionalProperties": false } Con questo schema, un'istanza contenente {"sku":"ABC","price":10,"extra":1} non supera la convalida, rilevando l'errore di battitura precocemente.
Uso improprio delle unioni di tipo
La parola chiave type si aspetta una stringa o un array di stringhe. Scrivere "type": "string, number" è uno schema JSON non valido; il parser considera l'intero valore come un singolo tipo sconosciuto, che molti validatori ignorano silenziosamente, consentendo a qualsiasi valore di passare. Un altro errore comune è l'omissione del tipo per un campo opzionale, il che fa sì che il validatore salta il controllo del tipo per quella chiave.
Esempio di un campo data nullable:
{ "type": "object", "properties": { "issuedAt": { "type": ["string","null"], "format": "date-time" } }, "required": ["issuedAt"] } Qui il valore null è consentito, quindi {"issuedAt":null} passa, mentre {"issuedAt":"not-a-date"} fallisce.
Trappole di $ref e deriva di versione
Un $ref che si risolve in una posizione mancante causa il fallimento dell'intero schema al momento del caricamento, il che è rumoroso e facile da rilevare. Il problema più silenzioso è un riferimento che si risolve ma punta alla definizione sbagliata perché la versione di bozza è cambiata o la struttura delle cartelle è stata spostata. Nella bozza 2020-12, la parola chiave per i blocchi riutilizzabili si è spostata da definitions a $defs. Se si mantiene la vecchia chiave, lo schema continua a validare (la parola chiave più vecchia viene ignorata) ma si perde la capacità di riutilizzare le definizioni, portando a codice duplicato e deriva.
Esempio di riferimento corretto:
{ "$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"] } Se per errore si scrive "$ref": "#/definitions/address" il riferimento si risolverebbe in undefined e il validator lancerebbe un errore, allertandoti alla discordanza.
Convalida con campioni prima della pubblicazione
Il controllo di confidenza più economico è eseguire una manciata di istanze JSON rappresentative attraverso il validator prima di considerare lo schema come un contratto. Una buona suite di test contiene almeno un esempio valido che corrisponde all'uso previsto e un esempio non valido che intenzionalmente viola ogni regola di cui ci si preoccupa. Se lo schema accetta il campione buono e rifiuta quello cattivo, si ha la prova che non è eccessivamente permissivo. Ho visto team saltare questo passaggio e scoprire successivamente che un requisito mancante ha permesso ordini senza ID di prodotto di passare, causando errori di evasione.
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" }; // missing id const validate = ajv.compile(schema); console.log('Campionamento buono:', validate(good) ? 'pass' : 'fail'); if (!validate(good)) console.error(validate.errors); console.log('Campionamento cattivo:', validate(bad) ? 'pass' : 'fail'); if (validate(bad)) console.error('Campione cattivo accettato inaspettatamente'); Eseguire questo in CI garantisce che un errore permissivo non raggiunga mai la produzione.
Cosa questo non è
Questa guida non promette che seguire questi punti renderà il tuo schema immune a ogni possibile errore. JSON Schema è un linguaggio flessibile e nuove insidie possono apparire quando lo estendi con parole chiave personalizzate o lo combini con altri strumenti come OpenAPI. Non sto affermando che i quattro errori elencati siano gli unici che contano; sono semplicemente quelli che appaiono più frequentemente nelle revisioni del codice che ho visto. I consigli qui presentati si basano sulla mia esperienza di manutenzione di SchemaSafe e sulle specifiche pubblicamente disponibili; non sono un sostituto della lettura della specifica ufficiale o dell'esecuzione dei propri test di convalida.
Riferimenti
https://ajv.js.org/json-schema.html
https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
https://json-schema.org
https://json-schema.org/draft/2020-12/json-schema-core.html
Domande frequenti
Dichiarare una proprietà in properties non la rende obbligatoria. È necessario elencarla nell'array required. L'array è un fratello di properties, non annidato all'interno di esso.
Di default è true, quindi le chiavi sconosciute vengono superate. Impostare additionalProperties: false dove è necessaria la rigidità, o limitarlo con uno schema per i campi di estensione. Gli schemi aperti lasciano passare i refusi in silenzio.
Ometterlo da required e includere "null" nel suo array di tipo, ad esempio ["string", "null"] . Scrivere una stringa di tipo separata da virgole è invalido e può annullare il vincolo.
Sotto $defs . La chiave definitions più vecchia funziona ancora, ma segna uno schema obsoleto. Assicurarsi sempre di bloccare $schema in modo che il validator applichi lo schema che si desidera.
Prova il prodotto: SchemaSafe
2026-09-16 · solo fonti primarie · nessuna metrica di traffico fabbricata
Articoli correlati
Convalida dello schema JSON senza un LLM (2026)
Esplora la matrice completa dei temi di AI micro-SaaS →
Perché il mio schema accetta campi mancanti?
Dichiarare una proprietà in properties non la rende obbligatoria. Devi elencarla nell'array required. L'array è un fratello di properties, non annidato al suo interno.
Cosa fa additionalProperties per impostazione predefinita?
Di default è true, quindi le chiavi sconosciute vengono accettate. Imposta additionalProperties: false dove è necessaria la rigidità, o limitalo con uno schema per i campi di estensione. Gli schemi aperti lasciano passare i refusi in silenzio.
Come posso contrassegnare un campo come opzionale in JSON Schema?
Omettilo da required e includi
Dove vanno le definizioni riutilizzabili in Draft 2020-12?
Sotto $defs. La chiave definitions più vecchia funziona ancora, ma segna un vecchio draft. Assicurati sempre di fissare $schema in modo che il validator applichi il draft che intendevi.
Solo per supporto decisionale. Non sostituisce la revisione formale dello schema o i controlli certificati.