Débuter avec le format de donnée JSON

Publié le 01/02/2016 | Jérémy Grèze
Débuter avec le format de donnée JSON

Dans mon quotidien de data anlayst, je travaille avec des données au format JSON. Autant les développeurs sont à l'aise plutôt avec ce format, les marketeurs ou les profils business sont souvent perdus devant ce nom technique. C'est pourtant devenu un grand standard dans le web, notamment dans l'utilisation des API. Je propose un article spécial pour débuter avec le JSON.

Pour l'histoire, le JSON est un format né dans les années 2000 avec Internet et principalement utilisé pour l'échange de données. La plupart des API utilisent ce format (si vous prospectez pour un service qui ne propose qu'une API XML, fuyez pauvre fou !). C'est un peu le symbole d'un web ouvert, de la communication des données.

Un format de données

Vous connaissez probablement les fichiers .txt et .csv, voire même les .xml. Ces fichiers sont tous lisibles directement avec un éditeur de texte même basique (je regarde dans la direction du bloc-notes Windows), ce sont des fichiers textes. Le JSON fait partie de cette famille. Ce sont des données écrites au format texte avec une certaine structure.

Pour prendre un exemple concret, je réalise une extraction des campagnes emailing réalisées avec MailChimp. J'utilise leur API Export, j'obtiens une URL, je l'ouvre dans mon navigateur et j'obtiens (bien évidemment) un JSON.

Exemple de JSON retourné par l'API Mailchimp
Un vrai JSON, retourné par l'API Mailchimp. Il est possible d’enregistrer le résultat dans un fichier ".json".

Au premier abord, cela semble illisible, du moins à l’œil humain. Pour que vous ayez une meilleur idée, je vais le simplifier et rajouter des espaces et sauts de lignes (indentation).

Voila ce que cela peut donner:

{
    "data": [
        {
            "create_time": "2016-01-15 15:04:10",
            "emails_sent": 0,
            "from_email": "pauline.brown@dataiku.com",
            "from_name": "pauline test",
            "saved_segment": [],
            "send_time": null,
            "subject": "TEST",
            "tracking": {
                "html_clicks": true,
                "opens": true,
                "text_clicks": true
            }
        },
        {
            "create_time": "2015-12-23 17:19:55",
            "emails_sent": 7,
            "from_email": "thomas.thus@dataiku.com",
            "from_name": "Thomas",
            "saved_segment": [],
            "send_time": "2015-12-23 17:27:08",
            "subject": "Merci d'avoir participé à notre dernier Webinar ! ",
            "tracking": {
                "html_clicks": true,
                "opens": true,
                "text_clicks": true
            }
        },
        //... D'autres campagnes sont listées ici ...
    ],
    "errors": [],
    "total": 67
}

(En réalité, l'extraction sous cette forme fait plus de 5.000 lignes, je l'ai vraiment simplifié.)

On arrive à deviner que cet énorme JSON est en fait une liste des campagnes emailing réalisées avec MailChimp (67 au total, c'est indiqué).

Les spécs du JSON

Le JSON est donc un langage de description des données. Comment un JSON est-il structuré ? Comment peut-on le lire ? Ses règles sont très strictes (et sont décrites par deux standards, RFC 7159 et ECMA-404), mais la logique est très simple.

Les éléments d'un JSON possibles sont les suivants:

Les nombres, chaînes de caractères, booléens et l'élément vide sont des valeurs.
Le tableau et l'objet permettent de structurer les données, c'est-à-dire ces valeurs.

Un objet est décrit par des clés et des valeurs. C'est le cœur de nos données.
Par exemple, un objet peut représenter un email, et pour le décrire on peut avoir besoin des clés suivantes: un expéditeur, un destinataire, une heure d'envoi, un titre et un corps du message. Et à chaque clé, on associe une valeur. Exemple:

"expediteur": "jeremy@foo.com"
"destinataire": "lecteur@bar.com"
"date_envoi": "31-01-2016 19:43:00"
"titre": "JSON EVERYWHERE"
"body": "Hum c'est quoi ce json <br> Tu comprends?"

Pour que ce soit un objet, les clés et valeurs sont séparées par des virgules, et le tout est entre accolades ({}). Exemple d'un objet qui représente un message email:

{
    "expediteur": "jeremy@foo.com",
    "destinataire": "lecteur@bar.com",
    "date_envoi": "31-01-2016 19:43:00",
    "titre": "JSON EVERYWHERE",
    "body": "Hum c'est quoi ce json <br> Tu comprends?",
    "nombre_denvoi": 1
}

Un tableau comprend des éléments qui sont listés entre crochets ([]) et séparés avec des virgules. Les espaces et saut de lignes qui ne sont pas entre guillemets n'ont pas d'importance.

Exemple d'un tableau qui liste des adresses emails (des chaînes de caractères):

["jeremy@foo.com", "peanuts@dataiku.com", "cacahuetes@apero.paris"]

Dans un tableau, on peut lister n'importe quel élément, donc pourquoi pas des objets.

Exemple d'un tableau qui liste 2 messages emails:

[
    {
        "expediteur": "jeremy@foo.com",
        "destinataire": "lecteur@bar.com",
        "date_envoi": "31-01-2016 19:43:00",
        "titre": "JSON EVERYWHERE",
        "body": "Hum c'est quoi ce json <br> Tu comprends?",
        "nombre_denvoi": 1
    },
    {
        "expediteur": "lecteur@bar.com",
        "destinataire": "jeremy@foo.com",
        "date_envoi": "31-01-2016 20:02:10",
        "titre": "RE: JSON EVERYWHERE",
        "body": "Bof...",
        "nombre_denvoi": 1
    }
]

Et ainsi de suite, on peut imbriquer de plus en plus d'éléments afin de décrire un ensemble de données.

Un dernier exemple pour la route:

{
    "nbr_de_campagnes_emails": 3,
    "campagnes": [
        {
            "titre": "Bienvenue",
            "envoie": true,
            "destinataires": ["jeremy@foo.com", "peanuts@dataiku.com", "cacahuetes@apero.paris"]
        },
        {
            "titre": "Test à ne pas envoyer",
            "envoie": false,
            "destinataires": []
        },
        {
            "titre": "Newsletter",
            "envoie": true,
            "destinataires": ["p1@d1.cc", "p2@d2.cc", "p3@d3.cc"]
        }
    ],
    "derniere_mise_a_jour": "23-11-2015"
}

Cet exemple est en fait très proche de ce que renvoie l'API MailChimp. L'objet principal décrit les campagnes qui ont été envoyées: il y a le nombre, la liste des campagnes (qui sont listées dans un tableau, et chacune d'entre elle est décrite par un objet), et la date de dernière mise à jour.

Les opérations classiques sur les JSON

Concrètement, qu'est-ce qu'on veut faire avec un JSON ? On veut en extraire des informations. Quand MailChimp me renvoie 5.000 lignes, j'ai envie pour mes analyses de récupérer certaines informations. Par exemple, je voudrais sûrement récupérer l'ensemble des adresses emails qui ont reçu un email. Puis, je pourrais compter pour chaque adresse email le nombre de clics sur les liens.

Pour extraire des informations d'un JSON, il faut donc le manipuler. Il existe plusieurs façons de procéder:

Au lieu de faire une liste exhaustive des opérations possibles sur les JSON (et ce serait compliqué), je vous propose quelques illustrations concrètes.

Premier exemple de manipulation: recréer une structure en deux dimensions afin de pouvoir ensuite travailler normalement dans son tableur (faire des graphiques, calculer des indicateurs, etc.). Souvent, cela signifie qu'on souhaite "éclater" les données par lignes et colonnes. Par exemple, si on a un un tableau qui liste des objets ([{...}, {...}, ...]), on peut construire une ligne par objet, puis une colonne par clé.

Manipulation de JSON avec DSS.

Deuxième exemple: ordonner un tableau, garder que N éléments d'un tableau (les 3 dernières campagnes emailing par exemple).

Dernier exemple de manipulation: extraire une liste d'éléments précis. Ces éléments précis peuvent être imbriqués très "profondément" dans le JSON (dans un objet qui est dans un tableau qui est... vous avez compris). Dans notre exemple, cela peut être une liste d'adresses emails.

Manipulation de JSON avec DSS.

Les illustrations ont été réalisées sur le logiciel DSS, avec les données de l'API MailChimp.

Conclusion

Le format du JSON demande un peu de rigueur mais est très simple à comprendre. Il permet de décrire toute sorte de données. Par contre, sa manipulation sans programmation n'est pas simple, et encore peu accessible dans les tableurs traditionnels. Il faut ruser pour s'en sortir, mais après tout, c'est bien l'essence du web :)

Personnellement, je travaille beaucoup sur les JSON en Python et sinon visuellement avec DSS. Les contextes d'utilisations tournent souvent autour de la communication des données entre services et API.