Blog SchemaSafe
Erreurs courantes lors de la création de schémas JSON
JSON Schema, actuellement Draft 2020-12, est la méthode standard pour décrire et valider la forme JSON. La plupart des schémas défectueux ne contiennent pas d'erreurs de syntaxe ; il s'agit d'erreurs de permissivité qui autorisent des données invalides. Les quatre erreurs qui apparaissent le plus souvent lors de la revue de code sont un tableau requis manquant, des propriétés supplémentaires ouvertes, des unions de types mal utilisées et un $ref qui ne pointe nulle part.
Oublier le tableau requis
Lorsque vous ajoutez une propriété sous properties, vous ne décrivez que sa forme, sans exiger sa présence. Si le tableau requis omet cette clé, une instance sans le champ est validée avec succès. C'est un passage silencieux car le validateur traite la propriété comme facultative. J'ai vu des équipes publier des API où un identifiant critique était manquant dans required, ce qui a conduit à des erreurs de pointeur null en aval qui n'apparaissaient que en production.
Par exemple, un schéma d'utilisateur qui attend un id doit contenir :
{ "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" } }, "required": ["id"] } Sans la ligne required, un objet avec seulement {"name":"Ada"} serait validé, même si l'API traite ensuite id comme obligatoire.
Laisser additionalProperties ouvert
La valeur par défaut de additionalProperties est true . Cela permet à toute clé non définie dans properties de passer la validation. Une faute de frappe telle que "user_name" au lieu de "username" devient alors un champ silencieusement accepté, polluant le modèle de données et rendant les migrations ultérieures plus difficiles. J'ai vu des équipes passer des semaines à nettoyer les clés errantes qui sont entrées dans la base de données parce que le schéma ne les a jamais rejetées.
Voici une version stricte d'un schéma de produit :
{ "type": "object", "properties": { "sku": { "type": "string" }, "price": { "type": "number", "minimum": 0 } }, "required": ["sku","price"], "additionalProperties": false } Avec ce schéma, une instance contenant {"sku":"ABC","price":10,"extra":1} échoue à la validation, détectant la faute de frappe tôt.
Mauvaise utilisation des unions de types
Le mot-clé type attend soit une chaîne de caractères, soit un tableau de chaînes de caractères. Écrire "type": "string, number" est un schéma JSON invalide ; l'analyseur traite la valeur entière comme un type inconnu, que de nombreux validateurs ignorent silencieusement, permettant ainsi à toute valeur de passer. Une autre erreur courante consiste à omettre le type pour un champ facultatif, ce qui fait que le validateur saute la vérification du type pour cette clé.
Exemple d'un champ de date nullable :
{ "type": "object", "properties": { "issuedAt": { "type": ["string","null"], "format": "date-time" } }, "required": ["issuedAt"] } Ici, null est autorisé, donc {"issuedAt":null} est valide, tandis que {"issuedAt":"not-a-date"} échoue.
Pièges $ref et dérive de version
Un $ref qui se résout à un emplacement manquant provoque l'échec de l'ensemble du schéma au moment du chargement, ce qui est bruyant et facile à détecter. Le problème plus silencieux est une référence qui se résout mais pointe vers la mauvaise définition parce que la version de draft a changé ou que la structure de dossiers a changé. Dans le Draft 2020-12, le mot-clé pour les blocs réutilisables a été déplacé de definitions à $defs. Si vous conservez l'ancienne clé, le schéma est toujours valide (l'ancien mot-clé est ignoré) mais vous perdez la capacité de réutiliser les définitions, ce qui entraîne un code dupliqué et une dérive.
Exemple d'une référence correcte :
{ "$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"] } Si vous avez écrit par erreur "$ref": "#/definitions/address" la référence se résoudrait à undefined et le validateur lancerait une erreur, vous alertant ainsi sur la non-conformité.
Valider avec des exemples avant de publier
La vérification de confiance la moins coûteuse consiste à exécuter une poignée d'instances JSON représentatives via le validateur avant de considérer le schéma comme un contrat. Un bon jeu de tests contient au moins un exemple valide qui correspond à l'utilisation prévue et un exemple invalide qui viole intentionnellement chaque règle qui vous intéresse. Si le schéma accepte l'exemple correct et rejette l'exemple incorrect, vous avez la preuve qu'il n'est pas trop permissif. J'ai vu des équipes omettre cette étape et découvrir plus tard qu'un champ requis manquant permettait à des commandes sans ID de produit de passer, provoquant des erreurs de traitement.
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" }; // id manquant const validate = ajv.compile(schema); console.log('Exemple correct :', validate(good) ? 'pass' : 'fail'); if (!validate(good)) console.error(validate.errors); console.log('Exemple incorrect :', validate(bad) ? 'pass' : 'fail'); if (validate(bad)) console.error('Exemple incorrect accepté de manière inattendue'); L'exécution de cela dans CI garantit qu'une erreur de permissivité ne parvient jamais en production.
Ce que ce n'est pas
Ce guide ne promet pas que suivre ces points rendra votre schéma à l'épreuve de toutes les erreurs possibles. JSON Schema est un langage flexible, et de nouveaux pièges peuvent apparaître lorsque vous l'étendez avec des mots-clés personnalisés ou que vous le combinez avec d'autres outils comme OpenAPI. Je ne prétends pas que les quatre erreurs répertoriées sont les seules qui comptent ; ce sont simplement celles qui apparaissent le plus souvent dans les revues de code que j'ai vues. Les conseils ici sont basés sur mon expérience de maintenance de SchemaSafe et sur des spécifications publiques ; ils ne remplacent pas la lecture de la spécification officielle ou l'exécution de vos propres tests de validation.
Références
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
FAQ
Déclarer une propriété dans les propriétés ne la rend pas obligatoire. Vous devez la lister dans le tableau des propriétés requises. Le tableau est un frère de properties, et non imbriqué à l'intérieur.
Il est par défaut true, donc les clés inconnues sont autorisées. Définissez additionalProperties: false lorsque la rigidité est importante, ou restreignez-le avec un schéma pour les champs d'extension. Les schémas ouverts laissent passer les fautes de frappe en silence.
Omettez-le des propriétés requises et incluez "null" dans son tableau de types, par exemple ["string", "null"]. Écrire une chaîne de type séparée par des virgules est invalide et peut annuler la contrainte.
Sous $defs. La clé de définition plus ancienne fonctionne toujours, mais marque un ancien brouillon. Épinglez toujours $schema pour que le validateur applique le brouillon que vous aviez l'intention d'utiliser.
Essayez le produit : SchemaSafe
2026-09-16 · sources primaires uniquement · pas de métriques de trafic fabriquées
Articles liés
Validation de schéma JSON sans LLM (2026)
Explorez la matrice complète du sujet micro-SaaS IA →
Pourquoi mon schéma accepte-t-il les champs manquants?
Déclarer une propriété dans properties ne la rend pas obligatoire. Vous devez la lister dans le tableau required. Le tableau est un frère de properties, et non un élément imbriqué.
Qu'est-ce que additionalProperties fait par défaut?
Il est par défaut true, donc les clés inconnues sont acceptées. Définissez additionalProperties: false lorsque la rigidité est importante, ou restreignez-le avec un schéma pour les champs d'extension. Les schémas ouverts laissent les fautes de frappe passer silencieusement.
Comment marquer un champ comme facultatif dans JSON Schema?
Omettez-le de required et incluez \
Où vont les définitions réutilisables dans Draft 2020-12?
Sous $defs. L'ancienne clé definitions fonctionne toujours, mais indique un ancien draft. Fixez toujours $schema afin que le validateur applique le draft que vous avez prévu.
À titre d'information uniquement. Ne remplace pas une revue de schéma formelle ou des audits certifiés.