Võrdle kahte JSON-struktuuri

võrdleb kahte JSON-struktuuri ja loetleb lisandused, kustutamised ja muutused, võti võtmena

Miks võrrelda kahte JSON-i?

Kahe JSON-struktuuri võrdlemine tuleb arendaja elus regulaarselt ette. API vastus mis muutub pärast värskendust. Konfiguratsioonifail, mis erineb kahe keskkonna vahel. A objektide eksport, mis peavad joondama viitega. JSON-i erinevus reageerib täpselt see küsimus: mida lisati, kustutati või muudeti ja kus?

Rea-realt diff (a la git diff) ei ole sageli piisav. Kui vormindamine erineb (tühikud, klahvide järjestus), tekstiline erinevus annab sadu ridu, samas kui struktuur andmed on identsed. JSON-i võrdleja töötab pärast sõelumist struktuuriga, mis selle välistab müra ja paljastab ainult semantilised erinevused.

Tööriista tekitatud erinevuse vorming

Iga kõrvalekalde korral tagastab tööriist:

  • tee lihtsustatud JSONPath-vormingus, näiteks $.user.address[0].city;
  • üks tüüp hulgast lisatud (lisatud paremal), eemaldatud (esineb vasakul ainult), muudetud (erinevad väärtused);
  • olenevalt tüübist vasak väärtus ja/või parem väärtus.

Tühi erinevus tähendab, et kaks JSON-i on olenemata nende struktuurist identsed vormindamine või võtmejärjestus.

Kuidas algoritm läbib kahte struktuuri

Algoritm on rekursiivne. Igal tasemel määrab see kahe võrreldava väärtuse tüübi:

  • Kui mõlemad on assotsiatiivsed objektid, on selleks vaja klahvide ühendust. Iga võtme jaoks see laskub rekursiivselt või märgib lisatuks/eemaldatuks, kui võti on ainult ühel küljel.
  • Kui mõlemad on järjestatud massiivid, võrdleb see positsiooni positsioonide kaupa. A erinevus tabeli alguses võib nihutada kõike muud, mis tekitab paljusõnalise erinevuse: see on a naiivse struktuurierinevuse oletatav piir.
  • Kui tüübid erinevad (objekt versus massiiv, skalaar versus null), märgitakse see muudetud.
  • Kui mõlemad väärtused on skalaarid (string, arv, tõeväärtus, null), on lihtne piisab rangest võrdlusest.

Võtmete järjekord objektis ei oma tähtsust: {"a": 1, "b": 2} ja {"b": 2, "a": 1} tekitada tühi erinevus. See vastab JSON-i semantikale, kus järjestus ei ole mõttekas. sisse Siiski on oluline massiivi elementide järjekord: massiiv on järjestatud ehituse järgi.

Konkreetne näide

Siin on kasutajaobjekti kaks versiooni:

// jäänud
{
  "id": 42,
  "nimi": "Alice",
  "rollid": ["administraator", "toimetaja"]
}

// õige
{
  "id": 42,
  "nimi": "Alice Martin",
  "rolles": ["administraator", "vaataja"],
  "aktiivne": tõsi
}

Erinevus toob kaasa:

  • $.name: muudetud, "Alice""Alice Martin"
  • $.rolles[1]: muudetud, "toimetaja""vaataja"
  • $.active: lisatud, tõene

Kasutusjuhtumid

  • Erinevad keskkonnad: võrrelge lõpp-punkti väljundit tootmiseelses ja tootmine. Väga kasulik migratsiooni või vahemälu värskendamise ajal.
  • Migratsiooniaudit: kontrollimiseks võrrelge eksporti enne ja pärast teisendamist et ükski põld pole kadunud.
  • API regressioon: enne ja pärast muudatust võrrelge a vastust identne päring. Tühi erinevus kinnitab mitteregressiooni.
  • Konfiguratsiooni sünkroonimine: võrrelge composer.json kahe vahel filiaalid, kaks .eslintrc-faili, kaks Symfony konfiguratsiooni.
  • Hetktõmmise testid: asendage ridadevaheline võrdlus võrdlusega struktuurne integratsioonitestide komplektis.

Struktuursete erinevuste piirid

Järjestatud massiivide võrdlemine on naiivsete struktuursete erinevuste teadaolev piirang. Kui sisestame a element massiivi alguses, nihutatakse kõiki järgnevaid positsioone ja diff annab märku igast kõrvalekaldest muudatusena. Sellistel juhtudel on olemas täiustatud algoritmid (Myers, Patience, diff loomuliku võtmega), kuid need väljuvad üldise võrdlustööriista ulatusest.

Diff ei ütle ka, miks muutus toimus: see on vaatlus. Analüüsida a regressiooni korral peab see tähelepanek olema ristviideta rakenduste, juurutuste ja parameetritega. päring.

JSON-i erinevus vs JSON-plaaster (RFC 6902)

Täiendav vorming on JSON-plaaster (RFC 6902). See kirjeldab toimingute vormis (lisa, eemalda, asenda, teisalda, kopeeri, test), kuidas muuta üks JSON-dokument teiseks. Kui meie erinevus on vaatlus (inimene), JSON Patch on retsept (masin). Need kaks esitust on samaväärsed lihtsatel juhtudel ja JSON Patch on kasulik RESTful API-de jaoks, mis aktsepteerivad muudatusi osaline.

Korduma kippuvad küsimused

Kas erinevus sõltub võtmejärjekorrast?

Ei: JSON-objekti puhul pole järjestus oluline. Võrdleja annab sama tulemuse kui võtmed on sorteeritud või mitte.

Kuidas käsitleda tabeleid, mille järjekord pole oluline?

Tööriist käsitleb massiive vaikimisi järjestatuna (see on JSON-i semantika). Kui ravite komplekte, sortige kaks massiivi enne võrdlemist loomuliku võtme järgi või kasutage teenust spetsiaalne võrdlustööriist, mis seda semantikat arvesse võtab.

Mis vahe on Git diffil?

Git võrdleb tekstiridu. Kui taane või võtmejärjestus erineb, on Git diff väga suur paljusõnaline. JSON-i erinevus töötab sõelutud struktuuris ja teatab ainult andmelünkadest.

Kas kehtetu JSON on aktsepteeritud?

Ei: kui üks kahest JSON-ist ei sõelu, tagastab tööriist veateate. Kinnitage esmalt meiega JSON-validaator.

Päringunäide

curl -X POST https://cdrn.fr/api/v1/tools/json-diff/execute \
  -H "Content-Type: application/json" \
  -d '{"left":"...","right":"..."}'

Sisendskeem

Väli Tüüp Kohustuslik Vaikimisi
left text
right text

Lõpp-punktid

  • GET https://cdrn.fr/api/v1/tools - loetleb kõik saadaolevad tööriistad
  • GET https://cdrn.fr/api/v1/tools/json-diff - toob selle tööriista skeemi
  • POST https://cdrn.fr/api/v1/tools/json-diff/execute - täidab selle tööriista JSON-payloadiga