Resposta A
Resposta B

Diff de resposta de API: comparar payloads JSON de API online

Cole a resposta esperada à esquerda, a resposta efetivamente recebida à direita, e veja cada campo que mudou. Feito para trabalho de backend, QA e integração. Nada sai do seu navegador.

O que é esta ferramenta de diff de resposta de API

Uma ferramenta gratuita, no próprio navegador, para comparar dois corpos de resposta HTTP de API. Cole o JSON obtido do staging à esquerda, o JSON obtido da produção à direita, e as diferenças são destacadas caractere por caractere. O texto nunca sai da sua máquina, o que importa porque respostas reais de API contêm com frequência endereços de email de clientes, tokens de sessão, IDs internos de usuário e outras coisas que você não quer enviar para um site de diff de terceiros.

Foi feita para o momento em que um teste de integração instável quebra na CI, e você tem uma captura do Postman de uma resposta funcional no seu notebook e um log de CI de uma resposta quebrada vinda do build runner. Subir um contract test do Pact completo para uma investigação pontual é exagero. Dois painéis de texto, um diff, e normalmente dá para isolar o problema em um único campo em menos de um minuto.

Por baixo, o motor de diff é o mesmo da nossa ferramenta compare-json. Apenas o enquadramos para o fluxo de testes de API. Se suas respostas são em XML ou envelopes SOAP, nossa página compare-xml dá conta. Se você está comparando texto livre como um log de webhook ou uma trilha de auditoria, nossa ferramenta compare-text é a porta de entrada certa.

Como um diff de resposta de API ajuda de fato

Um diff de resposta de API fica na lacuna entre duas ideias de teste relacionadas mas distintas. O diff de schema do OpenAPI 3.1 diz o que seu contrato declara ter mudado: um novo campo opcional, uma propriedade renomeada, um enum mais restrito. O snapshot testing (snapshots do Jest, snapshots do Vitest, pytest-snapshot) diz o que seu código produziu em relação a um fixture salvo. Esta ferramenta fica do lado do runtime. Você fornece dois corpos de resposta reais e ela mostra cada byte que difere, independentemente de o schema permitir a mudança ou de o seu fixture de snapshot estar atualizado.

Por que isso é útil? Porque os bugs que mais doem em trabalho de integração REST não são violações de schema. São desvios sutis: um serializer que silenciosamente trocou uma data de ISO-8601 para timestamp Unix após um upgrade do Jackson, um schema do Marshmallow que passou a emitir null em vez de omitir um campo ausente, um ViewSet do DRF que começou a embrulhar o payload em um envelope data após uma mudança de middleware. A spec OpenAPI não mudou. O snapshot não foi atualizado. Os testes passaram isolados. A integração quebrou. Um diff de corpo de resposta pega tudo isso porque não se importa com o contrato; se importa com os bytes.

Campos voláteis são o principal a vigiar. Timestamps, request IDs, trace IDs, UUIDs gerados pelo servidor e cursores de paginação vão diferir entre quaisquer duas capturas do mesmo endpoint, mesmo quando nada significativo mudou. O movimento certo é normalizar antes do diff: substitua timestamps por um placeholder, remova trace IDs, ordene arrays cuja ordem não seja contratualmente significativa. Ferramentas como o Pact tratam isso com matchers; nesta ferramenta você trata editando os painéis. Leva dez segundos e elimina o ruído de fundo.

Como fazer diff de uma resposta de API em três passos

Dois painéis de texto, um diff. Sem login, sem upload, sem proxy para configurar.

  1. 1

    Capture a primeira resposta

    Bata no endpoint com curl, httpie, Postman, Insomnia, ou o que sua equipe usar. curl -s https://api.example.com/v1/users/123 | jq é uma boa base porque o jq formata o JSON de modo legível, o que torna o diff bem mais fácil de ler. Copie o corpo (apenas o JSON, sem cabeçalhos) e cole no painel da esquerda. Se estiver puxando de um log de CI, retire o prefixo de timestamp que a maioria dos loggers adiciona para que o diff caia sobre o payload real.

  2. 2

    Capture a segunda resposta

    Bata na fonte de comparação: o outro ambiente, a outra versão da API, o outro fornecedor. Mesma forma de captura, mesmo passo de pretty-print. Cole no painel da direita. Se uma captura vier de um fixture gravado (vcrpy, pollyjs, MSW, nock) e a outra for ao vivo, normalize primeiro os campos voláteis óbvios: limpe o request_id, troque timestamps por uma constante, e remova quaisquer trace headers que tenham vazado para o corpo. O diff restante é o sinal de verdade.

  3. 3

    Leia as diferenças destacadas

    Remoções aparecem como tachados vermelhos à esquerda; inserções aparecem em verde à direita. Os contadores de mudanças em cada cabeçalho dizem quantas edições distintas o diff encontrou. Foque primeiro em três coisas: mudanças em strings de status, chaves ausentes ou adicionadas, e mudanças de tipo de valor (string para number, object para null). Essas três categorias cobrem quase toda regressão real de API. Mudanças de formato e ordenação costumam ser ruído, a menos que seu consumer dependa delas.

Quando um diff de resposta de API é a escolha certa

Reproduzir um teste de integração instável

Um teste passa local e quebra na CI. Você tem a resposta capturada pelo seu Postman local e a resposta capturada pelo agente de build da CI (a maioria dos sistemas de CI consegue dumpar request/response com uma flag verbose). Cole as duas na ferramenta de diff. Em nove de cada dez casos a diferença é ambiental: uma feature flag diferente, um fixture desatualizado, um offset de fuso horário no runner. O caso restante é um bug real, e você acabou de localizá-lo num campo específico.

Validar um fixture contra uma resposta nova

Seu repo tem um arquivo de fixture commitado que mocka uma API de terceiros para os testes. O provedor upstream acabou de liberar uma nova versão minor. Bata no endpoint ao vivo com curl, cole essa resposta ao lado do seu fixture e veja exatamente quais campos derivaram. Esta é a versão manual do que ferramentas de replay estilo VCR automatizam. Útil quando você quer atualizar um único fixture sem regravar a suíte de testes inteira.

Verificar compatibilidade reversa entre versões de API

Você está prestes a publicar a v2 de uma API interna. Um cliente v1 ainda existe em produção. Bata em /v1/orders/42 e /v2/orders/42 e tire o diff das respostas. Qualquer campo removido, qualquer chave renomeada, qualquer mudança de tipo de valor é um breaking change para o cliente v1. Qualquer campo novo é aditivo e seguro. É uma versão pobre de um contract test consumer-driven; não escala para dezenas de endpoints, mas para uma checagem rápida em um ou dois funciona.

Detectar uma regressão de serializer

Sua equipe atualizou Jackson, Marshmallow, DRF, ou uma camada de serialização parecida. Os testes passam. Em seguida um consumer downstream relata que o parser dele está engasgando. Capture a resposta do mesmo endpoint na branch antiga e na nova e tire o diff. Achados comuns: um formato de data virou de 2026-05-09T10:00:00Z para timestamp Unix, decimais perderam zeros à direita, um enum começou a ser serializado como inteiro em vez de string, ou campos null começaram a aparecer no payload em vez de serem omitidos.

Comparar payloads de webhook entre dois provedores ou versões

Webhook V1 e V2 do Stripe do mesmo tipo de evento parecem quase idênticos e não são nada disso. O mesmo vale para payloads de eventos de webhook do GitHub entre versões de API, e para event subscriptions do Slack entre escopos. Cole um payload de exemplo de cada um na ferramenta de diff para ver os campos renomeados, os objetos aninhados que se moveram e os novos blocos de metadados. É mais rápido do que ler as duas páginas de doc do provedor lado a lado, especialmente quando a doc passa por cima de quais campos realmente aparecem na prática.

Depurar o clássico "funciona em staging, quebra em prod"

A dor de cabeça clássica de deploy. A mesma requisição do cliente retorna JSON sutilmente diferente do staging e da produção. Capture os dois, cole os dois, e a diferença geralmente é uma flag de configuração, um feature gate ausente, ou uma resposta cacheada antiga. Aplica-se igualmente a debug multi-região (us-east-1 vs eu-west-1 retornando dados diferentes), problemas de cache de CDN (Cloudflare cacheou um corpo antigo), e atraso de read replica em que uma escrita não se propagou para todo lugar.

Casos de borda do diff de resposta de API que vale conhecer

Os casos em que um diff de corpo de resposta discorda do que seu framework de testes, sua ferramenta de OpenAPI, ou seus olhos diriam. Vale dar uma olhada antes de assumir que o diff achou um bug real.

TopicWhat this tool does
Campos voláteis (timestamps, IDs)created_at, updated_at, request_id, trace_id, UUIDs gerados pelo servidor e cursores de paginação sempre diferem entre duas capturas. Normalize com jq 'del(...)', troque por uma constante, ou apenas edite-os antes do diff. O sinal que de fato importa mora em outro lugar.
null vs chave ausente{"foo": null} e {} são diferentes em JSON, e muitos serializers (Marshmallow, Jackson, System.Text.Json) têm configurações que alternam entre os dois. O diff vai trazer isso à tona. Alguns clientes tratam como equivalentes e outros não; a resposta certa é o que seu consumer faz, e por isso é uma fonte frequente de regressão depois de um upgrade de serializer.
Ordem das chavesA RFC 8259 define objetos JSON como desordenados. Duas respostas semanticamente idênticas com ordens de chave diferentes vão aparecer como diff aqui porque a comparação textual é sensível à ordem. Pré-ordene os dois lados com jq --sort-keys se quiser diff insensível à ordem. Atenção ao raro consumer que depende da ordem (alguns fluxos de assinatura, alguns parsers legados).
Ordem dos arraysArrays em JSON são ordenados, mas muitas APIs retornam arrays cuja ordem não é de fato contratual: uma lista de permissões, uma lista de feature flags, uma lista de assinaturas de webhook. O diff marcará um array reordenado como mudança mesmo quando nenhum consumer se importa. Se reordenar é inofensivo no seu domínio, ordene os dois lados por uma chave estável antes do diff.
Estrita do JSON.parseO diff trata sua entrada como texto opaco. Se uma de suas capturas tem vírgula final, chave sem aspas, ou comentário (todos ilegais em JSON estrito), ele ainda fará o diff, mas vai parecer mais ruidoso do que o necessário. Passe ambas as capturas por jq . primeiro para reformatar e rejeitar entrada inválida. jq usa um parser RFC 8259 estrito.
Embrulho de resposta (envelope data vs plano)Muitas APIs embrulham payloads num envelope {"data": ...}, às vezes adicionando meta, links, ou included ao lado (JSON:API e similares). Uma migração de plano para embrulhado (ou vice-versa) é um breaking change que aparece imediatamente num diff mas é fácil de passar batido numa revisão de schema porque o registro interno parece o mesmo.
Mudanças no cursor de paginaçãoPaginação por cursor usa tokens opacos (next_cursor, after, page_token) projetados para mudar a cada chamada. Sempre aparecerão como diff. Remova-os antes de comparar, ou compare apenas o conteúdo do array data e ignore o bloco de paginação inteiro.
Formatos de resposta de erroCorpos de erro são o velho oeste. Algumas APIs retornam um {"error": "..."} plano, outras retornam RFC 7807 Problem Details com type, title, status, detail, instance, e outras retornam um formato proprietário. Uma migração para RFC 7807 a partir de um formato customizado produzirá um diff grande que é majoritariamente uma melhoria; uma migração no sentido contrário é uma regressão que vale pegar cedo.

Diff de resposta de API: perguntas frequentes

Como isso difere do recurso de diff embutido do Postman?

O Postman tem uma visão de comparação de resposta dentro do Collection Runner e um recurso Visualize para respostas individuais. Ambos são bons se você vive dentro do Postman e suas respostas já estão salvas como itens de histórico do Postman. Esta ferramenta é agnóstica ao provedor. Você pode colar a partir de Postman, Insomnia, curl, httpie, log de CI, snippet de Stack Overflow, ou mensagem de Slack de um colega. Sem conta, sem workspace, sem sync. Para comparações pontuais entre ferramentas, isso é mais rápido. Para testes de API compartilhados em equipe dentro de uma única plataforma, o recurso próprio do Postman serve.

Como lidar com campos voláteis como timestamps e request IDs?

O movimento pragmático é normalizar antes do diff. Abra os dois colados nos painéis e edite os campos voláteis diretamente: troque timestamps por uma string constante, remova os valores de request_id e trace_id, apague cursores de paginação que mudam a cada chamada. O diff destaca apenas as diferenças restantes, que são as que de fato importam. Para comparações repetidas do mesmo endpoint, você também pode passar a resposta por jq com um filtro delete (jq 'del(.meta.request_id)') antes de colar.

Como isso difere de um diff de schema OpenAPI?

Diff de schema compara contratos: diz que POST /orders ganhou um campo opcional discount_code, ou que o enum status ganhou um novo valor. Ferramentas conscientes de OpenAPI como oasdiff ou Spectral fazem isso bem. Esta ferramenta compara corpos de resposta reais. As duas são complementares. Diff de schema pega mudanças de contrato; diff de resposta pega o desvio entre contrato e realidade, que é onde se escondem os bugs de serialização, os descompassos de ambiente e os fixtures desatualizados.

Suporta respostas grandes?

Na prática sim, até alguns milhares de linhas de JSON formatado de cada lado. Acima disso, o diff de caractere com limpeza semântica fica lento, porque roda no seu navegador e não num servidor. Para payloads muito grandes (pense num dump paginado de 10.000 registros), a abordagem certa é cortar a resposta em pedaços menores por registro ou por chave de topo e fazer o diff de cada pedaço separadamente. Ou rodar um diff estrutural na linha de comando com jd ou diff <(jq . a.json) <(jq . b.json) para velocidade pura.

Funciona para respostas XML ou SOAP?

Diretamente não. Esta página é afinada para JSON, que é o que a maioria dos payloads modernos de REST e webhook usa. Se você precisa fazer diff de XML, envelopes SOAP, RSS, ou configuração estilo POM, nossa ferramenta compare-xml é a porta de entrada certa; ela lida com indentação e formatação de namespace corretamente. Para corpos de resposta crus que misturam cabeçalhos e corpo, ou para APIs em texto puro (alguns sistemas legados ainda retornam text/plain), compare-text faz o trabalho sem tentar impor uma estrutura.

Preserva a ordem das chaves ou as ordena?

Preserva a ordem das chaves que você cola. Objetos JSON são formalmente desordenados pela RFC 8259, então duas respostas semanticamente idênticas com chaves em ordens diferentes vão aparecer como diff nesta ferramenta. Se quiser ignorar a ordem, normalize os dois lados primeiro passando por jq --sort-keys ou equivalente. A maioria dos clientes não depende da ordem das chaves, então normalizar com chaves ordenadas é um padrão seguro para comparar respostas; mas saiba que alguns consumers legados (pontes XML-para-JSON antigas, certos fluxos de assinatura digital) dependem da ordem.

Privacidade e por que ela importa para respostas de API

Payloads de resposta de API contêm com frequência coisas que você não quer vazar. Endereços de email de clientes. IDs internos de usuário. Tokens de sessão. Tokens bearer de auth que acabaram num campo do corpo por engano. IDs de cliente do Stripe. Segredos de webhook. Campos PII como nomes, endereços e telefones. Colar um deles num serviço de diff hospedado na nuvem é em si um evento de tratamento de dados, e dependendo do seu setor pode violar seus controles SOC 2, contratos de tratamento de dados do GDPR, ou Business Associate Agreements do HIPAA. Esta ferramenta roda inteiramente no seu navegador. Nada é enviado, registrado, ou transmitido para qualquer serviço de terceiros. O diff, o destaque e a renderização rodam todos na sua máquina. Verificar a alegação é direto: abra as DevTools do seu navegador, vá para a aba Network, cole as duas respostas, e observe. Não há requisições saindo durante a comparação. Para orientação mais ampla de design e segurança de API, as boas práticas de design de API da Microsoft são uma referência sólida.