Comparar JSON
Compara dois documentos pela estrutura: reformatar ou mudar a ordem das chaves não conta.
Nada do que você cola sai do seu navegador. A lista de permissões connect-src transforma isso em uma garantia do navegador, e não em uma promessa. Confira você mesmo
Isto compara dois documentos pela estrutura, não pela linha. Reformate um deles, ordene as chaves, mude a indentação: o diff continua vazio, porque nada disso alterou os dados.
Um diff de texto sobre JSON é praticamente inútil exatamente por isso. Reserialize um documento com outra biblioteca e todas as linhas aparecem como alteradas sem que nada tenha mudado.
O que conta como diferença
Quatro tipos de mudança, cada um reportado com um JSON Pointer para o local exato.
- Adicionado
- Uma chave ou elemento presente à direita e ausente à esquerda.
- Removido
- Presente à esquerda e ausente à direita.
- Alterado
- Presente nos dois com um valor diferente do mesmo tipo.
- Tipo trocado
- Presente nos dois com um tipo diferente. Vale separar, porque um número que virou string costuma ser um bug de serialização e não uma mudança de dados.
Como os arrays são comparados, e por que isso importa
Arrays são a parte difícil de qualquer diff estrutural, e não existe uma única resposta certa.
Comparar posição a posição está certo para uma tupla de formato fixo e é catastrófico para uma lista. Insira um elemento no começo de um array de mil elementos e todas as posições seguintes aparecem como alteradas, o que enterra a única diferença real embaixo de mil falsas.
Esta ferramenta faz em vez disso uma passada de maior subsequência comum, então uma inserção é reportada como inserção. Isso custa tempo proporcional ao produto dos dois comprimentos, então acima de um limiar ela volta para a comparação posicional e diz isso nas notas. Ela nunca degrada em silêncio.
Coisas que de propósito não são diferenças
- A ordem das chaves
- Objetos JSON não têm ordem segundo a especificação. Dois documentos com os mesmos membros em ordem diferente são o mesmo documento.
- Espaço em branco e indentação
- Não significativos para um parser, então invisíveis aqui.
- 0 e -0
- Distintos sob Object.is, mas idênticos como números JSON.
How to do this in code
Comparação estrutural em código.
sh jq
A primeira linha é a que vale lembrar. Ordenar as chaves antes tira quase todo o ruído de um diff de texto.
# Sort keys recursively, then diff the text. Cheap and
# surprisingly effective for small documents.
diff <(jq -S . a.json) <(jq -S . b.json)
# Keys present in one and not the other
jq -n --slurpfile a a.json --slurpfile b b.json \
'($a[0] | paths) - ($b[0] | paths)' py Python
from deepdiff import DeepDiff
diff = DeepDiff(a, b, ignore_order=True)
print(diff)
# Standard library only, for a shallow comparison
changed = {k for k in a.keys() | b.keys() if a.get(k) != b.get(k)} js JavaScript
JSON Patch é o formato padrão para transmitir um diff de JSON, e os caminhos dele são ponteiros RFC 6901 como os que esta ferramenta reporta.
import { compare } from 'fast-json-patch';
// RFC 6902 JSON Patch: a list of operations that turns a into b
const patch = compare(a, b);
// [{ op: 'replace', path: '/user/name', value: 'Priya' }] go Go
go-cmp é a escolha padrão nos testes em Go e produz uma saída legível para estruturas aninhadas.
import "github.com/google/go-cmp/cmp"
if d := cmp.Diff(a, b); d != "" {
t.Errorf("mismatch (-want +got):\n%s", d)
} Perguntas frequentes
- Por que reordenar as chaves não mostra diferença nenhuma?
- Porque a RFC 8259 define um objeto como uma coleção sem ordem. Na prática todo parser preserva a ordem de inserção, e diffs que dependem disso estão testando a serialização e não os dados.
- Dá para ignorar campos como timestamps?
- Sim. Ignorar um caminho tira ele por completo da comparação, que é como se comparam duas respostas de API que só diferem em requestId e generatedAt.
- O que é um JSON Pointer?
- A RFC 6901: um caminho separado por barras como /users/0/email. Dentro de uma chave dois caracteres precisam de escape: ~ vira ~0 e / vira ~1. Cada mudança reportada aqui carrega um, então você consegue endereçar o local por programa.