Svar A
Svar B

API-respons-diff: jämför JSON-API-payloads online

Klistra in den respons du förväntade dig till vänster, den respons du faktiskt fick till höger, och se varje fält som ändrats. Byggd för backend, QA och integrationsarbete. Inget lämnar din webbläsare.

Vad detta API-respons-diff-verktyg är

Ett gratis, in-browser-verktyg för att jämföra två HTTP-API-responsbody. Klistra in JSON från staging till vänster, JSON från produktion till höger, och skillnaderna markeras tecken för tecken. Texten lämnar aldrig din maskin, vilket spelar roll eftersom riktiga API-responser regelbundet innehåller kunders e-postadresser, sessions-tokens, interna användar-ID och annat du inte vill ladda upp till en tredjeparts diff-sajt.

Det är byggt för stunden då ett flackigt integrationstest faller i CI och du har en Postman-skärmdump av en fungerande respons på laptopen och en CI-logg med en trasig respons från build-runnern. Att starta upp ett fullt Pact-contract test för en engångsutredning är overkill. Två textrutor, en diff, och du kan oftast snäva in problemet till ett enda fält på under en minut.

Under ytan är diff-motorn samma som driver vårt compare-json-verktyg. Vi har bara ramat in det för API-test-flödet. Om dina responser är XML eller SOAP-envelopes hanterar vår compare-xml-sida det. Om du jämför fri text som en webhook-logg eller en audit trail är vårt compare-text-verktyg rätt yta.

Hur en API-respons-diff faktiskt hjälper

En API-respons-diff sitter i glappet mellan två relaterade men distinkta testidéer. Schema-diff för OpenAPI 3.1 säger vad ditt kontrakt säger har ändrats: ett nytt valfritt fält, en omdöpt property, ett striktare enum. Snapshot-test (Jest-snapshots, Vitest-snapshots, pytest-snapshot) säger vad din kod producerade mot en sparad fixture. Det här verktyget sitter på runtime-sidan. Du ger det två riktiga responsbody, och det visar varje byte som skiljer sig, oavsett om schemat tillåter ändringen eller om din snapshot-fixture är aktuell.

Varför är det användbart? Eftersom de buggar som biter hårdast i REST-integrationsarbete inte är schema-överträdelser. Det är subtila drifter: en serializer som tyst växlade ett datum från ISO-8601 till en Unix-timestamp efter en Jackson-uppgradering, ett Marshmallow-schema som började skicka null i stället för att utelämna ett saknat fält, en DRF ViewSet som efter en middleware-ändring började svepa payloaden i en data-envelope. OpenAPI-specen ändrades inte. Snapshotten uppdaterades inte. Testerna gick i isolering. Integrationen gick sönder. En diff på responsbody fångar alla dessa fall, för den bryr sig inte om kontraktet; den bryr sig om bytena.

Volatila fält är det viktigaste att hålla koll på. Timestamps, request-ID, trace-ID, server-genererade UUID och paginerings-cursors kommer att skilja sig mellan två capture av samma endpoint, även när inget meningsfullt har ändrats. Det rätta draget är att normalisera före diff: byt timestamps mot en placeholder, ta bort trace-ID, sortera arrayer där ordningen inte är kontraktuellt viktig. Verktyg som Pact löser det med matchers; i det här verktyget löser du det genom att redigera rutorna. Det tar tio sekunder och tar bort grundbruset.

Så diffar du en API-respons i tre steg

Två textrutor, en diff. Ingen inloggning, ingen uppladdning, ingen proxy att koppla.

  1. 1

    Fånga första responsen

    Träffa endpointen med curl, httpie, Postman, Insomnia eller vad ditt team använder. curl -s https://api.example.com/v1/users/123 | jq är en bra grund eftersom jq formaterar JSON, vilket gör diffen mycket lättare att läsa. Kopiera body (bara JSON, inga headers) och klistra in i vänstra rutan. Om du drar från en CI-logg, ta bort timestamp-prefixet som de flesta loggers lägger till så att diffen landar på själva payloaden.

  2. 2

    Fånga andra responsen

    Träffa jämförelsekällan: andra miljön, andra API-versionen, andra leverantören. Samma form av capture, samma pretty-print-steg. Klistra in i högra rutan. Om en capture är från en inspelad fixture (vcrpy, pollyjs, MSW, nock) och den andra är live, normalisera först de uppenbara volatila fälten: skrubba request_id, byt timestamps mot en konstant och ta bort trace-headers som läckt in i body. Den kvarvarande diffen är den verkliga signalen.

  3. 3

    Läs de markerade skillnaderna

    Borttagningar visas som rött genomstrykt till vänster; tillägg som grönt till höger. Förändringsräknarna i varje header säger hur många separata ändringar diffen hittade. Fokusera först på tre saker: ändringar i status-strängar, saknade eller tillagda nycklar och ändringar av värdetyp (string till number, object till null). De tre kategorierna täcker nästan varje verklig API-regression. Format- och ordningsändringar är oftast brus om inte din consumer är beroende av dem.

När en API-respons-diff är rätt val

Reproducera ett flackigt integrationstest

Ett test går igenom lokalt och faller i CI. Du har responsen som din lokala Postman-körning fångade och responsen som CI-build-agenten fångade (de flesta CI-system kan dumpa request/response med en verbose-flagga). Klistra in båda i diff-verktyget. Nio gånger av tio är skillnaden miljörelaterad: en annan feature flag, en gammal fixture, en tidszons-offset på runnern. Den tionde är en riktig bugg, och du har just lokaliserat den till ett specifikt fält.

Validera en fixture mot en färsk respons

Ditt repo har en incheckad fixture-fil som mockar ett tredjeparts-API för testerna. Upstream-leverantören släppte just en ny minor-version. Träffa live-endpointen med curl, klistra in den responsen bredvid din fixture, och du ser exakt vilka fält som drivit. Det här är den manuella varianten av det VCR-liknande replay-verktyg automatiserar. Användbart när du vill uppdatera en enda fixture utan att spela in om hela testsuiten.

Verifiera bakåtkompatibilitet mellan API-versioner

Du är på väg att släppa v2 av ett internt API. En v1-klient finns kvar i produktion. Träffa både /v1/orders/42 och /v2/orders/42 och diffa responserna. Varje borttaget fält, varje omdöpt nyckel, varje ändring av värdetyp är en breaking change för v1-klienten. Varje nytt fält är additivt och säkert. Det är en fattigmansversion av ett consumer-driven contract test; det skalar inte till dussintals endpoints, men för en snabb sanity check på en eller två fungerar det.

Hitta en serializer-regression

Ditt team uppgraderade Jackson, Marshmallow, DRF eller ett liknande serialiseringslager. Testerna går igenom. Sedan rapporterar en downstream-consumer att deras parser sätter i halsen. Fånga samma endpoint-respons på gamla branchen och nya branchen och diffa dem. Vanliga fynd: ett datumformat slog över från 2026-05-09T10:00:00Z till en Unix-timestamp, decimaler tappade efterställda nollor, ett enum började serialiseras som integer i stället för string, eller null-fält började dyka upp i payloaden som tidigare utelämnades.

Jämför webhook-payloads från två leverantörer eller versioner

Stripe-webhook V1 och V2 av samma event-typ ser nästan identiska ut och är det inte alls. Detsamma gäller GitHubs webhook-event-payloads mellan API-versioner och Slacks event-subscriptions mellan scopes. Klistra in en exempel-payload från vardera i diff-verktyget för att se omdöpta fält, flyttade nästlade objekt och nya metadata-block. Det är snabbare än att läsa båda leverantörernas dokumentationssidor sida vid sida, särskilt när dokumentationen glider över vilka fält som faktiskt dyker upp i praktiken.

Felsök klassikern "fungerar på staging, trasigt på prod"

Den klassiska deploy-huvudvärken. Samma klient-request returnerar subtilt olika JSON från staging och produktion. Fånga båda, klistra in båda, och skillnaden är oftast en config-flagga, en saknad feature gate eller en gammal cachad respons. Det gäller lika mycket för debugging över regioner (us-east-1 mot eu-west-1 som ger olika data), CDN-cache-problem (Cloudflare cachade en gammal body) och read-replica-fördröjning där en skrivning inte propagerats överallt.

Edge-fall för API-respons-diff värda att känna till

Fallen där en respons-body-diff inte håller med om vad ditt testramverk, ditt OpenAPI-verktyg eller dina ögon skulle säga. Värt att skumma innan du antar att diffen hittat en riktig bugg.

TopicWhat this tool does
Volatila fält (timestamps, ID)created_at, updated_at, request_id, trace_id, server-genererade UUID och paginerings-cursors kommer alltid att skilja sig mellan två captures. Normalisera dem med jq 'del(...)', byt mot en konstant eller bara redigera bort dem före diff. Signalen du faktiskt bryr dig om bor någon annanstans.
null vs saknad nyckel{"foo": null} och {} är olika i JSON, och många serializers (Marshmallow, Jackson, System.Text.Json) har inställningar som växlar mellan dem. Diffen ytar det. Vissa klienter behandlar dem som likvärdiga, andra inte; rätt svar är vad din consumer gör, och det är därför detta är en vanlig regressionskälla efter en serializer-uppgradering.
NyckelordningRFC 8259 definierar JSON-objekt som oordnade. Två semantiskt identiska responser med olika nyckelordning visas här som diff eftersom textjämförelse är ordningskänslig. Sortera båda sidorna i förväg med jq --sort-keys om du vill ha ordnings-okänslig diff. Se upp för den ovanliga consumer som faktiskt beror på ordning (vissa signeringsflöden, vissa legacy-parsers).
Array-ordningArrayer i JSON är ordnade, men många API:er returnerar arrayer vars ordning faktiskt inte är kontraktuell: en lista över permissions, en lista över feature flags, en lista över webhook-subscriptions. En diff flaggar en omsorterad array som ändring även när ingen consumer bryr sig. Om omsortering är harmlös i din domän, sortera båda sidor på en stabil nyckel före diff.
JSON.parse-stränghetDiffen behandlar din input som ogenomskinlig text. Har en av dina captures ett efterföljande kommatecken, en ociterad nyckel eller en kommentar (alla otillåtna i strikt JSON), kommer den ändå att diffa men se brusigare ut än den behöver. Kör båda captures genom jq . först för att omformatera och avvisa ogiltig input. jq använder en strikt RFC 8259-parser.
Respons-omslutning (data-envelope vs platt)Många API:er sveper payloads i en {"data": ...}-envelope, ibland med meta, links eller included bredvid (JSON:API och liknande). En migration från platt till sveped (eller vice versa) är en breaking change som syns direkt i en diff men är lätt att missa i en schema-genomgång eftersom den underliggande posten ser likadan ut.
Ändringar av paginerings-cursorCursor-baserad paginering använder ogenomskinliga tokens (next_cursor, after, page_token) som är gjorda för att ändras vid varje anrop. De visas alltid som diff. Ta bort dem före jämförelsen, eller jämför bara innehållet i data-arrayen och ignorera pagineringsblocket helt.
Format för felresponserFelbody är vilda västern. Vissa API:er returnerar ett platt {"error": "..."}, vissa returnerar RFC 7807 Problem Details med type, title, status, detail, instance, och vissa returnerar en leverantörsspecifik form. En migration till RFC 7807 från en egen form ger en stor diff som mest är en förbättring; en migration åt andra hållet är en regression värd att fånga tidigt.

API-respons-diff: vanliga frågor

Hur skiljer sig detta från Postmans inbyggda diff-funktion?

Postman har en respons-jämförelsevy i sin Collection Runner och en Visualize-funktion för enskilda responser. Båda är bra om du lever i Postman och dina responser redan är sparade som Postman-historikobjekt. Det här verktyget är leverantörsoberoende. Du kan klistra in från Postman, Insomnia, curl, httpie, en CI-logg, ett Stack Overflow-snippet eller en kollegas Slack-meddelande. Inget konto, ingen workspace, ingen sync. För engångsjämförelser mellan verktyg är det snabbare. För team-delade API-tester inom en enda plattform fungerar Postmans egna funktion bra.

Hur hanterar jag volatila fält som timestamps och request-ID?

Det pragmatiska draget är att normalisera före diff. Öppna båda inklistringarna i rutorna och redigera bort de volatila fälten direkt: byt timestamps mot en konstant sträng, ta bort värdena för request_id och trace_id, radera paginerings-cursors som ändras vid varje anrop. Diffen markerar bara de skillnader som finns kvar, och de är de som faktiskt spelar roll. För upprepade jämförelser av samma endpoint kan du också köra responsen genom jq med ett delete-filter (jq 'del(.meta.request_id)') innan du klistrar in.

Hur skiljer sig detta från en OpenAPI-schema-diff?

Schema-diff jämför kontrakt: den säger att POST /orders lade till ett valfritt fält discount_code, eller att enumet status fick ett nytt värde. OpenAPI-medvetna verktyg som oasdiff eller Spectral gör det bra. Det här verktyget jämför verkliga responsbody. De två kompletterar varandra. Schema-diff fångar kontraktändringar; respons-diff fångar driften mellan kontrakt och verklighet, vilket är där serialiseringsbuggar, miljöskillnader och gamla fixtures gömmer sig.

Klarar det stora responser?

I praktiken ja, upp till några tusen rader formaterad JSON per sida. Bortom det blir tecken-diffen med semantisk uppstädning långsam, eftersom den körs i din webbläsare, inte på en server. För mycket stora payloads (tänk en paginerad dump på 10 000 poster) är rätt sätt att skiva responsen i mindre bitar per post eller per top-level-nyckel och diffa varje bit separat. Eller köra en strukturell diff från kommandoraden med jd eller diff <(jq . a.json) <(jq . b.json) för ren hastighet.

Funkar det för XML- eller SOAP-responser?

Inte direkt. Den här sidan är trimmad för JSON, vilket är vad de flesta moderna REST- och webhook-payloads använder. Om du behöver diffa XML, SOAP-envelopes, RSS eller POM-liknande konfiguration är vårt compare-xml-verktyg rätt yta; det hanterar indrag och namespace-formatering korrekt. För råa responsbody som blandar headers och body, eller för plain-text-API:er (vissa legacy-system returnerar fortfarande text/plain) gör compare-text jobbet utan att försöka tvinga på en struktur.

Bevarar det nyckelordningen eller sorterar det nycklarna?

Det bevarar den nyckelordning du klistrar in. JSON-objekt är formellt oordnade enligt RFC 8259, så två semantiskt identiska responser med nycklar i olika ordning visas som diff i det här verktyget. Vill du ignorera ordning, normalisera båda sidorna först genom jq --sort-keys eller motsvarande. De flesta klienter beror inte på nyckelordning, så normalisering med sorterade nycklar är ett säkert default för respons-jämförelse; men vissa legacy-consumers (gamla XML-till-JSON-bryggor, vissa flöden för digital signering) bryr sig om ordning.

Integritet och varför det spelar roll för API-responser

API-respons-payloads innehåller regelbundet sådant du inte vill läcka. Kunders e-postadresser. Interna användar-ID. Sessions-tokens. Auth-bearer-tokens som av misstag hamnat i ett body-fält. Stripe-kund-ID. Webhook-secrets. PII-fält som namn, adresser och telefonnummer. Att klistra in en sådan i en molnhostad diff-tjänst är i sig en databehandlingshändelse, och beroende på bransch kan det bryta mot dina SOC 2-kontroller, GDPR-databehandlingsavtal eller HIPAA Business Associate Agreements. Det här verktyget körs helt i din webbläsare. Inget laddas upp, loggas eller skickas till någon tredjepartstjänst. Diff, markering och rendering körs alla på din maskin. Att verifiera påståendet är enkelt: öppna webbläsarens DevTools, byt till Network-fliken, klistra in båda responserna och titta. Det finns inga utgående requests när du jämför. För bredare riktlinjer för API-design och säkerhet är Microsofts API design best practices en stabil referens.