Porovnat dvě JSON struktury
- Dashboard
- Dokumentace
- API
Proč porovnávat dvě JSON?
Porovnání dvou JSON struktur se pravidelně vrací v životě developera. API odpověď, která se mění po aktualizaci. Konfigurační soubor, který diverguje mezi dvěma prostředími. Export objektů, který se musí zarovnat na referenci. JSON diff přesně odpovídá na tuto otázku: co bylo přidáno, smazáno nebo modifikováno, a kde?
Řádkový diff (typu git diff) často nestačí. Pokud se formátování
liší (mezery, pořadí klíčů), textový diff signalizuje stovky řádků, zatímco struktura
dat je identická. JSON comparator pracuje na struktuře po parsing, což eliminuje tento
šum a odhaluje pouze sémantické rozdíly.
Formát diffu produkovaného nástrojem
Pro každý rozdíl nástroj vrací:
- cestu v zjednodušeném JSONPath formátu, například
$.user.address[0].city; - typ mezi added (přidáno vpravo), removed (přítomno pouze vlevo), modified (různé hodnoty);
- levou hodnotu a/nebo pravou hodnotu podle typu.
Prázdný diff znamená, že dva JSON jsou strukturálně identické, nezávisle na jejich formátování nebo pořadí klíčů.
Jak algoritmus prochází dvě struktury
Algoritmus je rekurzivní. Na každé úrovni identifikuje typ dvou porovnávaných hodnot:
- Pokud jsou oba asociativní objekty, vezme sjednocení klíčů. Pro každý klíč sestoupí rekurzivně, nebo označí added/removed, pokud klíč existuje jen na jedné straně.
- Pokud jsou oba uspořádaná pole, porovnává pozici po pozici. Rozdíl na začátku pole může posunout všechen zbytek, což produkuje ukecaný diff: je to přijatá limita naivního strukturálního diffu.
- Pokud se typy liší (objekt proti poli, skalár proti null), je to označeno modified.
- Pokud jsou dvě hodnoty skaláry (řetězec, číslo, boolean, null), stačí jednoduché striktní porovnání.
Pořadí klíčů v objektu nepočítá: {"a": 1, "b": 2} a {"b": 2, "a": 1}
produkují prázdný diff. To je konformní s JSON sémantikou, kde pořadí není signifikantní. Naopak
pořadí elementů pole počítá: pole je uspořádané konstrukcí.
Konkrétní příklad
Zde jsou dvě verze uživatelského objektu:
// levý
{
"id": 42,
"name": "Alice",
"roles": ["admin", "editor"]
}
// pravý
{
"id": 42,
"name": "Alice Martin",
"roles": ["admin", "viewer"],
"active": true
}
Produkovaný diff:
$.name: modified,"Alice"→"Alice Martin"$.roles[1]: modified,"editor"→"viewer"$.active: added,true
Případy použití
- Environment diff: porovnat výstup endpointu v pre-produkci a v produkci. Velmi užitečné při migraci nebo cache refresh.
- Migration audit: porovnat export před a po transformaci pro ověření, že žádné pole nebylo ztraceno.
- API regrese: před a po modifikaci porovnat odpověď pro identický požadavek. Prázdný diff potvrzuje non-regresi.
- Konfigurační synchronizace: porovnat
composer.jsonmezi dvěma větvemi, dva soubory.eslintrc, dvě Symfony konfigurace. - Snapshot testy: nahradit řádkové porovnání strukturálním porovnáním v integrační testovací sadě.
Limity strukturálního diffu
Porovnávání uspořádaných polí je známá limita naivních strukturálních diffů. Pokud vložíme element na začátek pole, všechny následující pozice jsou posunuty a diff signalizuje každý rozdíl jako modifikaci. Pro takové případy existují pokročilejší algoritmy (Myers, Patience, diff podle přirozeného klíče), ale vystupují z rámce obecného srovnávacího nástroje.
Diff také neříká, proč se změna udála: je to konstatování. Pro analýzu regrese je třeba zkřížit toto konstatování s commity, nasazeními a parametry požadavku.
JSON diff vs JSON Patch (RFC 6902)
Komplementární formát je JSON Patch (RFC 6902). Popisuje, ve formě operací
(add, remove, replace, move, copy,
test), jak transformovat JSON dokument na jiný. Tam, kde je náš diff konstatování
(lidské), JSON Patch je recept (strojový). Obě reprezentace jsou ekvivalentní pro
jednoduché případy, a JSON Patch je užitečný pro RESTful API, která přijímají částečné
modifikace.
Často kladené otázky
Závisí diff na pořadí klíčů?
Ne: pro JSON objekt není pořadí signifikantní. Comparator produkuje stejný výsledek, ať jsou klíče setříděny nebo ne.
Jak spravovat pole, kde pořadí není důležité?
Nástroj ve výchozím nastavení považuje pole za uspořádaná (to je JSON sémantika). Pokud zpracováváte množiny, setřiďte obě pole podle přirozeného klíče před porovnáním, nebo použijte specializovanou srovnávací službu, která bere tuto sémantiku v úvahu.
Jaký je rozdíl s Git diffem?
Git porovnává řádky textu. Pokud se indentace nebo pořadí klíčů liší, Git diff je velmi ukecaný. JSON diff pracuje na parsované struktuře a signalizuje pouze datové rozdíly.
Je nevalidní JSON přijat?
Ne: pokud se jeden ze dvou JSON neparsuje, nástroj vrací chybu. Nejprve validujte naším JSON validátorem.
Ukázka požadavku
curl -X POST https://cdrn.fr/api/v1/tools/json-diff/execute \
-H "Content-Type: application/json" \
-d '{"left":"...","right":"..."}'
Vstupní schéma
| Pole | Typ | Povinné | Výchozí |
|---|---|---|---|
left |
text | ✓ | – |
right |
text | ✓ | – |
Koncové body
GET https://cdrn.fr/api/v1/tools- vypíše všechny dostupné nástrojeGET https://cdrn.fr/api/v1/tools/json-diff- získá schéma tohoto nástrojePOST https://cdrn.fr/api/v1/tools/json-diff/execute- spustí tento nástroj s JSON payloadem