Comparar documentos JSON e gerar um patch

Cole as versões anterior e posterior para comparar a estrutura. Arrays são comparados por índice; revise itens reordenados antes de aplicar o patch.

Funciona localmente no seu navegador
Before
After
Changes
  • Compare two documents to inspect structural changes.
JSON Patch RFC 6902 operation list
Compare two JSON documents to generate a JSON Patch.

Arrays são comparados por índice. Revise os patches quando houver arrays reordenados ou campos de identidade específicos do domínio antes de aplicá-los a um documento de produção.

Como comparar dois documentos JSON

Cole o documento original à esquerda e a versão editada à direita e clique em Comparar: a página lista cada valor adicionado, removido ou alterado com o seu caminho — 7.143 mudanças entre dois objetos de 50.000 chaves, na ordem do percurso.

O resultado é um JSON Patch (RFC 6902) que transforma o primeiro documento no segundo: um array de operações add, remove e replace com caminhos JSON Pointer. A análise e a comparação acontecem na página, então nada é enviado e o comparador continua igual quando a rede cai.

  1. Cole o documento anterior na área da esquerda e o posterior na da direita. Carregar exemplo preenche as duas com um par pequeno para mostrar o formato do resultado.
  2. Clique em Comparar. Acima da lista aparecem os contadores — adicionados, removidos, alterados — e cada linha traz o ponteiro para o valor e uma prévia limitada a 120 caracteres.
  3. Leia o patch abaixo: é o documento RFC 6902 completo, indentado, pronto para colar numa suíte de testes, num script de migração ou numa requisição HTTP PATCH.
  4. Copiar patch coloca o resultado na área de transferência e Limpar esvazia as duas áreas. Se uma delas não puder ser analisada, a linha de status indica qual documento falhou — Before JSON ou After JSON — com a posição do erro, e o resultado anterior é descartado.

O que o patch mostra e o que não mostra

O que conta como diferença

A ordem das chaves não é diferença: {"a":1,"b":2} contra {"b":2,"a":1} dá 0 mudanças. Números são comparados como doubles do JavaScript, por isso 1 e 1.0 são o mesmo valor, enquanto 1e2 chega como 100 e aparece como uma mudança.

Tipos nunca são convertidos: 1 contra "1" é mudança, true contra 1 também, e uma chave com null não é o mesmo que uma chave ausente — null no primeiro documento e ausente no segundo resulta em remove /a em vez de coincidência. Chaves duplicadas mantêm o último valor, já que a área é lida com JSON.parse: {"a":1,"a":2} contra {"a":2} informa 0 mudanças.

Arrays são comparados por índice

Não existe operação move na saída. O array é percorrido posição por posição, então reordenar aparece como uma sequência de replace: [1,2] contra [2,1] gera replace /0 com 2 e replace /1 com 1.

Mudanças de tamanho saem do fim para o começo: [1,2,3,4] contra [1,2] remove /3 e depois /2, e [1,2] contra [1,2,3,4] adiciona /2 e /3. Assim cada operação continua válida quando o patch é aplicado de cima para baixo.

Ponteiros, escapes e chaves vazias

Cada caminho é um JSON Pointer conforme a RFC 6901. Chaves com barra ou til são escapadas: a/b aparece como /a~1b e c~d como /c~0d.

Uma chave vazia também recebe ponteiro — o caminho fica / — e o documento raiz tem caminho vazio, então substituí-lo inteiro é uma única operação com path "".

Onde a comparação roda

A análise e a comparação ocorrem na página. Ao carregar a ferramenta e comparar dois objetos de 50.000 chaves, nenhuma requisição saiu além dos próprios recursos da página: os documentos não saem do navegador, e depois de carregada a ferramenta funciona sem conexão.

Valem os limites do analisador JSON: inteiros acima de 2^53 perdem precisão, então 9007199254740993 e 9007199254740992 são considerados idênticos, e um aninhamento de 20.000 níveis foi comparado e corrigido sem erro. O tempo acompanha o número de mudanças: 50.000 chaves levaram cerca de meio segundo e geraram 511 KB de patch, e 500.000 chaves cerca de cinco segundos e 5,25 MB. Revise o patch antes de aplicá-lo a dados de produção.

Ferramentas recentes: