Sammenlign to JSON-strukturer
- Dashboard
- Dokumentation
- API
Hvorfor sammenligne to JSON?
Sammenligning af to JSON-strukturer dukker jævnligt op i en udviklers liv. Et API-svar som ændres efter en opdatering. En konfigurationsfil, der divergerer mellem to miljøer. A eksport af objekter, der skal justeres til en reference. En JSON diff reagerer præcist på dette spørgsmål: hvad blev tilføjet, slettet eller ændret, og hvor?
En linje-for-linje diff (a la git diff) er ofte ikke nok. Hvis formateringen
afviger (mellemrum, nøglerækkefølge), rapporterer tekstforskellen hundredvis af linjer, mens strukturen
data er identiske. En JSON-komparator virker på strukturen, når den er parset, hvilket eliminerer dette
støj og afslører kun semantiske forskelle.
Formatet af diff'en produceret af værktøjet
For hver afvigelse returnerer værktøjet:
- en sti i forenklet JSONPath-format, f.eks.
$.user.address[0].city; - én type blandt tilføjet (tilføjet til højre), fjernet (til stede til venstre kun), modificeret (forskellige værdier);
- den venstre værdi og/eller den den højre værdi afhængigt af typen.
En tom diff betyder, at de to JSON'er er strukturelt identiske, uanset deres formatering eller nøglerækkefølge.
Hvordan algoritmen krydser de to strukturer
Algoritmen er rekursiv. På hvert niveau identificerer den typen af de to sammenlignede værdier:
- Hvis begge er associative objekter, tager det foreningen af nøglerne. For hver nøgle, den falder rekursivt eller markerer tilføjet/fjernet, hvis nøglen kun findes på den ene side.
- Hvis begge er ordnede arrays, sammenlignes position for position. A forskel i begyndelsen af bordet kan forskyde alt andet, hvilket giver en verbose forskel: det er en antaget grænse for den naive strukturelle forskel.
- Hvis typerne er forskellige (objekt versus matrix, skalar versus null), er det markeret ændret.
- Hvis begge værdier er skalarer (streng, tal, boolean, null), en simpel streng sammenligning er nok.
Rækkefølgen af nøgler i et objekt er ligegyldig: {"a": 1, "b": 2} og {"b": 2, "a": 1}
producere en tom diff. Dette er i overensstemmelse med JSON-semantik, hvor orden ikke er meningsfuld. I
Rækkefølgen af elementerne i et array har imidlertid betydning: et array er ordnet efter konstruktion.
Et konkret eksempel
Her er to versioner af et brugerobjekt:
// venstre
{
"id": 42,
"name": "Alice",
"rolles": ["admin", "editor"]
}
// højre
{
"id": 42,
"name": "Alice Martin",
"rolles": ["admin", "seer"],
"aktiv": sandt
}
Forskellen giver:
$.name: modificeret,"Alice"→"Alice Martin"$.roles[1]: modificeret,"editor"→"fremviser"$.active: tilføjet,true
Brug cases
- Forskellige miljøer: Sammenlign output fra et slutpunkt i præproduktion og i produktion. Meget nyttig under en migrering eller cacheopdatering.
- Migreringsrevision: Sammenlign en eksport før og efter transformation for at kontrollere at ingen felter er gået tabt.
- API-regression: før og efter en ændring, sammenligne svaret for en identisk forespørgsel. En tom diff bekræfter ikke-regression.
- Konfigurationssynkronisering: sammenlign
composer.jsonmellem to branches, to.eslintrc-filer, to Symfony-konfigurationer. - Snapshot-tests: Erstat en linje-til-linje sammenligning med en sammenligning strukturel i en integrationstestsuite.
Grænser for strukturel forskel
Sammenligning af ordnede arrays er en kendt begrænsning af naive strukturelle forskelle. Hvis vi indsætter en element i starten af arrayet, forskydes alle efterfølgende positioner, og diffen signalerer hver afvigelse som en ændring. I sådanne tilfælde findes der mere avancerede algoritmer (Myers, Patience, diff ved naturlig nøgle), men de går ud over omfanget af et generelt sammenligningsværktøj.
Forskellen siger heller ikke, hvorfor en ændring fandt sted: det er en observation. At analysere en regression, skal denne observation krydshenvises til commits, implementeringer og parametre for forespørgsel.
JSON diff vs JSON Patch (RFC 6902)
Et komplementært format er JSON-patch (RFC 6902). Den beskriver, i form af operationer
(tilføj, fjern, erstat, flyt, kopi,
test), hvordan man transformerer et JSON-dokument til et andet. Hvor vores forskel er en observation
(menneske), JSON Patch er en opskrift (maskine). De to repræsentationer svarer til
simple tilfælde, og JSON Patch er nyttig til RESTful API'er, der accepterer ændringer
delvis.
Ofte stillede spørgsmål
Afhænger forskellen af nøglerækkefølgen?
Nej: for et JSON-objekt er rækkefølgen ikke signifikant. Komparatoren giver samme resultat som nøglerne er sorteret eller ej.
Hvordan håndterer man tabeller, hvis rækkefølge ikke er vigtig?
Værktøjet betragter arrays som bestilt som standard (dette er JSON-semantik). Hvis du behandler sæt, sorter de to arrays efter en naturlig nøgle før sammenligning, eller brug en tjeneste specialiseret sammenligningsværktøj, der tager højde for denne semantik.
Hvad er forskellen med en Git diff?
Git sammenligner tekstlinjer. Hvis indrykningen eller nøglerækkefølgen er forskellig, er Git-forskellen meget verbose. JSON-forskellen fungerer på den parsede struktur og rapporterer kun datahuller.
Er ugyldig JSON accepteret?
Nej: hvis en af de to JSON'er ikke parser, returnerer værktøjet en fejl. Valider først med vores JSON-validator.
Anmodningseksempel
curl -X POST https://cdrn.fr/api/v1/tools/json-diff/execute \
-H "Content-Type: application/json" \
-d '{"left":"...","right":"..."}'
Inputskema
| Felt | Type | Påkrævet | Standard |
|---|---|---|---|
left |
text | ✓ | – |
right |
text | ✓ | – |
Endpoints
GET https://cdrn.fr/api/v1/tools- lister alle tilgængelige værktøjerGET https://cdrn.fr/api/v1/tools/json-diff- henter skemaet for dette værktøjPOST https://cdrn.fr/api/v1/tools/json-diff/execute- udfører dette værktøj med et JSON-payload