MémentoAuteur : D. Dambreville · didierdambreville.github.io · licence CC BY 4.0

JSON

JavaScript Object Notation · syntaxe · modélisation · API · JSON Schema · jq · programmation
"titre" chasse fixe, gras : texte à écrire tel quel
fichier italique : valeur à remplacer
✓ valide  ·  ✗ invalide
Maj+Alt+F touche ou combinaison de touches
! piège fréquent

Qu’est-ce que JSON ?

  • JSON (JavaScript Object Notation) : format texte d’échange de données structurées, lisible par l’humain comme par la machine.
  • Issu de la syntaxe de JavaScript, mais indépendant de tout langage : tous savent le lire et l’écrire.
  • Normes : RFC 8259 (IETF, 2017) et ECMA-404 — même grammaire.
  • Type de média application/json · extension .json.
  • Encodage UTF-8 obligatoire entre systèmes ; sans BOM (marque d’ordre des octets).

Où le rencontre-t-on ?

  • API web : requêtes et réponses des services en ligne.
  • Configuration : package.json, settings.json de VS Code…
  • Stockage : bases documentaires, colonnes jsonb de PostgreSQL, journaux, carnets Jupyter.

Les six types de valeurs

objet{"nom": "Eve"}clés → valeurs, sans ordre
tableau[1, "a", null]liste ordonnée
chaîne"texte"guillemets doubles, Unicode
nombre42 · -3.5 · 6.02e23un seul type numérique
booléentrue · falseminuscules, sans guillemets
nulnullabsence de valeur

Objets et tableaux contiennent d’autres valeurs et s’imbriquent librement. Ni date, ni binaire (page 2).

Compact ou indenté

{"titre":"Candide","tags":["conte"]}
{
  "titre": "Candide",
  "tags": [
    "conte"
  ]
}

Même donnée : les espaces entre les éléments n’ont aucun sens. Compact pour transmettre, indenté pour lire.

Repères

2000–2002format décrit et diffusé par Douglas Crockford (site json.org)
2006RFC 4627 : première spécification de l’IETF
2014RFC 7159 : toute valeur admise à la racine
2017RFC 8259 (norme Internet STD 90) et ECMA-404, 2e édition : UTF-8 obligatoire entre systèmes

Anatomie d’un document

{                                  1
  "titre": "Candide",              2
  "annee": 1759,                   3
  "disponible": true,              4
  "prix": null,                    
  "auteur": {                      5
    "nom": "Voltaire",             
    "naissance": 1694              6
  },                               
  "tags": ["conte", "philosophie"] 7
}                                  
  1. 1Objet racine, entre accolades { }.
  2. 2Membre : une clé (chaîne entre guillemets doubles), :, puis une valeur — ici une chaîne.
  3. 3Nombre : sans guillemets. Une virgule sépare les membres.
  4. 4Littéraux true, false, null : minuscules, sans guillemets.
  5. 5Une valeur peut être un objet imbriqué…
  6. 6Pas de virgule après le dernier membre.
  7. 7… ou un tableau : liste ordonnée entre crochets [ ].

Les dix règles d’or

  1. Chaînes et clés entre guillemets doubles : "nom", jamais 'nom'.
  2. Toute clé est une chaîne : {"a": 1}, jamais {a: 1}.
  3. Une virgule entre deux éléments, jamais après le dernier.
  4. Deux-points entre la clé et sa valeur.
  5. true, false, null en minuscules, sans guillemets.
  6. Ni undefined, ni NaN, ni Infinity, ni fonction.
  7. Nombres en base 10, sans + initial ni zéro de tête.
  8. Dans une chaîne, échapper ", \ et les caractères de contrôle.
  9. Aucun commentaire : ni // ni /* */.
  10. Une seule valeur racine ; des clés uniques dans chaque objet.

L’ordre des clés d’un objet ne porte aucun sens ; l’ordre des éléments d’un tableau, si.

Déboguer un JSON invalide

  1. Indenter pour voir la structure : jq . f, py -m json.tool f, ou Maj+Alt+F dans VS Code.
  2. Lire la position donnée par le message : ligne, colonne ou caractère.
  3. Regarder juste avant : l’erreur réelle précède souvent l’endroit signalé.
  4. Vérifier dans l’ordre : virgules, guillemets, paires { } et [ ], littéraux.
  5. Fichier venu d’ailleurs : BOM en tête ? encodage autre qu’UTF-8 ?

Messages d’erreur types : page 6.

Erreurs fréquentes

✗ faux✓ correct
{'a': 1}{"a": 1}
{a: 1}{"a": 1}
[1, 2, 3,][1, 2, 3]
{"a": 1 "b": 2}{"a": 1, "b": 2}
{"ok": True}{"ok": true}
{"x": None}{"x": null}
{"x": undefined}{"x": null}
{"n": NaN}{"n": null}
{"n": 007}{"n": 7}
{"n": .5}{"n": 0.5}
{"n": 1,5}{"n": 1.5}
"C:\dossier""C:\\dossier"
{"a":1}{"b":2}[{"a":1},{"b":2}]
{"a": 1} // note{"a": 1}

Atouts et limites

Atouts

  • Grammaire minuscule : six types, quelques signes.
  • Lisible à l’œil nu, facile à écrire à la main.
  • Natif dans les navigateurs ; analyseurs dans tous les langages.
  • Plus léger que XML pour la plupart des données.

Limites

  • Ni commentaires, ni dates, ni binaire.
  • Précision des nombres laissée aux analyseurs.
  • Clés répétées dans chaque objet : volumineux en masse.
  • Aucune validation intégrée : il faut un schéma (page 4).

Vocabulaire

membreune paire "clé": valeur dans un objet
clé · nomla chaîne qui désigne une valeur
élémentune valeur dans un tableau
racinela valeur qui englobe tout le document
sérialiserdonnées en mémoire → texte JSON (encoder)
désérialisertexte JSON → données (analyser, parser)
analyseurprogramme qui lit et vérifie le JSON (parser)
indentermettre en forme avec retraits ; l’inverse : minifier
bien forméconforme à la grammaire JSON
valideconforme, en plus, à un schéma (page 4)

2 · Syntaxe en détail

Mémento — JSON

Objets

{}objet vide
{"a": 1, "b": 2}deux membres séparés par une virgule
{"prénom": "Anne"}clé libre : accents, espaces, symboles permis
{"": 0}même la clé vide est permise
{"a": 1, "a": 2}! clé en double : « devrait » être unique (RFC 8259)

Clés en double : la plupart des analyseurs gardent la dernière valeur (Python, JavaScript) ; d’autres signalent une erreur ou conservent toutes les paires. Résultat imprévisible : les proscrire.

Ordre des membres sans signification : {"a":1,"b":2} = {"b":2,"a":1}. Ne jamais s’y fier.

Tableaux

[]tableau vide
[1, 2, 3]éléments ordonnés : [3, 2, 1] est un autre tableau
["a", 1, true, null]types mêlés : permis, mais à éviter
[[1, 2], [3, 4]]tableaux imbriqués (matrice)
[{"id": 1}, {"id": 2}]tableau d’objets : la forme d’une table de données

Chaînes et échappements

\"guillemet double
\\barre oblique inverse
\/barre oblique (facultatif : / suffit)
\n · \rsaut de ligne · retour chariot
\ttabulation
\b · \fretour arrière · saut de page
\u00e9caractère Unicode en 4 chiffres hexadécimaux : é
\ud83d\ude00au-delà de U+FFFF : paire de substitution (ici un émoji)

À échapper obligatoirement : le guillemet ", la barre oblique inverse \ et les caractères de contrôle U+0000 à U+001F (saut de ligne, tabulation…).

! Invalides : \' \x41 \0 \a. Pas de retour à la ligne brut dans une chaîne : écrire \n.

En UTF-8, "été" et "\u00e9t\u00e9" sont la même chaîne.

Chemins Windows : "C:\\Users\\docs" — ou "C:/Users/docs", accepté par la plupart des programmes.

Espaces, racine, limites

  • Espaces permis entre les éléments : espace, tabulation, saut de ligne, retour chariot — et eux seuls.
  • Retrait conventionnel : 2 ou 4 espaces. Une ligne vide finale est d’usage, non requise.
  • La racine peut être n’importe quelle valeur : 42 ou "ok" forment un document JSON (RFC 8259) ; d’anciens analyseurs n’acceptent qu’un objet ou un tableau.
  • Taille, profondeur, longueur des chaînes : chaque analyseur fixe ses propres limites.

Toute la grammaire

valeur   = objet / tableau / chaîne / nombre
         / "true" / "false" / "null"
objet    = "{" [ membre *( "," membre ) ] "}"
membre   = chaîne ":" valeur
tableau  = "[" [ valeur *( "," valeur ) ] "]"
chaîne   = guillemet *caractère guillemet
nombre   = [ "-" ] entier [ fraction ] [ exposant ]
entier   = "0" / ( chiffre-1-à-9 *chiffre )
fraction = "." 1*chiffre
exposant = ( "e" / "E" ) [ "-" / "+" ] 1*chiffre

Notation ABNF simplifiée d’après RFC 8259 : / ou · [ ] facultatif · * zéro, une ou plusieurs fois · 1* au moins une fois. Des espaces peuvent entourer chaque signe { } [ ] : ,.

Nombres

-signe
facultatif
12partie
entière
.75fraction
facultative
e+3exposant
facultatif
✓ valides0-0423.14-0.51e101E-32.5e+8
✗ invalides+101.55.1.e30x1F1_0001,5NaNInfinity

Un seul type numérique : 1, 1.0 et 1e0 expriment la même quantité ; certains langages les distinguent (Python : int et float).

Précision

  • La norme ne fixe aucune limite ; la plupart des analyseurs utilisent des doubles IEEE 754 (64 bits).
  • Entiers exacts garantis de −(253−1) à 253−1 = 9007199254740991 (RFC 8259, § 6).
  • ! Au-delà, arrondi silencieux : en JavaScript, 9007199254740993 devient 9007199254740992.
  • Réels : arrondi binaire — 0.1 + 0.2 donne 0.30000000000000004.
  • → Identifiants longs en chaîne ; montants en centimes entiers ou en chaîne décimale : "19.90".

Ce que JSON ne sait pas représenter

BesoinConvention usuelle
date, heurechaîne ISO 8601 : "2026-09-29T14:30:00Z"
duréechaîne ISO 8601 "PT1H30M", ou nombre + unité dans le nom : "dureeSec": 5400
binaire (image…)chaîne Base64, ou lien vers le fichier
commentaireclé dédiée "_note" ; ou format JSONC / JSON5 (page 3)
undefinedomettre la clé, ou null
grand entier, décimal exactchaîne : "12345678901234567890"
référence, cycleidentifiant : "auteurId": "a-42"
type d’objetchamp discriminant : "type": "livre"

JSON n’est pas JavaScript

JavaScript accepteJSON exige
{nom: 'Candide'}{"nom": "Candide"}
[1, 2,][1, 2]
// commentaire— (aucun commentaire)
undefined · NaN · Infinitynull, ou une chaîne
new Date()"2026-09-29T14:30:00Z"

! Ne jamais lire du JSON avec eval() : exécution de code arbitraire. Utiliser JSON.parse().

Unicode et encodage

  • Texte JSON échangé : UTF-8, sans BOM ; un analyseur peut ignorer un BOM reçu, sans y être tenu.
  • Tout caractère Unicode peut figurer tel quel dans une chaîne, sauf ", \ et les caractères de contrôle.
  • ! Même aspect, octets différents : « é » s’écrit en un point de code (U+00E9) ou en deux (e + accent combinant U+0301). Normaliser (NFC) avant de comparer clés et valeurs.
  • Longueur d’une chaîne : un émoji compte 2 en JavaScript (UTF-16), 1 en Python.

Comparer deux documents

  • Même donnée, textes différents : ordre des clés, espaces, 1.0 et 1, "\u00e9" et "é".
  • Comparer les données, pas le texte : jq -S . a.json > a2.json, idem pour b, puis diff a2.json b2.json.
  • Signature, empreinte (hachage) : sérialisation canonique JCS (RFC 8785) — clés triées, forme des nombres et des chaînes fixée.

3 · Modéliser et échanger

Mémento — JSON

Exemple : une ressource bien conçue

{
  "id": "cmd-2026-00042",
  "statut": "expediee",
  "creeLe": "2026-09-29T14:30:00Z",
  "client": { "id": "c-1187", "nom": "Exemple SARL" },
  "lignes": [
    { "sku": "LIV-001", "quantite": 2, "prix": "12.50" },
    { "sku": "LIV-007", "quantite": 1, "prix": "8.00" }
  ],
  "total": { "montant": "33.00", "devise": "EUR" },
  "remarque": null
}

Identifiants en chaînes · statut lisible · date ISO avec fuseau · montants exacts avec devise · clé remarque présente mais vide.

Règles de conception

  • Un seul style de nommage : camelCase (dateCreation) ou snake_case (date_creation) ; clés sans accent ni espace.
  • Un champ, un type : quantite est toujours un nombre, jamais tantôt 2, tantôt "2".
  • Listes : nom au pluriel ; tableau vide [] plutôt que null.
  • Booléens nommés comme une question : estActif, enStock.
  • Unité dans le nom : poidsKg, dureeSec, tailleOctets.
  • Énumérations en chaînes lisibles : "statut": "expediee" plutôt que "statut": 3.
  • Dates ISO 8601 avec fuseau : Z (UTC) ou +02:00.
  • Montants : valeur exacte et code de devise ISO 4217 (EUR, USD).
  • Imbrication modérée : au-delà de trois ou quatre niveaux, aplatir ou référencer.
  • ! Clé absente (non fournie) et valeur null (vide) ne disent pas la même chose : fixer la convention et la documenter.

Objet ou tableau ?

une chose et ses propriétésobjet : {"titre": …, "annee": …}
une liste ordonnéetableau : […]
des enregistrementstableau d’objets : [{…}, {…}]
un accès par cléobjet indexé : {"fr": "Bonjour", "en": "Hello"}
un couple de taille fixetableau court, ordre documenté : [2.35, 48.85]

! GeoJSON (RFC 7946) écrit les positions [longitude, latitude] : l’inverse de l’usage courant.

La famille JSON

JSON Linesun document par ligne (.jsonl, dit aussi NDJSON) : journaux, gros volumes, flux
JSONCJSON + commentaires : settings.json de VS Code
JSON5+ commentaires, virgules finales, guillemets simples, clés nues
GeoJSONlieux et géométries (RFC 7946)
JSON-LDdonnées liées (W3C) ; balisage schema.org des pages web
I-JSONprofil strict pour l’interopérabilité (RFC 7493)
BSON · CBOR · MessagePackéquivalents binaires, plus compacts

Faire évoluer un format

  • Listes : envelopper le tableau dans un objet — {"donnees": […], "suivant": …} — pour ajouter plus tard pagination et métadonnées sans rien casser.
  • Ajouter un champ facultatif : sans risque. Retirer, renommer ou changer le type d’un champ : rupture → nouvelle version.
  • Clients tolérants : ignorer les champs inconnus au lieu d’échouer.

JSON sur HTTP (API web)

Content-Type: application/jsonle corps envoyé est du JSON
Accept: application/jsonle client demande du JSON en réponse

Codes de réponse utiles

200 · 201succès · ressource créée (en-tête Location)
204succès sans corps : rien à analyser
400requête mal formée — par exemple JSON invalide
401 · 403non authentifié · non autorisé
404 · 409ressource introuvable · conflit avec l’état actuel
415type de média refusé : vérifier Content-Type
422JSON bien formé, mais données refusées
429 · 500trop de requêtes : ralentir · erreur du serveur

charset=utf-8 est superflu : JSON est en UTF-8 et RFC 8259 ne définit aucun paramètre charset.

Décrire une erreur : RFC 9457

{
  "type": "https://example.com/erreurs/stock",
  "title": "Stock insuffisant",
  "status": 409,
  "detail": "Il reste 1 exemplaire de LIV-007.",
  "instance": "/commandes/cmd-2026-00042"
}
typeURI de la catégorie d’erreur (par défaut : about:blank)
titlerésumé lisible, identique pour toute la catégorie
statuscode HTTP
detail · instanceexplication · URI propres à cette occurrence

Type de média : application/problem+json. Des membres supplémentaires sont permis.

Désigner et modifier une partie

JSON Pointer (RFC 6901)

""le document entier
/lignes/0/skuclé lignes, élément 0, clé sku → "LIV-001"
~0 · ~1~ et / à l’intérieur d’un nom de clé

JSON Patch (RFC 6902) · application/json-patch+json

[
  { "op": "test", "path": "/statut", "value": "expediee" },
  { "op": "replace", "path": "/statut", "value": "livree" },
  { "op": "add", "path": "/lignes/-",
    "value": { "sku": "LIV-009", "quantite": 1 } },
  { "op": "remove", "path": "/remarque" }
]

Opérations : add remove replace move copy test, appliquées dans l’ordre ; si l’une échoue, le patch entier échoue. /lignes/- : après le dernier élément.

JSON Merge Patch (RFC 7396) · application/merge-patch+json

On envoie un objet partiel : ses membres remplacent ceux de la cible, null supprime la clé, un tableau est remplacé en entier. Ex. {"statut": "livree", "remarque": null}.

JSON face aux autres formats

FormatForcesLimites
JSONsimple, universel, natif du webni commentaires ni dates
XMLattributs, espaces de noms, documentsverbeux, lourd à traiter
YAMLtrès lisible, commentaires ; lit le JSON (YAML 1.2)indentation significative, typage piégeux
TOMLconfiguration claire, dates nativespeu fait pour l’imbrication profonde
CSVtableaux plats, tableursni types ni imbrication

4 · JSON Schema : décrire et valider

Mémento — JSON

À quoi sert un schéma ?

  • Décrire la structure attendue : types, champs obligatoires, valeurs permises.
  • Valider automatiquement données reçues, fichiers de configuration, réponses d’API.
  • Documenter, générer formulaires, code et tests ; OpenAPI 3.1 décrit les données des API en JSON Schema.
  • Un schéma est lui-même un document JSON. Version en vigueur : 2020-12 (précédente : 2019-09).

Exemple : le schéma de la commande (page 3)

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/schemas/commande.json",
  "title": "Commande",
  "type": "object",
  "required": ["id", "statut", "lignes"],
  "properties": {
    "id": { "type": "string", "pattern": "^cmd-\\d{4}-\\d{5}$" },
    "statut": {
      "enum": ["en-attente", "expediee", "livree", "annulee"]
    },
    "creeLe": { "type": "string", "format": "date-time" },
    "lignes": {
      "type": "array",
      "minItems": 1,
      "items": { "$ref": "#/$defs/ligne" }
    },
    "remarque": { "type": ["string", "null"], "maxLength": 500 }
  },
  "$defs": {
    "ligne": {
      "type": "object",
      "required": ["sku", "quantite"],
      "properties": {
        "sku": { "type": "string", "minLength": 1 },
        "quantite": { "type": "integer", "minimum": 1 },
        "prix": { "$ref": "#/$defs/decimal" }
      },
      "additionalProperties": false
    },
    "decimal": { "type": "string", "pattern": "^\\d+\\.\\d{2}$" }
  }
}

Dans une chaîne JSON, la barre oblique inverse d’une expression régulière se double : \\d pour \d.

Ce que le schéma accepte ou refuse

DonnéeRésultat
la commande de la page 3✓ valide
"quantite": 0✗ minimum : 0 < 1
"quantite": 2.5✗ type : pas un entier
"statut": "Livree"✗ enum : la casse compte
"lignes": []✗ minItems
ligne avec "couleur": "rouge"✗ additionalProperties
sans "id"✗ required
"prix": "12.5"✗ pattern : deux décimales
"creeLe": "29/09/2026"✓ en général ! format n’est qu’une annotation
clé inconnue "urgent": true à la racine✓ racine sans additionalProperties: false

Outils

ajvvalidateur JavaScript (Node.js), le plus répandu
jsonschemaPython : validate(instance=doc, schema=s)
check-jsonschemaligne de commande, intégration continue
VS Codevalide pendant la saisie si le fichier déclare "$schema", ou via le réglage json.schemas
SchemaStore.orgcatalogue de schémas des fichiers de configuration courants

Mots-clés essentiels

Tous types

type"string" "number" "integer" "boolean" "object" "array" "null" — ou une liste : ["string", "null"]
enum · constvaleurs permises · valeur imposée
title · description · defaultdocumentation ; ! default ne remplit aucune valeur

Chaînes

minLength · maxLengthlongueur en caractères
patternexpression régulière (ECMA-262), non ancrée
formatdate-time date time duration email uri uuid ipv4 ipv6 hostname…

Nombres

minimum · maximumbornes incluses
exclusiveMinimumborne exclue (un nombre) ; idem exclusiveMaximum
multipleOfmultiple de : 0.01, 5…

Objets

propertiesschéma de chaque clé déclarée
requiredliste des clés obligatoires
additionalPropertiesclés non déclarées ; false : interdites
patternPropertiesschéma des clés qui suivent un motif
minProperties · maxPropertiesnombre de clés ; propertyNames : contraintes sur leurs noms
dependentRequiredsi la clé A est présente, B devient obligatoire
unevaluatedPropertiescomme additionalProperties, mais voit à travers allOf, $ref…

Tableaux

itemsschéma de chaque élément
prefixItemsschémas des premiers éléments, rang par rang (n-uplet)
minItems · maxItemsnombre d’éléments
uniqueItemstrue : aucun doublon
containsau moins un élément conforme (minContains, maxContains)

Combiner et réutiliser

allOfconforme à tous les sous-schémas
anyOfconforme à au moins un
oneOfconforme à exactement un
notnon conforme
if · then · elsevalidation conditionnelle
$defs · $refdéfinitions réutilisables : "$ref": "#/$defs/ligne" (JSON Pointer)
$schema · $idversion du langage · identifiant du schéma

Pièges

  • Sans additionalProperties: false, une clé mal orthographiée ("quantitee") passe inaperçue.
  • required se place dans l’objet parent, pas dans la propriété.
  • pattern non ancré : "[0-9]+" accepte "abc1" → écrire "^[0-9]+$".
  • format n’est qu’une annotation par défaut : activer son contrôle dans le validateur.
  • integer accepte 1.0 : un nombre sans partie décimale est un entier.
  • oneOf échoue si deux branches conviennent : anyOf suffit souvent.
  • Anciens schémas (draft-04, draft-07) : definitions → $defs ; items en liste → prefixItems ; exclusiveMinimum booléen → nombre.

5 · jq et autres outils

Mémento — JSON

jq : lire et filtrer

jqcommande
-roptions
'.livres[0].titre'filtre
livres.jsonfichier

Sans fichier, jq lit l’entrée standard. | enchaîne les filtres, comme dans le shell.

Fichier d’exemple : livres.json

{ "livres": [
  { "titre": "Candide", "auteur": "Voltaire",
    "annee": 1759, "tags": ["conte", "philosophie"] },
  { "titre": "Notre-Dame de Paris", "auteur": "Hugo",
    "annee": 1831, "tags": ["roman"] },
  { "titre": "Les Misérables", "auteur": "Hugo",
    "annee": 1862, "tags": ["roman"] }
] }
.tout le document, indenté et coloré
.livres[0].titre"Candide"
.livres[-1].annee1862 (dernier élément)
.livres[].titreles trois titres, un par ligne
.livres | length3
.livres[0] | keys["annee", "auteur", …] (triées)
.livres[0].prix // "inconnu"clé absente → null, sans erreur ; // : valeur de repli
.livres[] | select(.auteur == "Hugo") | .titreles deux titres de Hugo
.livres[] | select(any(.tags[]; . == "roman"))les romans
.livres | map(.titre)["Candide", …] : un tableau
[.livres[].annee] | add / length1817.33… : la moyenne
.livres | group_by(.auteur) | map({auteur: .[0].auteur, n: length})[{"auteur": "Hugo", "n": 2}, …]
.. | .titre? // emptytoutes les clés titre, à toute profondeur
.livres[] | "\(.titre) (\(.annee))"avec -r : Candide (1759)…

jq : fonctions utiles

if .annee < 1800 then "ancien" else "moderne" endcondition
select(.titre | test("^les"; "i"))expression régulière (i : sans casse)
ascii_downcase · split(" ") · join(", ")traiter les chaînes
unique · flatten · min_by(f) · addtraiter les tableaux

Recettes

jq . brut.json > joli.jsonindenter (-c : compacter)
jq empty f.json && echo "valide"valider (code de retour)
jq -c '.[]' t.json > f.jsonltableau → JSON Lines
jq -s . f.jsonlJSON Lines → tableau
jq -r '.[] | [.a, .b] | @csv' f.jsonexporter en CSV
jq -s '.[0] * .[1]' a.json b.jsonfusion profonde de deux objets

! Sous Windows PowerShell 5.1, les guillemets doubles d’un filtre sont mal transmis : mettre le filtre dans un fichier (jq -f) ou utiliser Git Bash.

Gros volumes

  • Traiter en flux, sans tout charger en mémoire : JSON Lines, jq --stream, ijson (Python).
  • Réduire le volume : gzip (très efficace sur JSON) ou format binaire (CBOR, MessagePack).

jq : options

-rchaînes brutes, sans guillemets (pour les scripts)
-csortie compacte : un document par ligne
-sréunir toutes les entrées dans un tableau (slurp)
-nne rien lire : construire du JSON de toutes pièces
-Strier les clés
-ecode de retour selon le résultat (false, null → 1)
-Rlire du texte brut : chaque ligne devient une chaîne
-f fichierlire le filtre dans un fichier
--arg n vvariable $n : une chaîne
--argjson n vvariable $n : une valeur JSON
--indent n · --tabretrait de n espaces · tabulations

jq : transformer

.livres[0].prix = 12ajouter ou remplacer une valeur
.livres[].annee |= tostringmodifier sur place
del(.livres[].tags)supprimer une clé partout
.livres |= sort_by(.titre)trier le tableau en place
.livres[] | {titre, annee}ne garder que certaines clés
with_entries(.key |= ascii_upcase)renommer les clés
to_entries · from_entriesobjet ↔ [{"key": …, "value": …}]
.livres[] | [.titre, .annee] | @csvligne CSV (avec -r)
@tsv · @base64 · @uri · @htmlautres encodages de sortie

Autres outils

py -m json.tool fvalider et indenter (Python) ; python3 sous Linux ; -m json depuis Python 3.14
curl --json '{"a": 1}' urlPOST en JSON, en-têtes Content-Type et Accept posés (curl ≥ 7.82) ; --json @f.json : depuis un fichier
curl -s url | jq '.data[].id'interroger une API et filtrer
Maj+Alt+FVS Code : formater ; validation par schéma, repli des blocs
Firefoxvisionneuse JSON intégrée : replier, filtrer, JSON brut
gronaplatit en lignes json.livres[0].titre = "Candide"; → grep

Options de json.tool : --sort-keys, --compact, --no-ensure-ascii, --json-lines.

PowerShell

$d = Get-Content f.json -Raw | ConvertFrom-Jsonfichier → objets
$d.livres[0].titrenaviguer avec des points
$d | ConvertTo-Json -Depth 10objets → JSON
Invoke-RestMethod urlappel d’API : la réponse JSON devient un objet
ConvertFrom-Json -AsHashtable · Test-JsonPowerShell 7 (absents de la 5.1)

! ConvertTo-Json s’arrête à la profondeur 2 par défaut : plus bas, les objets deviennent du texte ("System.Collections.Hashtable") → toujours préciser -Depth.

! @(1) | ConvertTo-Json donne 1 : le pipeline déroule le tableau. ConvertTo-Json -InputObject @(1) donne [1].

! Windows PowerShell 5.1 : curl y désigne Invoke-WebRequest → taper curl.exe.

6 · Programmer avec JSON

Mémento — JSON

JavaScript

const obj = JSON.parse(texte);      // texte → valeur
const txt = JSON.stringify(obj);    // valeur → texte
JSON.stringify(obj, null, 2);       // indenté
JSON.stringify(obj, ["id", "nom"]); // ces clés seules
const d = JSON.parse(texte, (cle, val) =>  // « reviver »
  cle === "creeLe" ? new Date(val) : val);
const rep = await fetch(url);       // API web
const data = await rep.json();
undefined · fonction · Symbolclé omise ; dans un tableau : null
NaN · Infinitynull
Datechaîne ISO : "2026-09-29T14:30:00.000Z"
Map · Set{} : contenu perdu
-00
BigInt · objet cycliqueerreur TypeError
toJSON()si l’objet la définit, sa valeur de retour est sérialisée

Ce que devient chaque valeur avec JSON.stringify (ci-dessus). Au retour, JSON.parse rend les dates en chaînes (les convertir avec un reviver) et arrondit les entiers au-delà de 253.

Python

import json

with open("f.json", encoding="utf-8") as f:
    data = json.load(f)                 # fichier → objets

texte = json.dumps(data, ensure_ascii=False, indent=2)
data = json.loads(texte)                # chaîne → objets

with open("sortie.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)
JSONPython
objetdict
tableaulist (un tuple devient aussi un tableau)
chaînestr
nombre entier · à virguleint · float
true · false · nullTrue · False · None
  • ensure_ascii=True par défaut : é s’écrit \u00e9 → ensure_ascii=False.
  • ! NaN et Infinity acceptés et produits par défaut, hors norme → allow_nan=False.
  • Clés converties en chaînes : {1: "a"} → {"1": "a"} ; l’aller-retour ne rend pas l’original.
  • datetime, Decimal, set → TypeError : default=str, ou conversion explicite.
  • parse_float=Decimal : décimaux exacts. sort_keys=True : sortie stable, comparable.
  • Sous Windows, toujours encoding="utf-8" ; fichier avec BOM : "utf-8-sig".

Dates et heures

"2026-09-29"date seule (ISO 8601)
"2026-09-29T14:30:00Z"instant en UTC : la forme la plus sûre
"2026-09-29T16:30:00+02:00"même instant, avec décalage
1790692200même instant en secondes Unix (JavaScript compte en millisecondes)

! Sans fuseau, "2026-09-29T14:30:00" est ambiguë : JavaScript la lit en heure locale.

Autres langages

LangageLire · écrire
PHPjson_decode($s, true) · json_encode($v)
Java (Jackson)mapper.readValue(s, T.class) · mapper.writeValueAsString(v)
C# (.NET)JsonSerializer.Deserialize<T>(s) · JsonSerializer.Serialize(v)
Gojson.Unmarshal(b, &v) · json.Marshal(v)
Rust (serde_json)serde_json::from_str(s) · serde_json::to_string(&v)
PowerShellConvertFrom-Json · ConvertTo-Json -Depth 10
PostgreSQLdoc->>'titre' (texte) · jsonb_build_object(…)
SQLitejson_extract(doc, '$.titre') · json_object(…)

PHP : options JSON_PRETTY_PRINT, JSON_UNESCAPED_UNICODE, JSON_THROW_ON_ERROR (à combiner par |). Go : seuls les champs exportés (majuscule) sont sérialisés ; nom JSON fixé par la balise json:"titre".

Messages d’erreur courants

Python 3.14 · Node.js 24Cause probable
Expecting property name enclosed in double quotes
Expected property name or '}'
clé sans guillemets, ou entre guillemets simples
Illegal trailing comma before end of object
Expected double-quoted property name
virgule finale
Expecting ',' delimiter
Expected ',' or '}' after property value
virgule manquante, ou nombre mal écrit (007, 1.)
Expecting value
Unexpected token 'T', "{"ok": True}" is not valid JSON
valeur invalide : True, None, NaN (JS), 'x', .5…
Expecting value: line 1 column 1 (char 0)
Unexpected token '<', "<!DOCTYPE "…
réponse vide, ou page HTML reçue au lieu de JSON : vérifier le statut HTTP
Invalid \escape
Bad escaped character in JSON
\ isolé : chemin C:\dossier
Invalid control character at
Bad control character in string literal
retour à la ligne brut dans une chaîne
Extra data
Unexpected non-whitespace character after JSON
texte après la fin : documents collés, } en trop
Unexpected UTF-8 BOM (decode using utf-8-sig)
Unexpected token '', …
BOM (invisible) en tête du fichier
—
Unexpected end of JSON input
texte vide ou tronqué (réponse 204…)

Messages suivis de la position : line 1 column 9 (char 8) · at position 8 (line 1 column 9). Les libellés varient selon les versions.

Sécurité

  • Données reçues = non fiables : valider types, bornes et structure (schéma) avant usage.
  • Jamais eval() pour lire du JSON : JSON.parse, json.loads.
  • ! Ne jamais fabriquer du JSON par concaténation de chaînes : un guillemet dans une valeur casse ou détourne le document. Toujours passer par le sérialiseur.
  • Limiter taille et profondeur : un document démesuré ou très imbriqué épuise mémoire ou pile (Python : RecursionError).
  • Clés en double : deux analyseurs peuvent retenir des valeurs différentes et contourner un contrôle → les refuser.
  • JavaScript : fusion récursive d’objets reçus → pollution de prototype par les clés __proto__, constructor, prototype.
  • JSON inséré dans une page HTML : échapper < en \u003c pour neutraliser </script>.
  • Aucun secret (mot de passe, clé d’API, jeton) dans un JSON versionné : variables d’environnement ou coffre-fort.