Travailler avec le JSON imbriqué : aplanir, interroger et transformer les données
JSON imbrique des objets dans des objets, des tableaux dans des objets et des objets dans des tableaux, parce que les programmes modélisent les données ainsi. Les tableurs, fichiers CSV et tables SQL n'imbriquent rien ; ils ont deux dimensions, lignes et colonnes. L'aplatissement fait le pont entre les deux, et l'essentiel du travail avec du JSON imbriqué consiste à savoir quand aplatir et quand laisser la structure telle quelle.
Pourquoi le JSON profondément imbriqué résiste aux tableurs et à SQL
Un objet JSON avec trois niveaux d'imbrication et un tableau enfoui n'a pas de correspondance ligne/colonne évidente. Quel champ devient une colonne, et que faire d'un champ qui se répète pour chaque élément du tableau ? Collez du JSON imbriqué dans un convertisseur « JSON vers CSV » naïf ou dans l'import JSON d'Excel, et il abandonne les champs imbriqués ou les déverse dans une seule cellule sous forme de blob textuel. Les deux issues jettent la structure sur laquelle vous vouliez filtrer, trier ou interroger.
Ce n'est pas tant un échec d'outillage qu'un véritable décalage de représentation : le JSON imbriqué encode un arbre, et un tableur ou une table SQL encode une liste plate d'enregistrements. Passer de l'un à l'autre exige une décision explicite sur la façon de gérer ce décalage, pas une simple conversion de format.
Ce que signifie aplatir
Aplatir transforme une structure imbriquée en un objet à un seul niveau où chaque chemin imbriqué devient une clé, jointe par un point (`user.address.city`) ou écrite en notation crochets (`user[address][city]`). Les éléments de tableau reçoivent un index dans le chemin (`roles.0`, `roles.1`), et la liste devient un ensemble de clés adressables une à une. Le résultat n'a plus d'imbrication : chaque valeur est une chaîne, un nombre ou un booléen simple, et chaque clé désigne une seule valeur feuille du document d'origine.
Une colonne de tableur, une ligne SQL ou un simple magasin clé/valeur ont besoin de cette propriété : une clé par valeur feuille, aucune imbrication.
Un exemple concret
Prenons un enregistrement utilisateur imbriqué typique avec un objet adresse et un tableau de chaînes de rôles.
{
"user": {
"id": 42,
"name": "Ada Lovelace",
"address": {
"city": "London",
"postcode": "W1"
},
"roles": ["admin", "editor"]
}
}{
"user.id": 42,
"user.name": "Ada Lovelace",
"user.address.city": "London",
"user.address.postcode": "W1",
"user.roles.0": "admin",
"user.roles.1": "editor"
}Six clés, zéro imbrication, et chacune est un chemin sans ambiguïté vers une valeur d'origine. Vous pouvez les utiliser comme six colonnes de tableur ou six colonnes d'une seule ligne SQL.
Quand aplatir, quand conserver l'imbrication
Aplatissez quand la destination est tabulaire (un export CSV, un tableur, une ligne d'une table SQL, un outil d'analyse qui ne comprend que les colonnes plates) et quand les tableaux sont de courtes listes de scalaires (comme `roles` ci-dessus), où une clé numérotée par élément reste un compromis raisonnable.
Conservez l'imbrication, ou restructurez, quand un tableau contient des objets complets dont le nombre varie d'un enregistrement à l'autre. Prenez un tableau `orders` où chaque utilisateur a un nombre différent de commandes, chacune avec plusieurs champs. Aplatir cela sur place donne à chaque enregistrement un jeu de colonnes irrégulier et différent (`orders.0.total`, `orders.1.total`, ... `orders.14.total` pour votre plus gros client), ou écrase tout le tableau dans une cellule de JSON textuel, et l'aplatissement perd son intérêt. Pour les tableaux d'objets, appliquez la normalisation relationnelle classique : sortez le tableau dans sa propre table/feuille avec une clé étrangère vers l'enregistrement parent. L'outil JSON to Table de JsonForge le fait pour vous. Il aplatit les champs scalaires en colonnes et sépare les tableaux d'objets dans leurs propres tables liées au lieu de les défigurer en colonnes numérotées.
Accès par chemin : interroger sans tout aplatir
Parfois, vous voulez une seule valeur dans une structure profondément imbriquée, pas un document aplati. La notation à points (`user.address.city`) ou une expression de type JSONPath (`$.user.address.city`, `$.roles[0]`) adresse directement une valeur imbriquée. L'aplatissement applique cette idée au document entier ; un chemin l'applique à une seule recherche. `lodash.get(obj, 'user.address.city')`, l'interpolation de variables de la plupart des moteurs de gabarits et les outils de requête JSON fonctionnent ainsi.
Les deux techniques se complètent. L'outil JSON Flatten de JsonForge applique la transformation à points à tout un document d'un coup et change chaque valeur imbriquée en clé plate. Servez-vous-en quand la destination est un tableur, un simple magasin clé/valeur ou un outil incapable de parcourir des structures imbriquées.
FAQ
- En quoi aplatir diffère-t-il de textualiser les champs imbriqués ?
- Aplatir transforme chaque valeur imbriquée en sa propre clé scalaire de premier niveau, donc vous pouvez toujours interroger, trier et filtrer chaque valeur. Textualiser un champ imbriqué le réduit en un blob textuel opaque. Vous pouvez l'afficher, mais pas filtrer sur une valeur interne ni trier dessus sans réanalyser la chaîne. La textualisation repousse le problème que l'aplatissement résout.
- Comment les tableaux sont-ils représentés quand on aplatit du JSON ?
- La convention standard ajoute l'index du tableau au chemin, donc `roles: ["admin", "editor"]` devient `roles.0: "admin"` et `roles.1: "editor"`. Cela marche bien pour de courtes listes de scalaires à peu près fixes. Pour les tableaux dont la longueur varie beaucoup d'un enregistrement à l'autre, on obtient un ensemble de clés irrégulier et croissant, et une table liée séparée convient mieux.
- Un objet JSON aplati peut-il être reconverti en sa forme imbriquée d'origine ?
- Oui. Le « déplatissement » découpe chaque clé à points en ses parties et reconstruit les objets et tableaux imbriqués, à condition que vous ayez appliqué la convention de séparateur de façon cohérente et qu'aucune clé d'origine ne contienne un point littéral.
- La notation à points est-elle la seule façon de représenter une clé aplatie ?
- Non. La notation à points (`user.address.city`) est la plus courante car elle reflète la façon dont vous accéderiez à la valeur en JavaScript ou Python, mais la notation crochets (`user[address][city]`) et les clés jointes par tirets bas (`user_address_city`) sont aussi utilisées, en particulier par les outils ciblant des environnements où les points dans les noms de colonnes posent problème (certains dialectes SQL, certains tableurs). La convention importe moins que de l'appliquer de façon cohérente à tout le document.
Essayez ces outils
Articles associés
Qu'est-ce que JSON ? Le guide complet pour débutants →
JSON (JavaScript Object Notation) est un format d'échange de données léger, facile à lire pour les humains et à analyser pour les machines. Apprenez la syntaxe, les types de données et la structure qui font tourner les API modernes.
L'histoire de JSON : de 2000 au standard de l'industrie →
Suivez JSON depuis l'idée de Douglas Crockford en 2001, en passant par son adoption par Yahoo, jusqu'à devenir le standard ECMA-404 qui fait tourner 90 % des API modernes.
Le guide complet de JSON Schema (Draft 7) →
JSON Schema est le standard pour décrire et valider la structure JSON. Apprenez les mots-clés essentiels, construisez un véritable schéma d'API et appliquez les bonnes pratiques.