JSON pour les débutants
JSON est un format de données facilitant le stockage et l'échange de données entre tous langages de programmation. Louis Lazaris propose une introduction simple, mais détaillée, pour comprendre JSON et JSONP.
Si vous êtes nouveau dans le développement web, que vous avez des connaissances de HTML, CSS et même de JavaScript, JSON est important à connaître.
Même si vous connaissez déjà JSON et que vous l'avez utilisé dans un projet, il y a peut-être encore des choses que vous ne soupçonnez pas. Dans ce guide et tutoriel JSON, je vais essayer de présenter de manière approfondie JSON, son histoire et son utilité. Je terminerai avec une liste d'outils pratiques JSON qui pourront vous servir dans vos projets à venir.
Qu'est-ce que JSON ?
JSON (prononciation à la française /ʒi.sɔn/ ou /dʒej.sɔn/ , ou à l'anglaise /ˈdʒeɪˌsən/ (comme Jason Bourne !) signifie JavaScript Object Notation et c'est un format de données. Autrement dit, c'est une façon de stocker des informations, un peu comme une base de données. Bien que créé indépendamment de la spécification ECMAScript, il est maintenant lié à JavaScript qui inclut un objet JSON, et de nombreux développeurs l'incorporent quasiment comme un sous-ensemble du langage.
Voici un exemple de syntaxe JSON :
{
"espèce": "Dog",
"race": "Labrador Retriever",
"couleur": "Yellow",
"âge": 6
}
Comme vous le voyez, JSON est un format de données consistant en paires de nom/valeur (ou clé/valeur) ayant la forme de chaînes de caractères. Les nom et valeur sont séparés par deux points :
et chaque paire est séparée de la suivante par une virgule.
Bien que trouvant sa source dans JavaScript, beaucoup de langages de programmation (si ce n'est tous ?) peuvent générer et lire le format JSON. Il est donc devenu très populaire pour le stockage, la lecture et le partage d'information dans les applications et services web.
Une brève histoire de JSON
Douglas Crockford est l'inventeur de JSON et il maintient le site officiel JSON.org où il est présenté et discuté en détail. ( NdT : vous pouvez écouter Douglas Crockford raconter l'histoire de JSON dans cette vidéo YouYube, intéressante aussi pour comprendre certaines caractéristiques du format).
La première spécification officielle date de 2013, mais JSON remonte à bien plus loin. Le site web a été lancé en 2002, Yahoo et Google ont commencé à utiliser JSON dès 2005 et 2006 respectivement, et JSON a décollé à partir de là. L'article de wikipedia contient beaucoup de détails sur son histoire si vous voulez en savoir plus.
Différences entre JSON et JavaScript Object
Comme son nom l'indique, JSON est plus ou moins un object JavaScript, cependant il y a des différences. Tout d'abord, comme expliqué dans la spécification, "JSON est un format texte facilitant l'échange de données structurées entre tous les langages de programmation". Il est donc universel et non pas limité à JavaScript. En fait, il ne fait pas du tout partie de JavaScript, il est simplement dérivé de la façon dont les objets JavaScripts sont écrits.
En termes de syntaxe, il y a deux différences principales. Tout d'abord, tous les noms (clés) sont représentés sous forme de chaînes de caractères, autrement dit ils doivent être entre guillemets. Ceci par exemple n'est pas du JSON valide :
// JSON non valide, mais objet JS valide
{
foo: "bar"
}
La façon correcte d'écrire ce JSON est :
// JSON valide
{
"foo": "bar"
}
Remarquez que JSON requiert non seulement que le nom (la clé) soit entre guillemets, mais aussi que les guillemets soient doubles : les guillemets simples sont possibles sur les objets JavaScript, pas dans JSON.
L'autre différence majeure est dans le type de données que JSON peut stocker. JSON accepte les valeurs suivantes :
- Objet
- Array
- Nombre
- Chaîne de caractères
true
false
null
C'est assez similaire à ce qu'on trouve dans les objets JS, mais JSON étant représenté sous forme de texte on ne peut pas lui donner des choses du genre fonctions ou des valeurs dynamiques de dates utilisant Date()
. Par conséquent, il n'y a pas de méthodes ou autres fonctionnalités dans JSON, il n'y a que du texte. Et c'est bien ainsi, car c'est ce qui en fait un format universel d'échange de données.
Il est important de noter qu'un morceau complet de JSON est lui-même techniquement un objet JSON, et le type Objet
est ce qui permet d'imbriquer des objets JSON comme valeurs, un peu comme les objets dans JavaScript. Ci-dessous, on a un exemple d'objet JSON imbriqué :
// JSON valide
{
"species": "Dog",
"breed": "Labrador Retriever",
"age": 6,
"traits": {
"eyeColor": "brown",
"coatColor": "yellow",
"weight": "137lbs"
}
}
Ici, l'objet JSON racine a 4 paires de clés/valeurs (“species”, “breed”, “age”, et “traits”) mais la quatrième valeur est un objet imbriqué comprenant 3 paires de clés/valeurs. Et comme vous l'avez sans doute deviné, on peut imbriquer les objets à l'infini (mais restez raisonnable).
Un objet JavaScript ressemblerait à ceci :
// objet JS; non valide en JSON
let myAnimal = {
species: "dog",
breed: "Labrador Retriever",
age: 6,
traits: {
eyeColor: "brown",
coatColor: "yellow",
weight: "137lbs"
}
}
Vous voyez les différences avec JSON (les guillemets) et de plus, pour que l'objet soit utile en JavaScript il est créé comme valeur d'une variable (myAnimal
).
Comment stocker JSON ?
JSON étant du texte, on peut le stocker où l'on veut. Dans une base de données, dans un fichier texte, un stockage client (cookies ou localStorage) ou via son propre format de fichier qui utilise l'extension .json
(qui est en gros un fichier texte avec une extension .json
).
Une fois le contenu JSON stocké, il reste donc à pouvoir le récupérer et le parser de manière appropriée. Selon les langages, il y a diverses façons de récupérer et parser JSON, mais puisque nous nous intéressons au développement front-end, je vais montrer comment le faire en JavaScript.
JavaScript propose deux méthodes, qui font partie de la spécification ECMAScript, pour réaliser deux tâches distinctes.
Utiliser JSON.stringify()
Admettons que votre application construise des données d'une manière ou d'une autre. Pour conserver ces données quelque part, elles doivent être converties en une chaîne de caractères (string) JSON valide. Vous pouvez le faire avec JSON.stringify()
:
let myJSON = {
species: "Dog",
breed: "Labrador Retriever",
age: 6,
traits: {
eyeColor: "brown",
coatColor: "yellow",
weight: "137lbs"
}
};
let myNewJSON = JSON.stringify(myJSON, null, '\t');
/* output of myNewJSON:
{
"species": "Dog",
"breed": "Labrador Retriever",
"age": 6,
"traits": {
"eyeColor": "brown",
"coatColor": "yellow",
"weight": "137lbs"
}
}
*/
La méthode JSON.stringify()
prend un paramètre obligatoire (le JSON que vous voulez convertir en string) et deux arguments optionnels. Le premier est une fonction de remplacement que vous pouvez utiliser pour filtrer certaines paires clé/valeur que vous ne voulez pas inclure. Je n'ai rien exclu dans mon exemple, donc j'ai indiqué null
à la place de la fonction de remplacement. D'habitude je n'utilise pas null
, mais je voulais utiliser le troisième argument et pour cela il est obligatoire de mentionner le second.
Le troisième paramètre est la valeur d'espace, il vous aide à formater le JSON de façon à le rendre plus lisible avec indentation, retour à la ligne, etc. Si vous utilisez un nombre pour le troisième argument, il représentera le nombre d'espaces pour l'indentation.
Utiliser JSON.parse()
À l'inverse, si vous recevez du JSON et que vous voulez l'utiliser dans votre JavaScript, vous pouvez utiliser la méthode JSON.parse()
:
let myJSON = '{
"species":"Dog",
"breed":"Labrador Retriever",
"age":6,
"traits":{
"eyeColor":"brown",
"coatColor":"yellow",
"weight":"137lbs"
}
}';
let myNewJSON = JSON.parse(myJSON);
// logs a JavaScript object, not a string
console.log(myNewJSON);
Dans l'exemple ci-dessus, je crée manuellement une chaîne de caractères JSON que je stocke dans une variable. C'est juste pour la démonstration, dans un scénario réel le JSON pourrait venir d'une source externe ou d'un fichier JSON séparé.
La méthode JSON.parse()
convertit la chaîne de caractères JSON en un objet que je peux manipuler avec JavaScript. La chaîne de caractères est le seul argument obligatoire de la méthode, mais vous pouvez ajouter un second argument optionnel que l'on appelle un reviver de la fonction. En voici un exemple, qui part du JSON précédent :
let myNewJSON = JSON.parse(myJSON, function (name, value) {
if (name === "species") {
value = "Cat";
}
return value;
});
Vous pouvez le voir sur JS Bin
Si vous regardez le résultat sur JS Bin, vous verrez que notre Labrador Retriever est devenu un chat. C'est juste un exemple qui nous montre que l'on peut modifier les valeurs d'un des noms. Pour plus d'infos sur ces fonctions, vous pouvez consulter MDN ou cet article sur le codage web dynamique.
Utiliser JavaScript pour manipuler du JSON
Comme vous l'avez déjà deviné, une fois nos données JSON converties en objet JavaScript, nous pouvons y accéder comme à n'importe quel objet JS. Admettons que nous ayons parsé notre chaîne de caractères JSON et que la variable myNewJSON
contienne le résultat, comme nous l'avons vu dans la section précédente. Nous pouvons maintenant utiliser ce qu'on appelle la notation avec point (dot notation) pour accéder aux différentes parties de la donnée JSON :
console.log(myNewJSON.species); // "Dog"
console.log(myNewJSON.breed); // "Labrador Retriever"
console.log(myNewJSON.age); // 6
Nous pouvons également accéder à l'objet imbriqué et aux valeurs situées à l'intérieur via la notation avec point :
console.log(myNewJSON.traits);
/*
[object Object] {
coatColor: "yellow",
eyeColor: "brown",
weight: "137lbs"
}
*/
console.log(myNewJSON.traits.coatColor); // "yellow"
console.log(myNewJSON.traits.eyeColor); // "brown"
console.log(myNewJSON.traits.weight); // "137lbs"
Nous pouvons ensuite faire ce que nous voulons de ces données, par exemple ajouter de nouvelles valeurs, changer les valeurs actuelles, effacer des paires de clés/valeurs...
myNewJSON.age = 7;
delete myNewJSON.traits.weight;
myNewJSON.traits.cuddly = true;
console.log(myNewJSON);
/*
[object Object] {
age: 7,
species: "Dog",
breed: "Labrador Retriever",
traits: [object Object] {
coatColor: "yellow",
cuddly: true,
eyeColor: "brown"
}
}
*/
Dans le code ci-dessus, j'ai modifié la valeur de l'age
, supprimé la propriété weight
(poids) de l'objet traits
, et ajouté une nouvelle propriété cuddly
(câlin) à l'objet traits
.
Nous pouvons ensuite utiliser JSON.stringify()
pour convertir des nouvelles données dans le format d'origine de façon à pouvoir les stocker où nous voulons comme du JSON valide.
JSON mieux que XML ?
XML n'est certainement pas un format en voie de disparition, mais JSON le surpasse largement en popularité. Douglas Crockford explique les avantages de JSON sur XML ("le XML sans gras") et je cite un extrait ici :
XML n'est pas idéal pour les échanges de données, de même qu'un tournevis n'est pas fait pour enfoncer des clous. Il porte avec lui un lourd bagage et ne correspond pas au modèle de données de la plupart des langages de programmation. Lorsque les programmeurs ont vu XML pour la première fois, ils ont été choqués par sa laideur et son inefficacité. Cette première réaction était la bonne. Il existe une autre notation textuelle qui posséde tous les avantages de XML et se révèle bien mieux adaptée aux échanges de données — cette notation est JSON.
Il poursuit en détaillant les avantages proclamés de XML et en montrant pourquoi JSON fait mieux.
Qu'est-ce que JSONP ?
JSONP ("JSON with Padding") est une solution visant à surmonter les restrictions et limitations d'origines croisées (cross-origin) liées aux requêtes pour des ressources localisées sur un domaine différent de celui à l'origine de la requête. Bob Ippolito a proposé en 2005 JSONP, peu de temps après la solution similaire de George Jempty appelée JSON++.
JSON profite du fait que les éléments <script>
ne sont pas liés par les limitations d'origines croisées. C'est ainsi que nous pouvons faire un lien vers des scripts situés sur des CDN distants sans problème.
Dans cet exemple, nous accédons à des données JSONP via un simple JavaScript :
function doJSONP(result) {
console.log(result.data);
}
let script = document.createElement('script');
script.src = 'https://api.github.com/users/impressivewebs?callback=doJSONP'
document.getElementsByTagName('body')[0].appendChild(script);
Ce code crée un élément <script>
, ajoute une URL dans l'attribut src
, puis ajoute (append) le script au document. Dans cet exemple, j'accède à des données utilisateur spécifiques sur GitHub (mes propres données, en fait) en utilisant l'API de GitHub. Si vous ouvrez la démo, vous verrez les données affichées dans la console.
Si vous utilisez jQuery, vous pouvez faire une requête similaire via la méthode $.getJSON()
:
$.getJSON('https://api.github.com/users/impressivewebs', function (result) {
console.log(result);
});
Remarquez que dans ce cas les données que je veux sont exactement celles qui sont retournées. Avec la version JavaScript, il me faut creuser un peu plus loin avec la propriété data
pour obtenir le JSON voulu.
Dans tous les cas, après avoir obtenu le résultat je peux utiliser la notation avec point pour accéder aux paires clé/valeur. Par exemple je peux obtenir le nombre de mes followers sur GitHub, l'URL de mon avatar, ma quantité de repos publics et bien d'autres infos.
Comment marche JSONP ?
Pour comprendre comment fonctionne JSONP, il faut d'abord comprendre qu'un fichier JSON simple ne peut pas être utilisé de cette façon, sauf si le serveur prépare les données de façon à ce que la réponse soit correcte. Comment la technique JSONP résout-elle le problème ?
Dans l'exemple JavaScript précédent, vous avez sans doute remarqué que l'URL de l'API GitHub avait un paramètre attaché : callback=doJSON
. Cette fonction de callback agit comme un emballage (ou un padding) nous permettant l'accès aux données, car normalement lorsque nous injectons des données JSON via un élément <script>
il ne se passera rien, les contenus n'étant pas stockés dans une variable accessible dans notre JavaScript.
Avec JSONP, au lieu de :
{
"one": "value_1",
"two": "value_2"
}
...nous recevons ceci :
callback({
"one": "value_1",
"two": "value_2"
});
...où callback
est le nom de mon callback. Dans mon exemple, ce serait doJSON
.
Donc, si vous souhaitez qu'on puisse accéder à votre JSON à partir d'un serveur distant, vous devez vous assurer qu'il sera envoyé avec le padding (c'est à dire la fonction d'emballage). Vous pouvez en voir un exemple (négatif) dans ce codepen où j'essaie d'accéder à ces données de la Ligue de Baseball mais le navigateur me répond par un message d'erreur "Uncaught SyntaxError: Unexpected token :" parce que la Ligue de Baseball n'a pas fait en sorte que ses données soient accessibles par JSONP.
Une discussion détaillée de la résolution de ce problème dépasse les limites de cet article, mais vous trouverez une solution simple dans ce fil de Stack Overflow.
Il faut faire attention aux problèmes de sécurité liés à JSONP, donc faites quelques recherches si vous avez un projet dans ce sens. Pour plus d'infos sur JSONP, vous pouvez consulter les ressources suivantes :
- JSONP sur Wikipedia
- JSONP en termes simples sur Stack Overflow
- Utiliser JSONP en toute sécurité
Outils JSON
Il existe de nombreux outils pour faire beaucoup de choses avec les données JSON. Voici une liste de quelques outils intéressants que j'ai rencontrés :
- JSONLint — Un validateur de données JSON. C'est un bon outil pour apprendre les bases de la syntaxes et en quoi elle diffère de la syntaxe objet JavaScript.
- json.browse — Vous permet de naviguer, améliorer (prettify), manipuler du JSON à partir d'une source externe ou du JSON copié/collé. Une fonctionnalité intéressante est la possibilité de filtrer les données à partir d'un mot-clé.
- JSONedit — Un constructeur visuel de JSON qui facilite la construction de structures JSON complexes avec des types de données différents.
- JSON Schema — Un vocabulaire vous permettant d'annoter et de valider des documents JSON.
- JSON API — Une spécification pour réaliser des API en JSON.
- CSVJSON — Convertisseur de CSV et SQl en JSON
- JSON Formatter — Outil en ligne pour valider, améliorer, minifier et convertir les données JSON.
- excelJSON — Outil en ligne pour convertir du CSV ou TSV en JSON et JSON en CSV ou TSV.
- Myjson — Un entrepôt JSON simple pour votre appli web ou mobile.
- jsonbin.org — Un nouveau projet de Remy Sharp, "un entrepôt JSON comme service. Protégé par authentification les données sont stockée en JSON et peuvent être liées".
- Kinto — Un entrepôt JSON générique avec possibilité de partage et de synchronisation.
- JSON Generator — Outil en ligne pour générer des données aléatoires en JSON.
- Hjson — Une extension de syntaxe pour JSON, afin de faciliter la lectire et la correction par les humains, avant d'envoyer les données à la machine.
- JSON Selector Generator — Copiez/collez du JSON, puis cliquez sur n'importe quelle donnée et cet outil vous dira quel "sélecteur" utiliser en JavaScript pour accéder à cette donnée.
Pour recevoir d'autres outils, vous pouvez vous inscrire à Web Tools Weekly. N'hésitez pas à ajouter des commentaires ou à suggérer d'autres outils.
Conclusion
Si JSON était un concept relativement neuf pour vous, j'espère que cet article vous aura donné une bonne idée de ce qu'il peut vous apporter. JSON est une technologie solide, facile à utiliser et puissante parce qu'universelle.