Aller au contenu
jsonbeautifiers
Français

Analyseur JSON

Analysez un payload et voyez ses types, sa profondeur, son nombre de clés et tous ses chemins.

Entrée

Rien de ce que vous collez ne quitte votre navigateur. La liste d’autorisation connect-src en fait une garantie du navigateur plutôt qu’une promesse. Vérifiez-le vous-même

Analyser transforme du texte en structure. Cette page vous montre ce qui en est sorti : les types, la profondeur d’imbrication, combien il y a de clés et de tableaux, quels nombres ne survivront pas à un analyseur JavaScript, et où se trouvent les clés en double.

C’est la page à ouvrir quand on vient de vous remettre un payload et que la première question est : qu’y a-t-il réellement là-dedans.

Ce que disent les statistiques

Chacune répond à une question qui se pose au moment d’écrire du code contre un document.

Profondeur maximale
Jusqu’où va l’imbrication. Au-delà de quelques centaines de niveaux, vérifiez ce que font vos consommateurs. Mesuré ici : V8 analyse un million de niveaux mais refuse de sérialiser au-delà de 4 800 environ, et le scanner C de CPython atteint autour de 17 000 malgré une limite de récursion Python de 1 000.
Nombre de clés et d’objets
Une mesure grossière du travail qu’aura un mapper ou un ORM, et de la taille que prendra l’arbre en mémoire.
Nombres non sûrs
Combien d’entiers dépassent 2^53-1. Si ce n’est pas zéro, tout consommateur JavaScript lit déjà des valeurs différentes de celles du fichier.
Clés en double
Combien de clés d’objet ont été définies deux fois, avec la position de chacune.

Analyser n’est pas valider une forme

Un document peut s’analyser parfaitement et vous être inutile : un champ renommé, un nombre envoyé sous forme de chaîne, un tableau là où un objet était attendu. L’analyse vérifie la grammaire, pas le contrat.

Pour le contrat, générez un JSON Schema depuis un payload de confiance et validez les payloads suivants contre lui.

En quoi cet analyseur diffère de JSON.parse

Il est itératif plutôt que récursif : la profondeur n’est bornée que par la mémoire. Il enregistre le texte source exact de chaque nombre, donc rien n’est arrondi en silence. Il suit la position de chaque jeton, donc les erreurs ont une ligne et une colonne. Et il se rétablit après une erreur au lieu de s’arrêter, donc un document cassé signale tous ses problèmes en une passe.

Le coût de tout cela est la vitesse : environ 12 à 16 Mo par seconde ici, contre 60 à 70 pour un JSON.parse natif. C’est le prix de l’information, et c’est pourquoi le travail s’exécute dans un worker en arrière-plan.

How to do this in code

Analyser en code, y compris les options que l’on découvre en général trop tard.

js JavaScript

Le reviver ne peut pas récupérer les chiffres d’origine : quand il s’exécute, le nombre a déjà été converti en flottant.

const value = JSON.parse(text);

// The reviver runs on every key and value, which is how you
// intercept large integers before precision is lost.
const value2 = JSON.parse(text, function (key, val) {
  if (typeof val === 'number' && !Number.isSafeInteger(val)) {
    // this[key] is the raw value; the original TEXT is not
    // available here, which is the limitation.
    console.warn('unsafe integer at', key);
  }
  return val;
});
py Python

object_pairs_hook est le seul moyen portable de détecter les clés en double en Python.

import json
from decimal import Decimal

# parse_float and parse_int receive the raw TEXT of the number,
# so unlike JavaScript you can keep full precision.
data = json.loads(text, parse_float=Decimal, parse_int=int)

# Detect duplicate keys instead of silently keeping the last
def no_dupes(pairs):
    seen = {}
    for k, v in pairs:
        if k in seen:
            raise ValueError(f'duplicate key: {k}')
        seen[k] = v
    return seen

data = json.loads(text, object_pairs_hook=no_dupes)
go Go
// UseNumber keeps the original text instead of converting
// to float64, so large integers survive.
dec := json.NewDecoder(bytes.NewReader(data))
dec.UseNumber()

var v any
if err := dec.Decode(&v); err != nil {
    return err
}
java Java
ObjectMapper mapper = new ObjectMapper();

// Fail loudly on duplicates rather than keeping the last one
mapper.enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY);

// Keep big integers exact
mapper.enable(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS);

Questions fréquentes

Pourquoi mon nombre est-il différent après l’analyse ?
Parce que les nombres JSON n’ont pas de limite de taille et que les doubles IEEE 754 en ont une. Tout entier supérieur à 2^53-1 et beaucoup de décimaux ne peuvent pas être représentés exactement. Python, Go et Java offrent tous un moyen de conserver le texte d’origine ; JavaScript non, et c’est pourquoi les grands identifiants devraient être transmis sous forme de chaînes.
Que deviennent les clés en double ?
La RFC 8259 laisse la question indéfinie. JavaScript et Python gardent la dernière occurrence, certaines configurations Go et Java rejettent le document, quelques analyseurs gardent la première. Ne comptez jamais dessus. Cette page signale chaque doublon avec les deux positions.