ToolHub
View All Posts

Guida alla validazione JSON Schema: convalida le tue strutture dati

Ogni applicazione che riceve dati da fonti esterne affronta lo stesso problema fondamentale: posso fidarmi di questi dati? Che si tratti di corpi di richieste API, file di configurazione, messaggi in coda o importazioni di dati, i dati non attendibili devono essere convalidati prima di entrare nel sistema. JSON Schema fornisce un modo standardizzato e indipendente dal linguaggio per definire l'aspetto dei dati validi e convalidare i dati in entrata rispetto a quella definizione. Questa guida copre tutto, dalla scrittura del primo Schema ai pattern avanzati per validazioni complesse, con esempi pratici che puoi applicare immediatamente.

Cos'è JSON Schema?

JSON Schema è un documento JSON che descrive la struttura e i vincoli di altri documenti JSON. È un vocabolario che ti consente di annotare e convalidare dati JSON, standardizzato dall'Internet Engineering Task Force (IETF). JSON Schema definisce regole su quali campi devono esistere, di che tipo devono essere, quali valori sono accettabili e come dovrebbero essere strutturati oggetti e array.

Pensa a JSON Schema come al contratto dei tuoi dati. Proprio come uno schema di database definisce le colonne, i tipi e i vincoli delle tabelle, JSON Schema definisce le proprietà, i tipi e i vincoli dei documenti JSON. Qualsiasi dato JSON che soddisfa tutti i vincoli nello Schema è chiamato istanza valida, mentre i dati che violano qualsiasi vincolo sono non validi.

Cosa non è JSON Schema

Versioni di JSON Schema

JSON Schema si è evoluto attraverso diverse bozze, ognuna delle quali ha aggiunto funzionalità e perfezionato il vocabolario. Comprendere le versioni ti aiuta a scegliere quella giusta per il tuo progetto ed evitare problemi di compatibilità.

VersioneURI $schemaStatoFunzionalità principali
Draft 2020-12https://json-schema.org/draft/2020-12/schemaVersione correnteprefixItems, dynamicRef, supporto vocabolario
Draft 2019-09https://json-schema.org/draft/2019-09/schemaStabileunevaluatedProperties, $recursiveRef
Draft 7http://json-schema.org/draft-07/schema#Ampiamente supportatoif/then/else, contentEncoding
Draft 6http://json-schema.org/draft-06/schema#LegacypropertyNames, contains
Draft 4http://json-schema.org/draft-04/schema#DeprecatoPrima versione ampiamente adottata
Raccomandazione: Usa Draft 2020-12 per i nuovi progetti. È la versione stabile più recente con il maggior numero di funzionalità, supportata dai principali validatori. Se hai bisogno della massima compatibilità con strumenti esistenti, Draft 7 è una scelta sicura. Evita Draft 4 e versioni precedenti.

Scrivere il tuo primo Schema

Cominciamo con un semplice esempio: uno Schema per un oggetto utente con nome, email ed età.

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://example.com/schemas/user.json",
    "title": "User",
    "description": "A user account in the system",
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "The user's full name"
        },
        "email": {
            "type": "string",
            "format": "email",
            "description": "The user's email address"
        },
        "age": {
            "type": "integer",
            "minimum": 0,
            "maximum": 150,
            "description": "The user's age in years"
        }
    },
    "required": ["name", "email"],
    "additionalProperties": false
}

Questo Schema dichiara che un utente valido deve essere un oggetto con name e email come proprietà stringa obbligatorie. La proprietà age è opzionale ma se presente deve essere un intero tra 0 e 150. Il vincolo additionalProperties: false impedisce qualsiasi proprietà non definita nello Schema, il che può catturare errori di battitura e campi imprevisti.

Riferimento alle parole chiave principali

JSON Schema fornisce un ricco vocabolario di parole chiave per definire i vincoli. Ecco le parole chiave più importanti, organizzate per categoria.

Parola chiave type

Parola chiaveDescrizioneEsempio
typeTipo di dato previsto"type": "string" o "type": ["string", "null"]
enumElenco di valori consentiti"enum": ["active", "inactive", "pending"]
constDeve essere uguale a questo valore esatto"const": "v2"

Vincoli numerici

Parola chiaveDescrizioneEsempio
minimumValore minimo (incluso)"minimum": 0
exclusiveMinimumValore minimo (escluso)"exclusiveMinimum": 0
maximumValore massimo (incluso)"maximum": 100
exclusiveMaximumValore massimo (escluso)"exclusiveMaximum": 100
multipleOfDeve essere un multiplo di questo valore"multipleOf": 0.01

Vincoli sulle stringhe

Parola chiaveDescrizioneEsempio
minLengthLunghezza minima della stringa"minLength": 1
maxLengthLunghezza massima della stringa"maxLength": 255
patternEspressione regolare a cui la stringa deve corrispondere"pattern": "^[A-Z]{2}\\d{4}$"
formatFormato semantico (email, uri, date-time, ecc.)"format": "email"

Vincoli sugli oggetti

Parola chiaveDescrizioneEsempio
propertiesSchema per ogni proprietà conosciuta"properties": {"name": {"type": "string"}}
requiredElenco delle proprietà obbligatorie"required": ["name", "email"]
additionalPropertiesSe sono consentite proprietà aggiuntive"additionalProperties": false
minPropertiesNumero minimo di proprietà"minProperties": 1
maxPropertiesNumero massimo di proprietà"maxProperties": 10
patternPropertiesSchema per proprietà che corrispondono a una regex"patternProperties": {"^S_": {"type": "string"}}

Vincoli sugli array

Parola chiaveDescrizioneEsempio
itemsSchema per tutti gli elementi dell'array"items": {"type": "string"}
prefixItemsSchema per elementi posizionali (Draft 2020-12)"prefixItems": [{"type": "string"}, {"type": "number"}]
minItemsNumero minimo di elementi"minItems": 1
maxItemsNumero massimo di elementi"maxItems": 100
uniqueItemsTutti gli elementi devono essere unici"uniqueItems": true

Pattern comuni di Schema

Gli Schema del mondo reale spesso richiedono pattern che vanno oltre il semplice controllo dei tipi. Ecco i pattern più comunemente utilizzati.

Validazione condizionale con if/then/else

Usa la logica condizionale per applicare vincoli diversi in base ai valori delle proprietà. Ad esempio, un oggetto pagamento richiede campi diversi a seconda del metodo di pagamento.

{
    "type": "object",
    "properties": {
        "method": { "enum": ["credit_card", "bank_transfer"] },
        "card_number": { "type": "string" },
        "routing_number": { "type": "string" }
    },
    "required": ["method"],
    "if": {
        "properties": { "method": { "const": "credit_card" } }
    },
    "then": {
        "required": ["card_number"]
    },
    "else": {
        "required": ["routing_number"]
    }
}

Combinazione con allOf, anyOf, oneOf

Le parole chiave di composizione ti consentono di combinare Schema in modi potenti:

{
    "oneOf": [
        {
            "type": "object",
            "properties": {
                "type": { "const": "email" },
                "address": { "type": "string", "format": "email" }
            },
            "required": ["type", "address"]
        },
        {
            "type": "object",
            "properties": {
                "type": { "const": "phone" },
                "number": { "type": "string", "pattern": "^\\+?[1-9]\\d{1,14}$" }
            },
            "required": ["type", "number"]
        }
    ]
}

Riutilizzo di Schema con $ref

La parola chiave $ref ti consente di fare riferimento e riutilizzare Schema, eliminando la duplicazione e mantenendo gli Schema manutenibili. Puoi fare riferimento a Schema all'interno dello stesso documento o in file esterni.

{
    "$id": "https://example.com/schemas/order.json",
    "type": "object",
    "properties": {
        "customer": { "$ref": "#/$defs/address" },
        "shipping": { "$ref": "#/$defs/address" },
        "billing": { "$ref": "#/$defs/address" },
        "items": {
            "type": "array",
            "items": { "$ref": "#/$defs/lineItem" },
            "minItems": 1
        }
    },
    "required": ["customer", "items"],
    "$defs": {
        "address": {
            "type": "object",
            "properties": {
                "street": { "type": "string" },
                "city": { "type": "string" },
                "zip": { "type": "string", "pattern": "^\\d{5}(-\\d{4})?$" },
                "country": { "type": "string", "minLength": 2, "maxLength": 2 }
            },
            "required": ["street", "city", "zip", "country"]
        },
        "lineItem": {
            "type": "object",
            "properties": {
                "product": { "type": "string" },
                "quantity": { "type": "integer", "minimum": 1 },
                "price": { "type": "number", "exclusiveMinimum": 0 }
            },
            "required": ["product", "quantity", "price"]
        }
    }
}

Tipi nullable

In JSON Schema Draft 2020-12, i tipi nullable sono rappresentati utilizzando un array di tipi che include "null":

{
    "type": ["string", "null"],
    "description": "An optional display name, or null if not set"
}

Nelle bozze precedenti, la specifica OpenAPI utilizzava la parola chiave nullable: true. Per JSON Schema standard, usa sempre l'approccio con array di tipi.

Validazione del formato

La parola chiave format fornisce una validazione semantica oltre il controllo strutturale. Specifica che una stringa deve essere conforme a un formato ben noto. I formati comunemente supportati includono:

FormatoDescrizioneEsempio
emailIndirizzo emailuser@example.com
uriURI validohttps://example.com/path
uri-referenceURI o riferimento relativo/path/to/resource
date-timeData e ora ISO 86012026-05-19T14:30:00Z
dateData ISO 86012026-05-19
timeOra ISO 860114:30:00Z
ipv4Indirizzo IPv4192.168.1.1
ipv6Indirizzo IPv6::1
uuidIdentificatore univoco universale550e8400-e29b-41d4-a716-446655440000
hostnameNome host Internetwww.example.com
Nota importante: Per impostazione predefinita, la parola chiave format è un'annotazione, non un vincolo. I validatori potrebbero ignorarla a meno che tu non abiliti esplicitamente la validazione del formato. In Ajv, passa { strict: true } o { validateFormats: true } per applicare i controlli di formato. Verifica sempre che il tuo validatore applichi i vincoli di formato.

Validare dati JSON a livello di codice

La validazione Schema è più utile quando integrata nel codice dell'applicazione. Ecco esempi che utilizzano librerie popolari in diversi linguaggi.

JavaScript con Ajv

Ajv è il validatore JSON Schema più utilizzato in JavaScript. Supporta tutte le versioni delle bozze e offre prestazioni eccellenti grazie alla compilazione JIT degli Schema.

import Ajv from 'ajv';
import addFormats from 'ajv-formats';

const ajv = new Ajv();
addFormats(ajv);

const schema = {
    type: 'object',
    properties: {
        name: { type: 'string', minLength: 1 },
        email: { type: 'string', format: 'email' },
        age: { type: 'integer', minimum: 0 }
    },
    required: ['name', 'email'],
    additionalProperties: false
};

const validate = ajv.compile(schema);
const valid = validate({ name: 'Alice', email: 'alice@example.com', age: 30 });

if (!valid) {
    console.log(validate.errors);
    // [{ keyword: 'required', params: { missingProperty: 'email' }, ... }]
}

Python con jsonschema

from jsonschema import validate, ValidationError

schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string", "minLength": 1},
        "email": {"type": "string", "format": "email"},
        "age": {"type": "integer", "minimum": 0}
    },
    "required": ["name", "email"],
    "additionalProperties": False
}

try:
    validate(instance={"name": "Alice", "email": "alice@example.com"}, schema=schema)
except ValidationError as e:
    print(f"Validation failed: {e.message}")

Validazione dati API con JSON Schema

Una delle applicazioni più preziose di JSON Schema è la validazione dei dati di richiesta e risposta delle API. Questo garantisce che la tua API riceva input ben formati e restituisca dati nel formato previsto, catturando gli errori precocemente e fornendo messaggi di errore chiari ai client.

Middleware Express.js

import Ajv from 'ajv';

const ajv = new Ajv({ allErrors: true });

function validateBody(schema) {
    const validate = ajv.compile(schema);
    return (req, res, next) => {
        if (!validate(req.body)) {
            return res.status(400).json({
                error: 'Validation failed',
                details: validate.errors
            });
        }
        next();
    };
}

app.post('/api/users',
    validateBody({
        type: 'object',
        properties: {
            name: { type: 'string', minLength: 1, maxLength: 100 },
            email: { type: 'string', format: 'email' },
            role: { enum: ['admin', 'editor', 'viewer'] }
        },
        required: ['name', 'email'],
        additionalProperties: false
    }),
    (req, res) => {
        // req.body is guaranteed valid here
        createUser(req.body);
    }
);

OpenAPI e JSON Schema

OpenAPI (precedentemente Swagger) utilizza un sottoinsieme di JSON Schema per definire gli Schema di richiesta e risposta delle API. Se stai già utilizzando OpenAPI, puoi estrarre gli Schema dalla specifica API e utilizzarli per la validazione a runtime. Strumenti come openapi-schema-validator e express-openapi-validator possono automatizzare questo processo, garantendo che la documentazione API e la logica di validazione rimangano sempre sincronizzate.

Migliori pratiche

Hai bisogno di validare dati JSON rispetto a uno Schema? Prova il nostro validatore JSON Schema online gratuito. Incolla il tuo Schema e i tuoi dati per ottenere risultati di validazione istantanei con messaggi di errore dettagliati.

Validatore JSON SchemaStrumento di formattazione JSON

Domande frequenti

Cos'è JSON Schema?

JSON Schema è un documento JSON che descrive la struttura e i vincoli di altri documenti JSON. Ti consente di definire campi obbligatori, tipi di dati previsti, intervalli di valori, pattern di stringhe e strutture di oggetti annidati. Puoi usarlo per convalidare dati in entrata, generare documentazione e creare automaticamente interfacce di moduli.

Quale versione di JSON Schema dovrei usare?

Usa JSON Schema Draft 2020-12 per i nuovi progetti. È l'ultima versione stabile, supportata dai principali validatori come Ajv. Se hai bisogno di compatibilità con strumenti più vecchi, Draft 7 è anch'esso ampiamente supportato. Evita Draft 4 e versioni precedenti, poiché utilizzano parole chiave obsolete e mancano di funzionalità moderne.

Qual è la differenza tra JSON Schema e le interfacce TypeScript?

Le interfacce TypeScript forniscono solo controllo dei tipi a tempo di compilazione nel codice TypeScript. JSON Schema fornisce validazione a runtime attraverso i linguaggi di programmazione, e può convalidare dati da qualsiasi fonte (richieste API, file, database). Usa TypeScript per la sicurezza in fase di sviluppo e JSON Schema per la validazione dei dati a runtime ai confini del sistema.

JSON Schema può validare i corpi delle richieste API?

Sì, JSON Schema è ampiamente utilizzato per la validazione di richieste e risposte API. Framework come Express (con express-json-validator), FastAPI e Spring Boot supportano la validazione JSON Schema nativamente o tramite middleware. La validazione dei corpi delle richieste rispetto a uno Schema garantisce che i dati in entrata abbiano la struttura corretta prima che l'applicazione li elabori.

Quali sono le parole chiave JSON Schema più importanti?

Le parole chiave più critiche sono: type (tipo di dato), properties (campi oggetto), required (campi obbligatori), items (Schema degli elementi array), minimum/maximum (limiti numerici), minLength/maxLength (limiti di stringa), pattern (regex per stringhe), enum (valori consentiti) e $ref (riferimenti per riutilizzare Schema). Queste parole chiave coprono la stragrande maggioranza delle esigenze di validazione.