Qu'est-ce que le format JSON ?
Le JSON (JavaScript Object Notation) est un format de texte qui écrit des données structurées avec des accolades, des crochets et des paires nom-valeur. Presque toutes les API web l'utilisent pour envoyer et recevoir des données.
Savoir le lire, l'écrire et le vérifier évite de longues heures à chercher pourquoi une application refuse une donnée.
À la fin de cette leçon
Remarque
Je peux lire, écrire et vérifier un texte JSON.
Mots clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| JSON | un format de texte pour des données structurées | |
| Objet | un ensemble de paires nom-valeur entre accolades | {"id": 1} |
| Tableau | une liste de valeurs entre crochets | [1, 2, 3] |
| Type | la sorte d'une valeur : texte, nombre, booléen ou null | |
| Champ | une paire nom-valeur dans un objet | |
| Validation | vérifier qu'une donnée respecte les règles attendues |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Un objet et un tableau décrivent tout
Un objet écrit des champs entre accolades : un nom entre guillemets, deux-points, puis la valeur. Un tableau écrit une liste entre crochets, avec des virgules.
Une valeur est d'un des six types du tableau ci-dessous. Un objet peut contenir un tableau, et un tableau des objets.
Exemple : les six sortes de valeurs
| Type JSON | Exemple | Son équivalent en Python |
|---|---|---|
| Texte | "Germinal" | str |
| Nombre | 1885 ou 4.5 | int ou float |
| Booléen | true ou false | bool (True ou False) |
| Vide | null | None |
| Objet | {"id": 1} | dict |
| Tableau | [1, 2, 3] | list |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Préparer le catalogue et lire un livre
Le serveur du laboratoire répond en JSON. Préparez d'abord la table livres : le Run peut être relancé pour repartir de zéro.
Lisez ensuite un livre en entier, puis seulement deux champs. Repérez le texte, les nombres, le booléen et le null.
Créer la table des livres
PGPASSWORD=shop psql -q -h db -U shop -c "set client_min_messages to warning; drop table if exists livres; create table livres (id serial primary key, titre text not null unique, auteur text not null, annee integer not null, exemplaires integer not null default 1 check (exemplaires >= 0), disponible boolean not null default true, resume text); insert into livres (titre, auteur, annee, exemplaires, disponible) values ('Germinal', 'Emile Zola', 1885, 3, true), ('Candide', 'Voltaire', 1759, 0, false), ('Madame Bovary', 'Gustave Flaubert', 1857, 2, true), ('La Peste', 'Albert Camus', 1947, 4, true), ('Bel-Ami', 'Guy de Maupassant', 1885, 1, true); notify pgrst, 'reload schema'"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Lire le livre numéro 1
curl -s -w "\n" "http://api:3000/livres?id=eq.1"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Ne garder que deux champs
curl -s -w "\n" "http://api:3000/livres?id=eq.1&select=titre,resume"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Python lit et écrit du JSON
json.loads(texte) transforme un texte JSON en dictionnaire ou en liste. json.dumps(valeur) fait le chemin inverse. Les noms des champs deviennent des clés.
Lancez le code, puis changez l'année et relancez.
Exemple : lire puis réécrire un livre
import json
texte = '{"titre": "Germinal", "annee": 1885, "disponible": true, "resume": null}'
livre = json.loads(texte)
print(livre["titre"], livre["annee"] + 1)
print(livre["disponible"], livre["resume"])
# Changez l'année, puis écrivez de nouveau le texte JSON.
livre["annee"] = 1886
print(json.dumps(livre))
Valider une donnée avant de l'accepter
Une API ne croit jamais ce qu'on lui envoie. Elle vérifie que le champ est présent, que son type est le bon et que sa valeur reste dans les limites.
Un texte qui n'est pas du JSON fait échouer json.loads avec une erreur. On l'attrape avec try et except ValueError, puis on répond que la donnée est invalide.
Exemple : vérifier le type d'un champ
import json
def texte_plein(valeur):
return isinstance(valeur, str) and valeur != ""
def entier(valeur):
# True est aussi un nombre entier pour Python : on l'écarte.
return isinstance(valeur, int) and not isinstance(valeur, bool)
try:
livre = json.loads('{"titre": "Candide", "annee": true}')
except ValueError:
livre = {}
print(texte_plein(livre["titre"]))
print(entier(livre["annee"]))
Une erreur fréquente
Attention
Beaucoup pensent qu'un nombre entre guillemets reste un nombre. Faux : "1885" est un texte. Un serveur strict le refuse, un serveur souple le convertit. Dans les deux cas, vérifiez le type avant de calculer.
Envoyer une année qui est un mot
curl -s -o /dev/null -w "%{http_code}\n" -X POST -H "Content-Type: application/json" -d '{"titre":"Test","auteur":"X","annee":"mille"}' "http://api:3000/livres"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Envoyer un texte qui n'est pas du JSON
curl -s -o /dev/null -w "%{http_code}\n" -X POST -H "Content-Type: application/json" -d '{"titre":' "http://api:3000/livres"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Envoyer un champ que la table n'a pas
curl -s -o /dev/null -w "%{http_code}\n" -X POST -H "Content-Type: application/json" -d '{"titre":"Test","auteur":"X","annee":1900,"pages":300}' "http://api:3000/livres"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.