Salīdzināt divas JSON struktūras

salīdzina divas JSON struktūras un uzskaita papildinājumus, dzēšanas un izmaiņas, atslēgu pēc atslēgas

Kāpēc salīdzināt divus JSON?

Izstrādātāja dzīvē regulāri rodas divu JSON struktūru salīdzināšana. API atbilde kas mainās pēc atjaunināšanas. Konfigurācijas fails, kas atšķiras starp divām vidēm. A objektu eksportēšana, kas jāsaskaņo ar atsauci. JSON atšķirība precīzi reaģē šis jautājums: kas tika pievienots, dzēsts vai mainīts un kur?

Ar rindiņu pa rindiņām diff (a la git diff) bieži vien nepietiek. Ja formatējums atšķiras (atstarpes, taustiņu secība), teksta atšķirības ziņo simtiem rindu, kamēr struktūra dati ir identiski. Pēc parsēšanas struktūras darbojas JSON salīdzinātājs, kas to novērš troksni un atklāj tikai semantiskās atšķirības.

Rīka radītās atšķirības formāts

Katrai novirzei rīks atgriež:

  • ceļš vienkāršotā JSONPath formātā, piemēram, $.user.address[0].city;
  • viens veids starp pievienotajiem (pievienots labajā pusē), noņemts (parādīts kreisajā pusē tikai), modificēts (dažādas vērtības);
  • kreisā vērtība un/vai labā vērtība atkarībā no veida.

Tukša atšķirība nozīmē, ka abi JSON ir strukturāli identiski neatkarīgi no to veida formatēšana vai atslēgu secība.

Kā algoritms šķērso divas struktūras

Algoritms ir rekursīvs. Katrā līmenī tas identificē divu salīdzināto vērtību veidu:

  • Ja abi ir asociatīvie objekti, ir nepieciešams taustiņu savienojums. Katrai atslēgai, tā rekursīvi samazinās vai atzīmē pievienotu/noņemtu, ja atslēga ir tikai vienā pusē.
  • Ja abi ir sakārtoti masīvi, tiek salīdzināta pozīcija pēc pozīcijas. A atšķirība tabulas sākumā var mainīt visu pārējo, kas rada daudznozīmīgu atšķirību: tas ir a pieņemtā naivās strukturālās atšķirības robeža.
  • Ja tipi atšķiras (objekts pret masīvu, skalārs pret nulli), tas tiek atzīmēts pārveidots.
  • Ja abas vērtības ir skalāri (virkne, skaitlis, Būla vērtība, nulle), vienkārša pietiek ar stingru salīdzinājumu.

Atslēgu secībai objektā nav nozīmes: {"a": 1, "b": 2} un {"b": 2, "a": 1} radīt tukšu diferenciāciju. Tas atbilst JSON semantikai, kur secībai nav nozīmes. In Tomēr masīva elementu secībai ir nozīme: masīvs tiek sakārtots pēc konstrukcijas.

Konkrēts piemērs

Šeit ir divas lietotāja objekta versijas:

// pa kreisi
{
  "id": 42,
  "vārds": "Alise",
  "lomas": ["administrators", "redaktors"]
}

// pareizi
{
  "id": 42,
  "vārds": "Alise Mārtina",
  "lomas": ["administrators", "skatītājs"],
  "aktīvs": patiess
}

Atšķirība rada:

  • $.name: pārveidots, "Alise""Alise Mārtina"
  • $.roles[1]: pārveidots, "redaktors""skatītājs"
  • $.active: pievienots, true

Lietošanas gadījumi

  • Dažādas vides: salīdziniet galapunkta rezultātus pirmsražošanas un ražošanu. Ļoti noderīga migrācijas vai kešatmiņas atsvaidzināšanas laikā.
  • Migrācijas audits: salīdziniet eksportu pirms un pēc transformācijas, lai pārbaudītu ka neviens lauks nav zaudēts.
  • API regresija: pirms un pēc izmaiņām salīdziniet atbildi uz a identisks vaicājums. Tukša atšķirība apstiprina regresijas neesamību.
  • Konfigurācijas sinhronizācija: salīdziniet divus composer.json filiāles, divi .eslintrc faili, divas Symfony konfigurācijas.
  • Momentuzņēmumu testi: aizstājiet rindu salīdzinājumu ar salīdzinājumu strukturālā integrācijas testu komplektā.

Strukturālās atšķirības robežas

Sakārtoto masīvu salīdzināšana ir zināms naivu strukturālo atšķirību ierobežojums. Ja ievietojam a elements masīva sākumā, visas nākamās pozīcijas tiek nobīdītas un diferenciācija signalizē par katru novirzi kā modifikācija. Šādos gadījumos pastāv uzlaboti algoritmi (Myers, Patience, atšķir. pēc dabiskās atslēgas), taču tie pārsniedz vispārēja salīdzināšanas rīka darbības jomu.

Atšķirībā arī nav pateikts, kāpēc notika izmaiņas: tas ir novērojums. Lai analizētu a regresijas gadījumā šim novērojumam jābūt savstarpējai atsaucei ar saistībām, izvietošanu un parametriem vaicājums.

JSON atšķirība pret JSON ielāpu (RFC 6902)

Papildu formāts ir JSON ielāps (RFC 6902). Tas apraksta darbību veidā (pievienot, noņemt, aizstāt, pārvietot, kopēt, pārbaudīt), kā pārveidot vienu JSON dokumentu citā. Kur mūsu atšķirība ir novērojums (cilvēks), JSON ielāps ir recepte (mašīna). Abi attēlojumi ir līdzvērtīgi vienkāršos gadījumos, un JSON ielāps ir noderīgs RESTful API, kas pieņem modifikācijas daļēja.

Bieži uzdotie jautājumi

Vai atšķirība ir atkarīga no atslēgu secības?

Nē: JSON objektam secība nav nozīmīga. Salīdzinātājs rada tādu pašu rezultātu kā atslēgas ir sakārtotas vai nav.

Kā rīkoties ar tabulām, kuru secība nav svarīga?

Rīks masīvus uzskata par sakārtotiem pēc noklusējuma (tā ir JSON semantika). Ja jūs ārstējat kopas, pirms salīdzināšanas kārtojiet divus masīvus pēc dabiskās atslēgas vai izmantojiet pakalpojumu specializēts salīdzināšanas rīks, kas ņem vērā šo semantiku.

Kāda ir atšķirība no Git atšķirības?

Gits salīdzina teksta rindiņas. Ja atkāpe vai atslēgu secība atšķiras, Git atšķirība ir ļoti liela runīgs. JSON diferenciācija darbojas parsētajā struktūrā un ziņo tikai par datu nepilnībām.

Vai tiek pieņemts nederīgs JSON?

Nē: ja viens no diviem JSON netiek parsēts, rīks atgriež kļūdu. Vispirms apstipriniet ar mūsu palīdzību JSON pārbaudītājs.

Pieprasījuma piemērs

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

Ievades shēma

Lauks Tips Obligāts Noklusējums
left text
right text

Endpoint

  • GET https://cdrn.fr/api/v1/tools - uzskaita visus pieejamos rīkus
  • GET https://cdrn.fr/api/v1/tools/json-diff - iegūst šī rīka shēmu
  • POST https://cdrn.fr/api/v1/tools/json-diff/execute - izpilda šo rīku ar JSON payload