Validation JSON Schema : valider du JSON dans Node, Python et le navigateur (2026)
En bref — JSON Schema est un contrat pour les données JSON : vous déclarez les types de champs, les clés obligatoires et les contraintes, puis un validateur vérifie qu’un document JSON respecte ce contrat. Utilisez Ajv dans Node pour la validation la plus rapide, la bibliothèque jsonschema en Python pour des schémas portables, et embarquez Ajv dans le navigateur pour un retour immédiat sur les formulaires et les configurations. Pour les nouveaux projets en 2026, partez sur Draft 2020-12.
Au programme : le plus petit exemple qui fonctionne, des patrons de bout en bout dans les trois environnements d’exécution, et les pièges concrets qui causent les bugs du type « la validation passe, mais la production rejette les données ».
Ce que JSON Schema est (et n’est pas)
Une définition en une phrase
Un JSON Schema est un document JSON qui décrit la forme d’autres documents JSON. Un validateur lit le schéma et les données, puis confirme la conformité ou retourne les chemins en échec.
Voici l’exemple le plus court qui serve à quelque chose :
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": { "name": { "type": "string" } },
"required": ["name"]
}
{"name": "Alice"} passe. {"age": 30} échoue (name manquant). {"name": 42} échoue (name n’est pas une chaîne). Le modèle mental tient là-dedans.
JSON Schema vs validation de syntaxe JSON
Deux problèmes différents, souvent confondus.
| Dimension | Vérification de syntaxe JSON | Validation JSON Schema |
|---|---|---|
| Ce qu’elle vérifie | Est-ce un document JSON valide ? | Ce JSON correspond-il au contrat ? |
| Ce qu’elle attrape | Virgules manquantes, guillemets simples, commentaires | Mauvais types, champs requis manquants, valeurs hors plage |
| Outils | JSON.parse(), Formateur JSON | Ajv, jsonschema (Python), fastjsonschema |
| Quand l’utiliser | En premier, avant le parsing | Juste après le parsing, avant la logique métier |
En pratique, vous faites les deux : passez la charge utile dans le Formateur JSON pour confirmer qu’elle parse, puis passez-la dans un schéma pour confirmer qu’elle suit le contrat.
JSON Schema vs JSONPath, JSON Patch, jq et TypeScript
Cinq outils se partagent ce terrain. La matrice de décision :
| Outil | Question à laquelle il répond | À utiliser quand |
|---|---|---|
| JSON Schema | Ce JSON correspond-il à la structure attendue ? | Valider une entrée d’API, un fichier de configuration, une charge utile de formulaire |
| JSONPath | Comment interroger une valeur dans ce JSON ? | Extraire des champs imbriqués, lectures par lots |
| JSON Patch (RFC 6902) | Comment décrire le diff entre A et B ? | Édition collaborative, synchronisation incrémentale |
| jq | Comment traiter du JSON en ligne de commande ? | Scripts shell, pipelines de logs, vérifications CI |
| Types TypeScript | Mon code utilise-t-il correctement cette forme ? | Garanties à la compilation au sein d’une même base de code |
La différence qui compte : JSON Schema valide des données inconnues à l’exécution. TypeScript valide du code connu à la compilation. TypeScript ne peut rien pour du JSON qui arrive d’un webhook tiers ou d’un collage utilisateur ; c’est précisément à cela que sert JSON Schema. Zod et Pydantic occupent un terrain intermédiaire (types à la compilation plus validation à l’exécution), traités plus loin.
JSON Schema vs OpenAPI
Idée reçue répandue : OpenAPI remplacerait JSON Schema. Faux. OpenAPI utilise JSON Schema en interne pour décrire les corps de requête et de réponse, puis ajoute par-dessus les chemins, les paramètres, les schémas de sécurité et les URLs de serveur. Le schéma est le contrat sur la forme des données ; OpenAPI est le contrat d’API qui l’enveloppe.
| Dimension | JSON Schema | OpenAPI |
|---|---|---|
| Portée | Forme d’un seul document JSON | Forme d’une API HTTP entière |
| Dépendances | Aucune (le schéma est du JSON autonome) | Importe JSON Schema pour les définitions de corps |
| Appariement de version | Draft 7 / Draft 2019-09 / Draft 2020-12 | OpenAPI 3.0 utilise un sous-ensemble de Draft 4 ; OpenAPI 3.1 utilise Draft 2020-12 nativement |
| Usage typique | Fichiers de configuration, enveloppes de messages, validation de formulaire, contrats à charge utile unique | Conception d’API REST, génération de SDK, serveurs mock, tests de contrat |
| Génération de code | Limitée (quelques outils façon quicktype) | Écosystème mature (openapi-generator, oapi-codegen, SDKs constructeurs) |
| Gestion de contrat | Un fichier par forme, pas de routage | Chemins, opérations, flux d’authentification, endpoints versionnés dans un même document |
Optez pour du JSON Schema simple quand l’artefact qui vous intéresse est un document unique : une charge utile de webhook, un fichier de configuration, un message de file ou un formulaire. Il n’y a pas de surface HTTP à décrire, donc OpenAPI devient une lourdeur inutile.
Optez pour OpenAPI quand vous publiez une API HTTP et voulez un seul document qui pilote la documentation, la génération de SDK, les serveurs mock et les tests de contrat. Définissez d’abord vos schémas comme des fichiers JSON Schema autonomes dans un répertoire schemas/, puis référencez-les depuis le document OpenAPI via $ref. Cela garde les schémas réutilisables hors du contexte d’API.
L’appariement des versions piège les équipes. OpenAPI 3.0 utilise un sous-ensemble de Draft 4 : impossible donc d’utiliser des mots-clés Draft 2020-12 comme prefixItems ou unevaluatedProperties dans un document 3.0 — les générateurs les ignoreront silencieusement. OpenAPI 3.1 est un sur-ensemble de Draft 2020-12 ; tout ce qui est valide en 2020-12 est valide en 3.1. Si vous avez le choix, ciblez OpenAPI 3.1 et écrivez partout des schémas Draft 2020-12.
Votre premier JSON Schema (5 minutes)
Les mots-clés à connaître en premier
Avec ceux-ci, vous couvrez 80 % des cas :
{
"type": "object",
"properties": {
"id": { "type": "integer", "minimum": 1 },
"email": { "type": "string", "format": "email" },
"age": { "type": "integer", "minimum": 0, "maximum": 150 },
"tags": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
"role": { "enum": ["admin", "editor", "viewer"] },
"metadata": { "type": "object", "additionalProperties": true }
},
"required": ["id", "email"],
"additionalProperties": false
}
Le vocabulaire :
type—string,number,integer,boolean,null,array,objectproperties+required— déclarer les champs et indiquer ceux qui doivent être présentsenum/const— restreindre à un ensemble fixe ou à un littéral uniqueminimum/maximum/multipleOf— bornes numériquesminLength/maxLength/pattern— longueur de chaîne et regexminItems/maxItems/uniqueItems— forme de tableauadditionalProperties: false— refuser les clés non déclarées (toujours le mettre sur les contrats d’entrée)
Exemples de JSON Schema par cas d’usage
Les mots-clés ci-dessus se combinent différemment selon ce que vous validez. Quelques formes représentatives :
Corps de requête d’API — un endpoint d’inscription qui accepte e-mail et mot de passe :
{
"type": "object",
"properties": {
"email": { "type": "string", "format": "email" },
"password": { "type": "string", "minLength": 8, "maxLength": 128 }
},
"required": ["email", "password"],
"additionalProperties": false
}
Fichier de configuration — une configuration de logger qui verrouille le niveau à un ensemble fixe :
{
"type": "object",
"properties": {
"level": { "enum": ["debug", "info", "warn", "error"] },
"output": { "type": "string", "default": "stdout" }
},
"required": ["level"],
"additionalProperties": false
}
Charge utile de formulaire avec règles conditionnelles — quand accountType vaut "business", taxId devient requis :
{
"type": "object",
"properties": {
"accountType": { "enum": ["personal", "business"] },
"taxId": { "type": "string" }
},
"if": { "properties": { "accountType": { "const": "business" } } },
"then": { "required": ["taxId"] }
}
Enregistrement JSON issu d’une ligne CSV — une ligne d’une table de commandes exportée :
{
"type": "object",
"properties": {
"orderId": { "type": "string", "pattern": "^ORD-[0-9]{6}$" },
"orderedOn": { "type": "string", "format": "date" },
"totalUsd": { "type": "number", "minimum": 0 }
},
"required": ["orderId", "orderedOn", "totalUsd"]
}
Enveloppe d’événement webhook — oneOf discrimine par le littéral type, chaque variante d’événement a donc sa propre forme de charge utile :
{
"oneOf": [
{ "properties": { "type": { "const": "order.created" }, "data": { "$ref": "#/$defs/order" } } },
{ "properties": { "type": { "const": "order.refunded" }, "data": { "$ref": "#/$defs/refund" } } }
]
}
Ces cinq exemples couvrent l’essentiel de ce que les équipes écrivent en pratique. Copiez celui qui s’approche le plus, ajustez les noms de champs — le vocabulaire de mots-clés reste le même.
Valider sans rien installer
Collez le schéma et la charge utile dans le bac à sable de ajv.js.org ou de jsonschemavalidator.net pour avoir un verdict tout de suite. Si le JSON lui-même semble suspect, faites-le d’abord passer dans le Formateur JSON.
Validation dans Node.js avec Ajv
Installation et exemple en 12 lignes
Au premier appel à compile, Ajv transforme votre schéma en une fonction optimisée, qu’il réutilise ensuite.
npm install ajv
import Ajv from "ajv";
const ajv = new Ajv();
const schema = {
type: "object",
properties: {
name: { type: "string" },
age: { type: "integer", minimum: 0 }
},
required: ["name"]
};
const validate = ajv.compile(schema);
const data = { name: "Alice", age: 30 };
if (!validate(data)) console.log(validate.errors);
else console.log("OK");
Passer à Draft 2020-12
Pour des raisons de rétrocompatibilité, le constructeur Ajv par défaut reste figé sur Draft 7. Activez explicitement 2020-12 :
import Ajv2020 from "ajv/dist/2020";
const ajv = new Ajv2020({ strict: true, allErrors: true });
prefixItems, unevaluatedProperties et $dynamicRef sont alors disponibles. Voir la section Draft 2020-12 plus bas pour le rôle de chacun.
Activer la validation format
La bizarrerie d’Ajv qui piège le plus de développeurs : par défaut, format: "email" ne fait rien. La spécification considère format comme indicatif, vous devez donc enregistrer le module de format :
npm install ajv-formats
import addFormats from "ajv-formats";
addFormats(ajv); // maintenant "format": "email" valide réellement
Sans cette étape, {"email": "not-an-email"} passe un schéma qui exige pourtant format: "email". En production, installez toujours ajv-formats.
Middleware Express en conditions réelles
Un validateur par route, compilé au démarrage :
import express from "express";
import Ajv2020 from "ajv/dist/2020";
import addFormats from "ajv-formats";
const ajv = new Ajv2020({ allErrors: true });
addFormats(ajv);
const validateUser = ajv.compile({
type: "object",
properties: {
email: { type: "string", format: "email" },
age: { type: "integer", minimum: 13 }
},
required: ["email"],
additionalProperties: false
});
const app = express();
app.use(express.json());
app.post("/users", (req, res) => {
if (!validateUser(req.body)) {
return res.status(400).json({ errors: validateUser.errors });
}
// ... logique métier
res.status(201).json({ ok: true });
});
L’erreur la plus coûteuse : appeler ajv.compile(schema) à l’intérieur du gestionnaire de requête. Compilez une seule fois au niveau du module et réutilisez la fonction renvoyée. Recompiler à chaque requête divise le débit par 50, voire plus.
Validation en Python avec jsonschema
Installation et utilisation de base
pip install jsonschema
from jsonschema import validate, ValidationError
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer", "minimum": 0}
},
"required": ["name"]
}
try:
validate(instance={"name": "Alice", "age": 30}, schema=schema)
print("OK")
except ValidationError as e:
print("ÉCHEC :", e.message, "à", list(e.absolute_path))
Collecter toutes les erreurs avec Draft202012Validator
validate() lève une exception dès la première erreur. Pour lister tous les problèmes d’un coup (pratique pour les réponses de formulaires), utilisez iter_errors :
from jsonschema import Draft202012Validator
validator = Draft202012Validator(schema)
errors = sorted(validator.iter_errors(instance), key=lambda e: e.path)
for err in errors:
print(f" - {'/'.join(map(str, err.absolute_path))}: {err.message}")
L’utilisateur corrige tout en une fois au lieu d’enchaîner les allers-retours.
jsonschema vs Pydantic : laquelle choisir
Deux bibliothèques Python solides pour deux problèmes différents.
| Dimension | jsonschema | Pydantic v2 |
|---|---|---|
| Format de schéma | Un dict JSON (le schéma est de la donnée) | Une classe Python avec annotations de type |
| Performance | Interprété, ~10 à 100× plus lent que Pydantic | Cœur en Rust, le plus rapide de l’écosystème |
| Portabilité multi-langage | Oui (le même schéma fonctionne en JS, Go, Rust) | Non (Python uniquement) |
| Intégration FastAPI / modèles natifs | Conversion manuelle | Intégrée |
Mots-clés Draft 2020-12 complets ($dynamicRef, etc.) | Complet | Partiel |
La règle qui tient en production : utilisez jsonschema pour les contrats multi-langages (OpenAPI, API publiques, webhooks) ; utilisez Pydantic pour les services internes en Python. Beaucoup d’équipes font tourner les deux : jsonschema à la passerelle pour faire respecter le contrat, Pydantic au niveau applicatif pour la logique métier typée. Le schéma reste l’artefact portable, le même que celui que vous donneriez à Ajv.
Validation dans le navigateur
Pourquoi valider côté client
Trois raisons, par ordre d’importance :
- UX : un retour immédiat pendant la saisie vaut mieux qu’un aller-retour serveur
- Bande passante : les erreurs évidentes ne quittent jamais le navigateur
- Hygiène de sécurité : réduit le volume de déchets envoyés au backend (ne remplace pas la validation serveur)
Ne faites jamais confiance à la seule validation côté client. Re-validez côté serveur.
Embarquer Ajv pour le navigateur
npm install ajv ajv-formats
import Ajv2020 from "ajv/dist/2020";
import addFormats from "ajv-formats";
const ajv = new Ajv2020({ allErrors: true });
addFormats(ajv);
export const validateForm = ajv.compile({
type: "object",
properties: {
email: { type: "string", format: "email" },
password: { type: "string", minLength: 8 }
},
required: ["email", "password"]
});
Le bundle ajoute environ 30 Ko gzippés : c’est significatif sans être catastrophique. Les équipes embarquent Ajv quand elles veulent une définition de schéma unique, partagée entre serveur et client.
Alternatives plus légères : Zod et Valibot
Si vous n’avez pas besoin de l’écosystème JSON Schema et que vous êtes déjà en TypeScript, un validateur natif TS donne des bundles plus petits et une inférence de type plus serrée :
import { z } from "zod";
const UserSchema = z.object({
email: z.string().email(),
password: z.string().min(8)
});
const result = UserSchema.safeParse(data);
if (!result.success) console.log(result.error.issues);
Valibot tient dans environ 3 Ko gzippés avec une API similaire. À choisir quand la taille du bundle prime. Contrepartie : aucune des deux ne produit de JSON Schema. Si vous avez besoin d’une source de vérité unique partagée avec des backends, des clients tiers ou des générateurs OpenAPI, restez sur Ajv. Si tout votre code reste du TypeScript maison, Zod et Valibot sont plus ergonomiques.
Ce que Draft 2020-12 apporte
prefixItems pour la validation de tuples
Draft 7 exprimait les tuples avec items: [] et additionalItems. Draft 2020-12 sépare clairement :
{
"type": "array",
"prefixItems": [
{ "type": "string" },
{ "type": "number" }
],
"items": false
}
["x", 42] passe. ["x", 42, "extra"] échoue. Le schéma se lit exactement comme il agit.
unevaluatedProperties pour les schémas composés
Un bug subtil qui finit par mordre toutes les équipes qui utilisent allOf ou oneOf : additionalProperties: false ne contrôle que le niveau immédiat où il apparaît. Les sous-schémas frères à l’intérieur de allOf déclarent les propriétés qu’ils veulent. Le correctif 2020-12, c’est unevaluatedProperties: false :
{
"allOf": [
{ "$ref": "#/$defs/base" }
],
"unevaluatedProperties": false
}
Cela rejette toute propriété qu’aucune branche n’a évaluée, ce qui est le comportement que la plupart des développeurs attendaient de additionalProperties: false.
$dynamicRef pour les schémas récursifs
Quiconque a déjà tenté de déclarer un schéma d’arbre récursif en Draft 7 connaît les contorsions nécessaires. $dynamicRef couplé à $dynamicAnchor simplifie tout :
{
"$dynamicAnchor": "node",
"type": "object",
"properties": {
"value": { "type": "string" },
"children": { "type": "array", "items": { "$dynamicRef": "#node" } }
}
}
La récursion devient déclarative et surchargeable depuis les descendants sans avoir à réécrire $id.
Draft 7 vs 2020-12 : lequel choisir
- Nouveau projet, chaîne d’outils moderne → Draft 2020-12
- Construire ou consommer OpenAPI 3.1 → 2020-12 est le dialecte natif
- Travailler avec OpenAPI 3.0 ou des services plus anciens → Draft 4 (OpenAPI 3.0 utilise un sous-ensemble de Draft 4 ; ne mélangez pas les dialectes)
- Besoin d’une large compatibilité de validateurs (Postman, vieux outils CI) → Draft 7 reste le format d’échange le plus sûr
Tous les validateurs modernes (Ajv, jsonschema Python, jsonschema-rs, networknt/json-schema-validator en Java) supportent aujourd’hui 2020-12.
Patrons réels
Validation d’entrée d’API
Le middleware Express ci-dessus est la forme de production. Deux pratiques par-dessus : conservez tous les schémas dans un répertoire schemas/ à la racine du dépôt, et ajoutez une étape CI qui lance ajv test (ou l’équivalent Python) pour valider les schémas eux-mêmes face au méta-schéma JSON Schema.
Fichiers de configuration
Visual Studio Code embarque une intégration SchemaStore : autocomplétion et validation en ligne pour package.json, tsconfig.json et des dizaines d’autres. Ajoutez un champ $schema à vos propres configurations et les utilisateurs de l’éditeur bénéficient du même traitement.
Fixtures de tests CI
Les fixtures de tests pourrissent. Quelqu’un met à jour un modèle, une fixture reste à l’ancienne forme, le test continue de passer parce que les assertions ne touchaient pas le champ modifié. Attrapez ce genre de dérive avec une vérification de schéma avant l’exécution des assertions :
import { glob } from "glob";
const files = await glob("__tests__/fixtures/*.json");
for (const f of files) {
const data = JSON.parse(await fs.readFile(f, "utf8"));
if (!validate(data)) throw new Error(`${f}: ${ajv.errorsText(validate.errors)}`);
}
Quand la vérification de schéma se déclenche, le réflexe suivant, c’est en général un diff structurel. Faites passer la fixture dans Comparer JSON face à un échantillon de production frais pour voir ce qui a dérivé. Si les timestamps et les IDs dominent le diff, appliquez les patrons d’ignorance par chemin du guide JSON diff pour séparer le signal du bruit.
Charges utiles de webhooks (Stripe, GitHub)
Les webhooks tiers font partie des endroits à plus haute valeur où appliquer JSON Schema. Un webhook est un contrat, le fournisseur peut le modifier, et vous voulez le savoir dès que ça arrive. Stripe et GitHub publient des descriptions OpenAPI dont vous pouvez extraire des JSON Schemas. Validez les événements entrants : une mise à jour cassante allume votre supervision au lieu de corrompre l’état en silence.
Validation de formulaires pilotée par le schéma
React Hook Form dispose d’un adaptateur @hookform/resolvers/ajv ; côté Vue, VeeValidate a un plugin Ajv équivalent. Tous deux pilotent le rendu du formulaire, les messages d’erreur et la validation de soumission depuis un même JSON Schema. Le schéma sert de source de vérité unique, et l’UI hérite de ses règles.
Messages d’erreur conviviaux
Pourquoi les valeurs par défaut sont rugueuses
D’origine, Ajv produit des erreurs du genre #/properties/email format must match "email". Acceptable pour un développeur qui débogue un 400. Inutile pour un utilisateur qui remplit un formulaire de paiement.
ajv-errors pour des messages personnalisés
npm install ajv-errors
import ajvErrors from "ajv-errors";
ajvErrors(ajv);
const schema = {
type: "object",
properties: { email: { type: "string", format: "email" } },
required: ["email"],
errorMessage: {
properties: { email: "Veuillez saisir une adresse e-mail valide" },
required: { email: "L'e-mail est requis" }
}
};
Le mot-clé errorMessage reste à l’intérieur du schéma, ce qui permet de transporter ensemble les règles de validation et le texte destiné à l’utilisateur.
ajv-i18n pour des erreurs traduites
ajv-i18n fournit des traductions des messages par défaut dans plus de 30 langues. Une ligne au démarrage et votre validateur parle espagnol, français, japonais ou n’importe quelle locale que vous servez. Pratique comme repli quand vos surcharges errorMessage ne couvrent pas chaque contrainte.
Mapper les chemins de schéma vers les champs de formulaire
Chaque erreur Ajv possède un instancePath du genre /users/0/email. La plupart des bibliothèques de formulaires attendent des chemins pointés du type users[0].email. En une ligne :
const fieldPath = error.instancePath.replace(/^\//, "").replace(/\//g, ".");
Dans le jsonschema de Python, l’équivalent vit dans error.absolute_path. Joignez avec . pour le même effet.
Cinq pièges qui passent la validation puis font planter la production
1. format est indicatif par défaut
Sans ajv-formats et addFormats(ajv), chaque mot-clé format ne fait rien. {"format": "email"} accepte "not-an-email". En production, installez toujours le paquet de formats.
2. additionalProperties vaut true par défaut
Sans additionalProperties: false, votre schéma accepte n’importe quel champ non déclaré. Les clients peuvent envoyer des champs supplémentaires qui contournent entièrement la validation. Mettez additionalProperties: false par défaut sur les contrats d’entrée et relâchez délibérément quand c’est nécessaire.
3. additionalProperties ne se compose pas
À l’intérieur de allOf, oneOf ou anyOf, additionalProperties: false n’inspecte que les propriétés de son propre niveau. Les sous-schémas frères passent à travers. Le correctif Draft 2020-12, c’est unevaluatedProperties: false.
4. Les $ref distants sont un risque en production
$ref: "https://example.com/schema.json" fait qu’Ajv va chercher sur le réseau au premier compile. Résultat : de la latence, une exposition au DoS si l’hôte distant cale, et une surface d’attaque MITM. Inlinez toutes les cibles de $ref ou chargez-les depuis le disque au moment du build.
5. Les schémas générés dérivent des données réelles
Des outils comme quicktype et typescript-json-schema génèrent des schémas à partir de types existants. La sortie est en général trop permissive : chaque champ optionnel, additionalProperties ouvert. Traitez les schémas générés comme des brouillons, resserrez à la main, et faites tourner en CI une validation des échantillons de production réels face au schéma (et inversement) pour faire remonter la dérive rapidement.
Performance : chiffres et règles empiriques
- Ajv (Node.js) : les validateurs compilés enchaînent une vérification bien en dessous de la microseconde. Le validateur JS de qualité production le plus rapide disponible.
jsonschema(Python) : interprété, 10 à 100× plus lent que Pydantic. Basculez surfastjsonschemaquand ça mord ; il génère du code Python et atteint des niveaux proches d’Ajv.- Rust et Go :
jsonschema-rsetxeipuuv/gojsonschemavous donnent encore 2 à 5× de plus qu’Ajv au niveau de la passerelle. - Le plus gros gain : précompiler.
ajv.compile(schema)une fois au chargement du module, puis réutiliser le validateur retourné à chaque requête. Recompiler à chaque requête tue le débit d’un facteur 50 ou plus.
Foire aux questions
Qu’est-ce que la validation JSON Schema, en clair ?
La validation JSON Schema vérifie qu’un document JSON suit un contrat. Le contrat (le schéma) est lui-même du JSON, qui déclare des types, des champs obligatoires et des contraintes. Un validateur lit le schéma et les données puis indique « passe » ou les chemins qui ont échoué et pourquoi.
Comment valider du JSON face à un schéma en ligne ?
Collez le schéma et les données dans le bac à sable de ajv.js.org ou de jsonschemavalidator.net pour un verdict immédiat. Si le JSON paraît malformé, nettoyez-le d’abord dans le Formateur JSON ; les deux tournent dans le navigateur, sans envoi.
Quel est le validateur JSON Schema le plus rapide en 2026 ?
Dans Node, Ajv avec des validateurs précompilés enchaîne une vérification en moins d’une microseconde. En Python, fastjsonschema génère du code et atteint un débit de classe Ajv. Au niveau de la passerelle, jsonschema-rs (Rust) et gojsonschema (Go) sont 2 à 5× plus rapides qu’Ajv. Quel que soit votre choix, précompilez une seule fois puis réutilisez.
Quelle est la différence entre JSON Schema et les types TypeScript ?
TypeScript vérifie à la compilation le code que vous écrivez. JSON Schema vérifie du JSON inconnu à l’exécution. TypeScript ne peut pas voir du JSON qui arrive d’une réponse HTTP, d’un fichier ou d’un collage utilisateur ; c’est précisément à cela que sert JSON Schema.
Faut-il utiliser Draft 2020-12 ou Draft 7 ?
Pour les nouveaux projets en 2026, prenez Draft 2020-12. prefixItems, unevaluatedProperties et $dynamicRef règlent de vrais problèmes. OpenAPI 3.1 utilise nativement 2020-12. Restez sur Draft 7 uniquement pour la compatibilité Postman ou les services plus anciens. OpenAPI 3.0 utilise un sous-ensemble de Draft 4 ; ne mélangez pas les dialectes.
Comment générer un JSON Schema à partir d’un JSON existant ?
Trois options : coller des échantillons dans quicktype.io ou jsonschema.net ; lancer npx genson-js ou pip install genson && genson sample.json en ligne de commande ; ou l’écrire à la main. Les schémas générés automatiquement sont trop permissifs (chaque champ optionnel, additionalProperties: true), donc resserrez-les toujours avant de les traiter comme des contrats.
JSON Schema peut-il remplacer OpenAPI ?
Non. OpenAPI utilise JSON Schema en interne pour décrire les corps de requête et de réponse, puis ajoute les chemins, les schémas de sécurité, les paramètres et les URLs de serveur. Les deux se composent : écrivez vos schémas, référencez-les depuis un document OpenAPI, et vous obtenez des contrats d’API complets.
JSON Schema est-il la même chose que JSONPath ou jq ?
Problèmes différents. JSON Schema valide la structure (« ce JSON correspond-il au contrat ? »). JSONPath et jq extraient des valeurs (« le nom de chaque pod en phase Running »). Validez avec un schéma ; interrogez avec JSONPath ou jq.
Pourquoi ma validation Ajv passe-t-elle alors que la production rejette les données ?
Trois coupables couvrent presque tous les cas : avoir oublié ajv-formats si bien que format: "email" n’a jamais rien validé ; avoir omis additionalProperties: false si bien que des champs client supplémentaires sont passés ; utiliser additionalProperties: false à l’intérieur de allOf ou oneOf et découvrir qu’il ne se compose pas. Passez à unevaluatedProperties: false.
Puis-je personnaliser les messages d’erreur JSON Schema pour les utilisateurs finaux ?
Oui. Dans Node, installez ajv-errors pour intégrer errorMessage dans le schéma, et ajv-i18n pour les traductions sur plus de 30 locales. En Python, jsonschema expose le contexte complet de validation sur chaque objet d’erreur ; vous pouvez donc mapper le type d’erreur plus le chemin vers le texte que votre design system utilise.