Comparer des objets JSON et repérer chaque modification
Une comparaison textuelle rend parfois une petite mise à jour JSON illisible : indentation, ordre des clés et formatage masquent les données réellement modifiées.
Lancer gratuitement
Tout se passe dans votre navigateur : gratuit, sans envoi de vos données.
Cet outil compare les valeurs analysées, classe les clés ajoutées, supprimées et modifiées, parcourt les objets imbriqués communs et fournit un chemin JSON Pointer sans ambiguïté. Les tableaux restent ordonnés et sont comparés en bloc. Le calcul est déterministe, sans accès réseau, et refuse au niveau racine les tableaux, primitives et valeurs null.
Interpréter une différence JSON structurelle
Le résultat répartit les écarts entre trois collections : ajouts, suppressions et modifications. Un ajout n’existe que dans le nouvel objet, une suppression uniquement dans l’original, et une modification contient les valeurs avant et après. Chaque entrée porte un chemin JSON Pointer commençant par une barre. Ainsi, /profile/name désigne name dans profile. Une barre présente dans une clé devient ~1 et un tilde devient ~0, ce qui évite toute confusion avec les niveaux imbriqués. Le parcours trié garantit une réponse stable. Le bloc counts résume chaque catégorie et le total. Trois listes vides signifient que les objets sont structurellement identiques, même si leur texte d’origine utilise une autre indentation ou un ordre de clés différent.
Gestion des objets imbriqués et des tableaux
Lorsqu’une même clé contient un objet des deux côtés, la comparaison descend jusqu’à la propriété précise qui diffère. Si seul profile.active change, le chemin rendu est /profile/active. Une clé entièrement absente d’un côté est toutefois signalée une seule fois avec sa valeur complète, sans développer tous ses descendants. Les tableaux sont des valeurs JSON ordonnées comparées en bloc : insertion, suppression, déplacement ou modification d’un élément signale la propriété entière comme modifiée. Les primitives et null sont comparés directement, et un changement de type constitue aussi une modification. Seules les deux valeurs racines obéissent à une contrainte stricte : before et after doivent être des objets JSON non nuls.
Exploiter le résultat en révision et en automatisation
Placez l’objet original dans before et la version proposée dans after. L’outil web travaille localement ; une requête API coûte $0.002 et produit la même structure déterministe. Vous pouvez bloquer un déploiement si un réglage protégé disparaît, vérifier que seules des routes autorisées changent ou conserver une différence compacte dans un audit. Le formatage et l’ordre des clés ne créant aucun faux positif, l’outil convient aux configurations, webhooks, indicateurs, permissions et réponses normalisées. Interprétez les chemins comme des JSON Pointer et tenez compte de leur catégorie. Pour un tableau, appliquez ensuite vos propres règles métier aux valeurs complètes. Une racine invalide renvoie une erreur explicite plutôt qu’une différence vide trompeuse.
Cas d’usage
Contrôler une nouvelle configuration
Comparez la configuration déployée à la candidate sans bruit dû aux espaces ou à l’ordre des clés.
Auditer l’évolution des webhooks
Consignez les champs imbriqués apparus, disparus ou modifiés entre deux exemples normalisés.
Protéger les réglages approuvés
Contrôlez les chemins en CI et bloquez le déploiement si un réglage protégé change.
Questions fréquentes
Quel format de chemin le résultat emploie-t-il ?
Chaque chemin est un JSON Pointer de type RFC 6901 ; les barres des clés deviennent ~1 et les tildes ~0.
L’ordre des clés compte-t-il comme modification ?
Non. La comparaison porte sur les clés et les valeurs, pas sur leur ordre de sérialisation.
Comment les tableaux sont-ils comparés ?
Ils sont ordonnés et comparés en bloc. Toute insertion, suppression, modification ou permutation signale le tableau.
Puis-je comparer deux tableaux racines ?
Non. before et after doivent être des objets JSON non nuls ; une autre racine provoque une erreur de saisie.
Quel est le prix d’une requête API ?
L’outil web fonctionne gratuitement en local. Chaque requête API applique le tarif de base publié de $0.002.
Pour les développeurs — accès API
Tout sur cette page est disponible par programmation. Cette section s'adresse aux équipes qui veulent l'intégrer à leurs systèmes ; les autres peuvent simplement utiliser l'outil ci-dessus.
Endpoint
Authentification par jeton Bearer : un seul POST met la tâche en file d’attente, et le résultat vous parvient par webhook ou lien signé.
Appeler depuis votre stack
curl -X POST https://api.kit.forhosting.com/data/diff-json-objects \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"before":{"name":"Ada","profile":{"active":true,"score":8},"roles":["reader"]},"after":{"name":"Ada","profile":{"active":false,"score":8,"city":"London"},"roles":["reader","editor"]}}'const res = await fetch("https://api.kit.forhosting.com/data/diff-json-objects", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"before": {
"name": "Ada",
"profile": {
"active": true,
"score": 8
},
"roles": [
"reader"
]
},
"after": {
"name": "Ada",
"profile": {
"active": false,
"score": 8,
"city": "London"
},
"roles": [
"reader",
"editor"
]
}
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/data/diff-json-objects",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"before": {
"name": "Ada",
"profile": {
"active": true,
"score": 8
},
"roles": [
"reader"
]
},
"after": {
"name": "Ada",
"profile": {
"active": false,
"score": 8,
"city": "London"
},
"roles": [
"reader",
"editor"
]
}
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/data/diff-json-objects", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"before":{"name":"Ada","profile":{"active":true,"score":8},"roles":["reader"]},"after":{"name":"Ada","profile":{"active":false,"score":8,"city":"London"},"roles":["reader","editor"]}}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"before":{"name":"Ada","profile":{"active":true,"score":8},"roles":["reader"]},"after":{"name":"Ada","profile":{"active":false,"score":8,"city":"London"},"roles":["reader","editor"]}}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/data/diff-json-objects", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Exemple de requête
{
"before": {
"name": "Ada",
"profile": {
"active": true,
"score": 8
},
"roles": [
"reader"
]
},
"after": {
"name": "Ada",
"profile": {
"active": false,
"score": 8,
"city": "London"
},
"roles": [
"reader",
"editor"
]
}
}Exemple de réponse
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "data.diff_json_objects",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}L’API est asynchrone : chaque appel renvoie un task_id immédiatement, puis vous interrogez l’état à raison d’une requête par seconde.
Tarifs
Le prix est publié, sans tokens ni crédits. Une tâche qui échoue n’est pas facturée.
Limites
max_mb | 25 |
Erreurs
| HTTP | Code | Signification |
|---|---|---|
401 | unauthorized | Clé API absente ou invalide : vérifiez l’en-tête Authorization. |
402 | insufficient_balance | Solde insuffisant : rechargez votre compte pour lancer cette tâche. |
404 | unknown_type | Type de tâche inconnu : vérifiez le champ type de votre requête. |
429 | rate_limited | Trop de requêtes : ralentissez la cadence, puis réessayez. |