Diff di risposta API: confronta payload JSON di API online
Incolla a sinistra la risposta che ti aspettavi, a destra la risposta effettivamente ricevuta, e vedi ogni campo che è cambiato. Pensato per lavoro di backend, QA e integrazione. Nulla esce dal tuo browser.
Cos'è questo strumento di diff per risposte API
Uno strumento gratuito, in-browser, per confrontare due body di risposta HTTP di API. Incolla a sinistra il JSON ottenuto da staging, a destra il JSON ottenuto da produzione, e le differenze vengono evidenziate carattere per carattere. Il testo non lascia mai la tua macchina, cosa che conta perché le risposte API reali contengono spesso indirizzi email di clienti, token di sessione, ID utente interni e altre cose che non vuoi caricare su un sito di diff di terze parti.
È pensato per il momento in cui un test di integrazione instabile fallisce in CI, e hai uno screenshot Postman di una risposta funzionante sul portatile e un log CI di una risposta rotta dal build runner. Tirare su un contract test Pact completo per un'indagine una tantum è eccessivo. Due pannelli di testo, un diff, e in genere riesci a restringere il problema a un singolo campo in meno di un minuto.
Sotto il cofano, il motore di diff è lo stesso che alimenta il nostro strumento compare-json. L'abbiamo solo riposizionato per il flusso di test API. Se le tue risposte sono XML o envelope SOAP, la nostra pagina compare-xml le gestisce. Se stai confrontando testo libero come un log webhook o un audit trail, il nostro strumento compare-text è la porta giusta.
In che modo un diff di risposta API aiuta davvero
Un diff di risposta API si colloca nello spazio fra due idee di test correlate ma distinte. Il diff di schema OpenAPI 3.1 ti dice cosa il tuo contratto dichiara di aver cambiato: un nuovo campo opzionale, una proprietà rinominata, un enum più stretto. Lo snapshot testing (snapshot Jest, snapshot Vitest, pytest-snapshot) ti dice cosa il tuo codice ha prodotto rispetto a una fixture salvata. Questo strumento sta sul lato runtime. Gli passi due body di risposta reali e ti mostra ogni byte che differisce, indipendentemente dal fatto che lo schema permetta il cambiamento o che la tua fixture di snapshot sia aggiornata.
Perché è utile? Perché i bug che mordono di più nel lavoro di integrazione REST non sono violazioni di schema. Sono drift sottili: un serializer che ha silenziosamente cambiato una data da ISO-8601 a un timestamp Unix dopo un upgrade di Jackson, uno schema Marshmallow che ha iniziato a emettere null invece di omettere un campo mancante, un ViewSet DRF che ha cominciato a incartare il payload in un envelope data dopo una modifica di middleware. La spec OpenAPI non è cambiata. Lo snapshot non è stato aggiornato. I test sono passati in isolamento. L'integrazione si è rotta. Un diff sul body della risposta intercetta tutti questi casi perché non si interessa al contratto; si interessa ai byte.
I campi volatili sono la cosa principale a cui prestare attenzione. Timestamp, request ID, trace ID, UUID generati dal server e cursori di paginazione differiranno fra due qualunque catture dello stesso endpoint, anche quando nulla di significativo è cambiato. La mossa giusta è normalizzare prima del diff: sostituisci i timestamp con un placeholder, togli i trace ID, ordina gli array dove l'ordine non è contrattualmente significativo. Strumenti come Pact lo gestiscono con i matcher; in questo strumento lo gestisci editando i pannelli. Ci vogliono dieci secondi e si toglie il rumore di fondo.
Come fare il diff di una risposta API in tre passi
Due pannelli di testo, un diff. Niente login, niente upload, niente proxy da cablare.
- 1
Cattura la prima risposta
Chiama l'endpoint con curl, httpie, Postman, Insomnia, o quel che usa il tuo team. curl -s https://api.example.com/v1/users/123 | jq è una buona base perché jq formatta il JSON, cosa che rende il diff molto più leggibile. Copia il body (solo il JSON, non gli header) e incollalo nel pannello sinistro. Se lo prendi da un log CI, togli il prefisso di timestamp che la maggior parte dei logger aggiunge, così il diff cade sul payload reale.
- 2
Cattura la seconda risposta
Chiama la fonte di confronto: l'altro ambiente, l'altra versione di API, l'altro fornitore. Stessa forma di cattura, stesso passo di pretty-print. Incolla nel pannello destro. Se una cattura viene da una fixture registrata (vcrpy, pollyjs, MSW, nock) e l'altra è live, normalizza prima i campi volatili evidenti: pulisci il request_id, sostituisci i timestamp con una costante, e togli eventuali trace header finiti nel body. Il diff rimanente è il segnale vero.
- 3
Leggi le differenze evidenziate
Le rimozioni appaiono come barrato rosso a sinistra; le aggiunte in verde a destra. I contatori di modifiche in ogni header dicono quante edit distinte ha trovato il diff. Concentrati prima su tre cose: cambiamenti nelle stringhe di status, chiavi mancanti o aggiunte, e cambi di tipo di valore (string a number, object a null). Queste tre categorie coprono quasi ogni regressione API reale. Cambi di formato e ordine di solito sono rumore, a meno che il tuo consumer non ne dipenda.
Quando un diff di risposta API è la scelta giusta
Riprodurre un test di integrazione instabile
Un test passa in locale e fallisce in CI. Hai la risposta catturata dal tuo Postman locale e la risposta catturata dal build agent CI (la maggior parte dei sistemi CI può dumpare request/response con un flag verbose). Incolla entrambe nello strumento di diff. Nove volte su dieci la differenza è ambientale: un feature flag diverso, una fixture vecchia, un offset di fuso orario sul runner. La decima è un bug vero, e l'hai appena localizzato a un campo specifico.
Validare una fixture rispetto a una risposta fresca
Il tuo repo ha un file di fixture committato che mocka una API di terze parti per i test. Il provider upstream ha appena rilasciato una nuova versione minor. Chiama l'endpoint live con curl, incolla quella risposta accanto alla fixture, e vedi esattamente quali campi sono andati alla deriva. Questa è la versione manuale di ciò che strumenti di replay in stile VCR automatizzano. Utile quando vuoi aggiornare una sola fixture senza ri-registrare l'intera suite di test.
Verificare la retro-compatibilità fra versioni di API
Stai per pubblicare la v2 di un'API interna. In produzione esiste ancora un client v1. Chiama sia /v1/orders/42 sia /v2/orders/42 e fai il diff delle risposte. Qualunque campo rimosso, qualunque chiave rinominata, qualunque cambio di tipo di valore è un breaking change per il client v1. Qualunque campo nuovo è additivo e sicuro. È una versione povera di un contract test consumer-driven; non scala su decine di endpoint, ma per un sanity check rapido su uno o due funziona.
Individuare una regressione del serializer
Il tuo team ha aggiornato Jackson, Marshmallow, DRF o un layer di serializzazione simile. I test passano. Poi un consumer downstream segnala che il suo parser si strozza. Cattura la risposta dello stesso endpoint sul branch vecchio e sul nuovo e fai il diff. Ritrovamenti comuni: un formato di data passato da 2026-05-09T10:00:00Z a un timestamp Unix, decimali che hanno perso gli zeri finali, un enum che inizia a serializzarsi come integer invece che string, o campi null che appaiono nel payload mentre prima venivano omessi.
Confrontare payload webhook fra due provider o versioni
I webhook V1 e V2 di Stripe per lo stesso tipo di evento sembrano quasi identici e non lo sono affatto. Lo stesso vale per i payload di evento webhook GitHub fra versioni di API, e per le event subscription Slack fra scope. Incolla un payload di esempio di ciascuno nello strumento di diff per vedere i campi rinominati, gli oggetti annidati spostati, e i nuovi blocchi di metadata. È più veloce che leggere fianco a fianco le due pagine di doc del provider, soprattutto quando la doc glissa su quali campi compaiono davvero in pratica.
Debuggare il classico "funziona in staging, rotto in prod"
Il classico mal di testa da deploy. La stessa richiesta del client restituisce JSON sottilmente diverso da staging e da produzione. Cattura entrambe, incolla entrambe, e la differenza di solito è un flag di config, un feature gate mancante, o una risposta cached vecchia. Vale ugualmente per il debug multi-region (us-east-1 vs eu-west-1 che restituiscono dati diversi), problemi di cache CDN (Cloudflare ha cached un body vecchio), e lag di read replica in cui una scrittura non si è propagata ovunque.
Edge case del diff di risposta API utili da conoscere
I casi in cui un diff di body di risposta non concorda con quello che direbbero il tuo framework di test, il tuo strumento OpenAPI, o i tuoi occhi. Vale la pena scorrerli prima di assumere che il diff abbia trovato un bug vero.
| Topic | What this tool does |
|---|
| Campi volatili (timestamp, ID) | created_at, updated_at, request_id, trace_id, UUID generati dal server e cursori di paginazione differiranno sempre fra due catture. Normalizzali con jq 'del(...)', sostituisci con una costante, oppure semplicemente toglili prima del diff. Il segnale che davvero conta è altrove. |
|---|
| null vs chiave mancante | {"foo": null} e {} sono diversi in JSON, e molti serializer (Marshmallow, Jackson, System.Text.Json) hanno impostazioni che oscillano fra i due. Il diff lo farà emergere. Alcuni client li trattano come equivalenti e altri no; la risposta giusta è ciò che fa il tuo consumer, ed è per questo che è una fonte frequente di regressione dopo un upgrade di serializer. |
|---|
| Ordine delle chiavi | RFC 8259 definisce gli oggetti JSON come non ordinati. Due risposte semanticamente identiche con ordine di chiavi diverso appariranno qui come diff perché il confronto testuale è sensibile all'ordine. Pre-ordina entrambi i lati con jq --sort-keys se vuoi un diff insensibile all'ordine. Attenzione al raro consumer che dipende dall'ordine (alcuni flussi di firma, certi parser legacy). |
|---|
| Ordine degli array | Gli array in JSON sono ordinati, ma molte API restituiscono array il cui ordine non è effettivamente contrattuale: una lista di permessi, una lista di feature flag, una lista di subscription a webhook. Un diff segnerà come cambiamento un array riordinato anche quando nessun consumer se ne preoccupa. Se riordinare è innocuo nel tuo dominio, ordina entrambi i lati su una chiave stabile prima del diff. |
|---|
| Severità di JSON.parse | Il diff tratta il tuo input come testo opaco. Se una delle tue catture ha una virgola finale, una chiave senza apici, o un commento (tutti illegali in JSON stretto), il diff girerà comunque ma sembrerà più rumoroso del necessario. Fai prima passare entrambe le catture per jq . per riformattare e rifiutare input non valido. jq usa un parser RFC 8259 stretto. |
|---|
| Wrapping di risposta (envelope data vs flat) | Molte API incartano i payload in un envelope {"data": ...}, a volte aggiungendo meta, links, o included a fianco (JSON:API e simili). Una migrazione da flat a wrapped (o viceversa) è un breaking change che compare subito in un diff ma è facile da mancare in una review di schema perché il record sottostante sembra lo stesso. |
|---|
| Cambi di cursore di paginazione | La paginazione a cursore usa token opachi (next_cursor, after, page_token) progettati per cambiare a ogni chiamata. Compariranno sempre come diff. Toglili prima di confrontare, o confronta solo il contenuto dell'array data e ignora del tutto il blocco di paginazione. |
|---|
| Formati di risposta di errore | I body di errore sono il far west. Alcune API restituiscono un {"error": "..."} piatto, altre restituiscono RFC 7807 Problem Details con type, title, status, detail, instance, e altre restituiscono una forma proprietaria. Una migrazione a RFC 7807 da una forma custom produrrà un diff grosso che è perlopiù un miglioramento; una migrazione nella direzione opposta è una regressione che vale la pena prendere presto. |
|---|
Diff di risposta API: domande frequenti
In cosa si differenzia dalla funzione di diff integrata di Postman?
Postman ha una vista di confronto risposte dentro il Collection Runner e una funzione Visualize per le singole risposte. Entrambe vanno bene se vivi dentro Postman e le tue risposte sono già salvate come voci di history Postman. Questo strumento è agnostico rispetto al provider. Puoi incollare da Postman, Insomnia, curl, httpie, un log CI, uno snippet di Stack Overflow, o il messaggio Slack di un collega. Niente account, niente workspace, niente sync. Per confronti una tantum fra strumenti, è più veloce. Per test API condivisi nel team dentro una singola piattaforma, la funzione di Postman va bene.
Come gestisco i campi volatili come timestamp e request ID?
La mossa pragmatica è normalizzare prima del diff. Apri entrambi gli incollati nei pannelli, poi edita direttamente i campi volatili: sostituisci i timestamp con una stringa costante, togli i valori di request_id e trace_id, rimuovi i cursori di paginazione che cambiano a ogni chiamata. Il diff evidenzia solo le differenze rimanenti, che sono quelle che contano davvero. Per confronti ripetuti dello stesso endpoint, puoi anche far passare la risposta in jq con un filtro di delete (jq 'del(.meta.request_id)') prima di incollare.
In cosa si differenzia da un diff di schema OpenAPI?
Il diff di schema confronta i contratti: ti dice che POST /orders ha aggiunto un campo opzionale discount_code, o che l'enum status ha guadagnato un nuovo valore. Strumenti consapevoli di OpenAPI come oasdiff o Spectral lo fanno bene. Questo strumento confronta i body di risposta reali. I due sono complementari. Il diff di schema cattura i cambi di contratto; il diff di risposta cattura il drift fra contratto e realtà, ed è lì che si nascondono i bug di serializzazione, le incongruenze di ambiente e le fixture vecchie.
Gestisce risposte grandi?
In pratica sì, fino a qualche migliaio di righe di JSON formattato per lato. Oltre, il diff a livello di carattere con cleanup semantico rallenta perché gira nel tuo browser, non su un server. Per payload molto grandi (pensa a un dump paginato di 10.000 record), l'approccio giusto è tagliare la risposta in pezzi più piccoli per record o per chiave di primo livello e fare il diff di ogni pezzo separatamente. Oppure eseguire un diff strutturale da riga di comando con jd o diff <(jq . a.json) <(jq . b.json) per pura velocità.
Funziona per risposte XML o SOAP?
Direttamente no. Questa pagina è tarata per JSON, che è ciò che usano la maggior parte dei payload moderni REST e webhook. Se devi fare il diff di XML, envelope SOAP, RSS, o configurazioni in stile POM, il nostro strumento compare-xml è la porta giusta; gestisce indentazione e formattazione di namespace correttamente. Per body di risposta grezzi che mescolano header e body, o per API in testo puro (alcuni sistemi legacy ancora restituiscono text/plain), compare-text fa il lavoro senza tentare di imporre una struttura.
Preserva l'ordine delle chiavi o le ordina?
Preserva l'ordine delle chiavi che incolli. Gli oggetti JSON sono formalmente non ordinati secondo RFC 8259, quindi due risposte semanticamente identiche con chiavi in ordine diverso appariranno come diff in questo strumento. Se vuoi ignorare l'ordine, normalizza prima entrambi i lati passando per jq --sort-keys o equivalente. La maggior parte dei client non dipende dall'ordine delle chiavi, quindi la normalizzazione a chiavi ordinate è un default sicuro per il confronto di risposte; tieni presente che alcuni consumer legacy (vecchi bridge XML-a-JSON, certi flussi di firma digitale) all'ordine ci tengono.
Privacy e perché conta per le risposte API
I payload di risposta API contengono regolarmente cose che non vuoi far trapelare. Indirizzi email di clienti. ID utente interni. Token di sessione. Token Auth bearer finiti in un campo del body per errore. ID cliente Stripe. Segreti webhook. Campi PII come nomi, indirizzi e numeri di telefono. Incollarne uno in un servizio di diff ospitato in cloud è di per sé un evento di trattamento dati, e a seconda del settore può violare i tuoi controlli SOC 2, gli accordi di trattamento dati GDPR, o i Business Associate Agreement HIPAA. Questo strumento gira interamente nel tuo browser. Nulla viene caricato, loggato o inviato a servizi terzi. Il diff, l'evidenziazione e il rendering vengono eseguiti tutti sulla tua macchina. Verificarlo è diretto: apri le DevTools del browser, vai sulla scheda Network, incolla entrambe le risposte, e osserva. Non ci sono richieste in uscita quando confronti. Per linee guida più ampie su design e sicurezza delle API, le best practice di API design di Microsoft sono un riferimento solido.