Guide de validation par JSON Schema : valider vos structures de données
Chaque application qui reçoit des données d'une source externe est confrontée au même problème fondamental : puis-je faire confiance à ces données ? Qu'il s'agisse de corps de requêtes API, de fichiers de configuration, de messages de file d'attente ou d'importations de données, les données non fiables doivent être validées avant d'entrer dans le système. JSON Schema fournit un moyen standardisé et indépendant du langage de définir à quoi ressemblent les données valides et de vérifier si les données entrantes correspondent à cette définition. Ce guide couvre tout, de l'écriture de votre premier Schema aux modèles avancés de validation complexe, avec des exemples pratiques que vous pouvez appliquer immédiatement.
Qu'est-ce que JSON Schema ?
JSON Schema est un document JSON qui décrit la structure et les contraintes d'autres documents JSON. C'est un vocabulaire qui vous permet d'annoter et de valider des données JSON, standardisé par l'Internet Engineering Task Force (IETF). JSON Schema définit des règles sur les champs qui doivent être présents, leurs types, les valeurs acceptables et la façon dont les objets et tableaux doivent être structurés.
Pensez à JSON Schema comme un contrat pour vos données. Tout comme un schéma de base de données définit les colonnes, types et contraintes d'une table, JSON Schema définit les propriétés, types et contraintes d'un document JSON. Toute donnée JSON satisfaisant toutes les contraintes du Schema est appelée une instance valide, et toute donnée enfreignant une contrainte est invalide.
Ce que JSON Schema n'est pas
- Pas un format de données : JSON Schema ne définit pas comment les données sont sérialisées ou transférées. Il décrit simplement à quoi ressemblent les données valides.
- Pas un remplacement de la logique métier : la validation par Schema vérifie l'exactitude structurelle (types, formats, plages). Les règles métier complexes (comme « un utilisateur ne peut pas transférer plus que son solde ») appartiennent au code de l'application.
- Pas un schéma de base de données : bien que les concepts soient similaires, JSON Schema valide des documents JSON, pas des tables de base de données. Cependant, vous pouvez combiner JSON Schema avec des contraintes de base de données pour une défense en profondeur.
Versions de JSON Schema
JSON Schema a évolué à travers plusieurs drafts, chacun ajoutant des fonctionnalités et affinant le vocabulaire. Comprendre ces versions vous aide à choisir la bonne version pour votre projet et à éviter les problèmes de compatibilité.
| Version | URI $schema | Statut | Fonctionnalités principales |
|---|---|---|---|
| Draft 2020-12 | https://json-schema.org/draft/2020-12/schema | Version actuelle | prefixItems, dynamicRef, support de vocabulaire |
| Draft 2019-09 | https://json-schema.org/draft/2019-09/schema | Version stable | unevaluatedProperties, $recursiveRef |
| Draft 7 | http://json-schema.org/draft-07/schema# | Large support | if/then/else, contentEncoding |
| Draft 6 | http://json-schema.org/draft-06/schema# | Ancienne version | propertyNames, contains |
| Draft 4 | http://json-schema.org/draft-04/schema# | Déprécié | Première version largement adoptée |
Écrire votre premier Schema
Commençons par un exemple simple : un Schema pour un objet utilisateur contenant un nom, un email et un âge.
{
"$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
}Ce Schema déclare qu'un utilisateur valide doit être un objet, avec name et email comme propriétés obligatoires de type chaîne. La propriété age est facultative, mais si elle est présente, elle doit être un entier entre 0 et 150. La contrainte additionalProperties: false empêche toute propriété non définie dans le Schema, ce qui permet de détecter les fautes de frappe et les champs inattendus.
Référence des mots-clés principaux
JSON Schema fournit un riche vocabulaire de mots-clés pour définir des contraintes. Voici les mots-clés les plus importants, organisés par catégorie.
Mot-clé type
| Mot-clé | Description | Exemple |
|---|---|---|
| type | Type de données attendu | "type": "string" ou "type": ["string", "null"] |
| enum | Liste des valeurs autorisées | "enum": ["active", "inactive", "pending"] |
| const | Doit être exactement cette valeur | "const": "v2" |
Contraintes numériques
| Mot-clé | Description | Exemple |
|---|---|---|
| minimum | Valeur minimale (incluse) | "minimum": 0 |
| exclusiveMinimum | Valeur minimale (exclusive) | "exclusiveMinimum": 0 |
| maximum | Valeur maximale (incluse) | "maximum": 100 |
| exclusiveMaximum | Valeur maximale (exclusive) | "exclusiveMaximum": 100 |
| multipleOf | Doit être un multiple de cette valeur | "multipleOf": 0.01 |
Contraintes de chaîne
| Mot-clé | Description | Exemple |
|---|---|---|
| minLength | Longueur minimale de chaîne | "minLength": 1 |
| maxLength | Longueur maximale de chaîne | "maxLength": 255 |
| pattern | Expression régulière que la chaîne doit correspondre | "pattern": "^[A-Z]{2}\\d{4}$" |
| format | Format sémantique (email, uri, date-time, etc.) | "format": "email" |
Contraintes d'objet
| Mot-clé | Description | Exemple |
|---|---|---|
| properties | Schema pour chaque propriété connue | "properties": {"name": {"type": "string"}} |
| required | Liste des propriétés obligatoires | "required": ["name", "email"] |
| additionalProperties | Si les propriétés supplémentaires sont autorisées | "additionalProperties": false |
| minProperties | Nombre minimum de propriétés | "minProperties": 1 |
| maxProperties | Nombre maximum de propriétés | "maxProperties": 10 |
| patternProperties | Schema des propriétés correspondant à une expression régulière | "patternProperties": {"^S_": {"type": "string"}} |
Contraintes de tableau
| Mot-clé | Description | Exemple |
|---|---|---|
| items | Schema pour tous les éléments du tableau | "items": {"type": "string"} |
| prefixItems | Schema pour les éléments positionnels (Draft 2020-12) | "prefixItems": [{"type": "string"}, {"type": "number"}] |
| minItems | Nombre minimum d'éléments | "minItems": 1 |
| maxItems | Nombre maximum d'éléments | "maxItems": 100 |
| uniqueItems | Tous les éléments doivent être uniques | "uniqueItems": true |
Modèles de Schema courants
Les Schémas du monde réel nécessitent souvent des modèles allant au-delà de la simple vérification de type. Voici les modèles les plus couramment utilisés.
Validation conditionnelle avec if/then/else
Utilisez une logique conditionnelle pour appliquer différentes contraintes en fonction de la valeur d'une propriété. Par exemple, un objet de paiement nécessite des champs différents selon la méthode de paiement.
{
"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"]
}
}Combinaisons avec allOf, anyOf, oneOf
Les mots-clés de combinaison vous permettent de combiner des Schémas de manière puissante :
- allOf : les données doivent satisfaire tous les sous-Schémas. Utilisé pour combiner plusieurs contraintes ou intégrer des fragments de Schema réutilisables.
- anyOf : les données doivent satisfaire au moins un sous-Schema. Utilisé pour les types union où plusieurs formes sont acceptables.
- oneOf : les données doivent satisfaire exactement un sous-Schema. Utilisé pour des alternatives mutuellement exclusives.
{
"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"]
}
]
}Réutilisation de Schema avec $ref
Le mot-clé $ref vous permet de référencer et de réutiliser des Schémas, éliminant la duplication et maintenant la maintenabilité du Schema. Vous pouvez référencer des Schémas dans le même document ou dans des fichiers externes.
{
"$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"]
}
}
}Types nullables
Dans JSON Schema Draft 2020-12, les types nullables sont représentés à l'aide d'un tableau de types incluant « null » :
{
"type": ["string", "null"],
"description": "An optional display name, or null if not set"
}Dans les drafts antérieurs, la spécification OpenAPI utilisait le mot-clé nullable: true. Pour le JSON Schema standard, utilisez toujours l'approche du tableau de types.
Validation de format
Le mot-clé format fournit une validation sémantique au-delà des vérifications structurelles. Il spécifie qu'une chaîne doit correspondre à un format bien connu. Les formats couramment pris en charge incluent :
| Format | Description | Exemple |
|---|---|---|
| Adresse e-mail | user@example.com | |
| uri | URI valide | https://example.com/path |
| uri-reference | URI ou référence relative | /path/to/resource |
| date-time | Date-heure ISO 8601 | 2026-05-19T14:30:00Z |
| date | Date ISO 8601 | 2026-05-19 |
| time | Heure ISO 8601 | 14:30:00Z |
| ipv4 | Adresse IPv4 | 192.168.1.1 |
| ipv6 | Adresse IPv6 | ::1 |
| uuid | Identifiant unique universel | 550e8400-e29b-41d4-a716-446655440000 |
| hostname | Nom d'hôte Internet | www.example.com |
Validation programmatique des données JSON
La validation par Schema est plus utile lorsqu'elle est intégrée dans le code de l'application. Voici des exemples utilisant des bibliothèques populaires dans différents langages.
JavaScript avec Ajv
Ajv est le validateur JSON Schema le plus utilisé en JavaScript. Il prend en charge toutes les versions de draft et offre d'excellentes performances grâce à la compilation JIT des Schémas.
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 avec 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}")Validation de données d'API avec JSON Schema
L'une des applications les plus précieuses de JSON Schema est la validation des données de requêtes et de réponses d'API. Cela garantit que votre API reçoit des entrées bien formatées et renvoie des données au format attendu, détectant les erreurs tôt et fournissant des messages d'erreur clairs aux clients.
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 vs JSON Schema
OpenAPI (anciennement Swagger) utilise un sous-ensemble de JSON Schema pour définir les Schémas de requêtes et de réponses d'API. Si vous utilisez déjà OpenAPI, vous pouvez extraire les Schémas de la spécification d'API et les utiliser pour la validation à l'exécution. Des outils comme openapi-schema-validator et express-openapi-validator peuvent automatiser ce processus, garantissant que votre documentation d'API et votre logique de validation restent toujours synchronisées.
Meilleures pratiques
- Définissez toujours $schema : incluez le mot-clé $schema pour déclarer la version de draft utilisée par votre Schema. Cela évite l'ambiguïté et garantit que le validateur interprète correctement votre Schema.
- Utilisez $id comme identifiant de Schema : le mot-clé $id fournit un identifiant unique pour votre Schema et sert d'URI de base pour la résolution des références $ref. Même pour les Schémas locaux, définissez-le toujours.
- Définissez additionalProperties: false : par défaut, JSON Schema autorise des propriétés supplémentaires dans les objets. Définir additionalProperties: false permet de détecter les fautes de frappe et les champs inattendus, rendant votre Schema plus strict et votre API plus prévisible.
- Utilisez $defs pour les composants réutilisables : définissez des Schémas courants dans $defs et référencez-les avec $ref. Cela réduit la duplication et rend le Schema plus facile à maintenir.
- Ajoutez des descriptions : chaque propriété et Schema devrait avoir un champ description. Cela sert de documentation et aide les autres développeurs à comprendre le but et les contraintes de chaque champ.
- Validez aux frontières du système : appliquez la validation par Schema aux frontières de votre système : points d'extrémité d'API, consommateurs de messages, pipelines d'importation de données et chargeurs de configuration. Ne validez pas les données que votre propre code a produites et en qui vous avez confiance.
- Activez le mode strict dans le validateur : configurez le validateur pour rejeter les mots-clés inconnus, appliquer la validation de format et signaler toutes les erreurs plutôt que de s'arrêter à la première erreur. Cela permet de détecter plus de problèmes en une seule validation.
- Versionnez vos Schémas : incluez la version du Schema dans l'URI $id (par exemple https://example.com/schemas/user/v2.json). Cela vous permet de faire évoluer le Schema sans casser les consommateurs existants.
- Testez vos Schémas : écrivez des tests unitaires avec des exemples valides et invalides pour vos Schémas. Cela garantit que votre Schema applique les contraintes que vous souhaitez et détecte les régressions lors de modifications du Schema.
- Utilisez format pour la validation sémantique : préférez format: "email" à un motif d'expression régulière complexe. Les formats sont plus lisibles, plus faciles à maintenir et bénéficient d'une logique de validation bien testée dans les bibliothèques de validateurs.
Besoin de valider des données JSON avec un Schema ? Essayez notre validateur JSON Schema en ligne gratuit. Collez votre Schema et vos données pour obtenir des résultats de validation instantanés avec des messages d'erreur détaillés.
Validateur JSON SchemaOutil de formatage JSONQuestions fréquentes
Qu'est-ce que JSON Schema ?
JSON Schema est un document JSON qui décrit la structure et les contraintes d'autres documents JSON. Il vous permet de définir les champs obligatoires, les types de données attendus, les plages de valeurs, les motifs de chaîne et la structure des objets imbriqués. Vous pouvez l'utiliser pour valider les données entrantes, générer de la documentation et créer automatiquement des interfaces de formulaires.
Quelle version de JSON Schema dois-je utiliser ?
Pour les nouveaux projets, utilisez JSON Schema Draft 2020-12. C'est la dernière version stable, prise en charge par les principaux validateurs comme Ajv. Si vous avez besoin de compatibilité avec des outils plus anciens, Draft 7 est également largement pris en charge. Évitez Draft 4 et versions antérieures car elles utilisent des mots-clés obsolètes et manquent de fonctionnalités modernes.
Quelle est la différence entre JSON Schema et les interfaces TypeScript ?
Les interfaces TypeScript ne fournissent une vérification de type qu'à la compilation dans le code TypeScript. JSON Schema fournit une validation à l'exécution inter-langages qui peut valider des données de n'importe quelle source (requêtes API, fichiers, bases de données). Utilisez TypeScript pour la sécurité au développement, et JSON Schema pour la validation des données à l'exécution aux frontières du système.
JSON Schema peut-il valider des corps de requête d'API ?
Oui, JSON Schema est largement utilisé pour la validation des requêtes et réponses d'API. Des frameworks comme Express (avec express-json-validator), FastAPI et Spring Boot prennent en charge nativement ou via middleware la validation par JSON Schema. Valider les corps de requête avec un Schema garantit que les données entrantes ont la bonne structure avant que l'application ne les traite.
Quels sont les mots-clés JSON Schema les plus importants ?
Les mots-clés les plus critiques sont : type (type de données), properties (champs d'objet), required (champs obligatoires), items (Schema des éléments de tableau), minimum/maximum (limites numériques), minLength/maxLength (limites de chaîne), pattern (expression régulière de chaîne), enum (valeurs autorisées) et $ref (référence pour réutiliser des Schémas). Ces mots-clés couvrent la grande majorité des besoins de validation.