🔍 JSON Diff (構造比較)
2 つの JSON を構造的に比較し、追加・削除・変更を JSON Pointer (/path/to/field) 付きで表示します。キー順序や配列順序の無視、型変化の検出にも対応。
🔒 プライバシーについて
- ・すべての処理はあなたのブラウザ内で完結します
- ・入力データは一切サーバーに送信されません
差分結果
🔗 関連ツール
📖 つまずきやすいポイント
2 つの JSON を構造として比較し、追加・削除・変更を JSON Pointer 付きで表示します。処理はブラウザ内で完結します。テキスト diff とは見ているものが違い、インデントや改行の違いは差分になりません。逆に、テキストとしては 1 文字も違わないのに構造としては差が出る、あるいはその反対も起こります — この境目を理解しておかないと、結果を読み違えます。
| ケース | 何が起きるか | どうする |
|---|---|---|
| 配列の先頭に 1 件足しただけで全要素が「変更」になる | 配列はインデックスの位置どうしで突き合わせます。先頭に 1 件挿入すると、以降の要素がすべて 1 つずつずれるため、「/0 が変更、/1 が変更、… 末尾に 1 件追加」という読みづらい差分になります。テキスト diff が「挿入された 1 行」と表示できるのは最長共通部分列 (LCS) を計算しているからで、構造比較はそれをしません。要素が数十件あると差分が全面赤になり、実質的に読めなくなります。 | 「配列順序: 無視」に切り替えてください — 集合として比較するので、並び替えただけのものは「変更なし」になります。ただしこれは順序に意味がある配列 (手順・優先度・ランキング) には使えません。実務でいちばん効くのは、比較の前に id でソートを揃えておくことです — API のレスポンスは順序が保証されないことが多く、順序のゆらぎを差分として見せられても判断材料になりません。差分の読み方の目安として、変更が全件に及んだら「本当に全部変わった」ではなく「対応付けに失敗している」を先に疑ってください。 |
| 見た目は同じ数値なのに「変更」と出る / 違うのに出ない | JSON には整数と浮動小数点数の区別がありません。1 と 1.0 はパース後に同じ値になるので差分は出ませんが、文字列の "1" と数値の 1 は「型変化: 厳密」では別物です。API のレスポンスで数値が文字列になったり戻ったりするゆらぎは珍しくありません (大きな整数を安全に運ぶために文字列にする設計は一般的です)。もっと危険なのは逆のケースです — JavaScript の Number は 2 の 53 乗を超える整数を正確に表せないため、9007199254740993 と 9007199254740992 はパースした時点で同じ値になり、差分がまったく出ません。 |
型のゆらぎだけを許したいなら「型変化: 緩い」に切り替えてください。ただし大きな整数の問題は、このツールに限らず JavaScript を通す全ての比較で起きます — 対象が Snowflake ID・スナップショットのバージョン番号・金額を最小単位の整数で持つデータなどであれば、比較の前にその項目を文字列として扱う (パーサーに reviver を渡す、あるいは比較対象から外して別に検査する) 必要があります。判別は簡単で、値が 16 桁を超えていたら疑ってください — 2 の 53 乗は 9,007,199,254,740,992 で 16 桁です。 |
| null とキーが無いことの区別に振り回される | {"a": null} と {} は構造として別物なので、差分が出ます。これは正しい挙動ですが、実際のシステムでは両者を区別していないことが多く、意味の無い差分が大量に出ます。原因は言語の側にあります — JavaScript の JSON.stringify は値が undefined のキーを出力から落としますが、Python の json.dumps は None を null として出力します。同じ「値が無い」を表すのに、片方はキーごと消え、もう片方は null が残ります。言語をまたぐ API の比較では、ほぼ確実にここで差分が膨らみます。 |
比較の前に、どちらか一方に正規化してください — 実務では「値が null のキーを両側から取り除く」のが扱いやすいです (欠落と null を同一視することになるので、その前提が成り立つデータでのみ)。ただし、この 2 つを意図的に区別する API では絶対に正規化しないでください — PATCH の意味論では {"a": null} が「a を消せ」、キーが無いのが「a には触れるな」を表します (JSON Merge Patch, RFC 7386)。ここを潰すと、差分から生成した更新リクエストが意図しないフィールドを削除します。正規化してよいかどうかは、常に相手の API の仕様で決まります。 |
JSON Pointer (RFC 6901) にはエスケープ規則があります — キーに含まれる ~ は ~0、/ は ~1 と書きます。URL やファイルパスをキーにした辞書では必ずこれに当たります — {"https://example.com/a": 1} のキーを指す Pointer は /https:~1~1example.com~1a です。表示された Pointer をそのままコードに貼ると、エスケープを戻し忘れて別のパスを指してしまうので注意してください。順序に関するもう 1 点: JSON のオブジェクトのキー順序は仕様上は意味を持ちませんが、多くのパーサーは挿入順を保持します。したがってキー順序の差分は「意味は同じだが生成側が変わった」という情報になり、ライブラリの更新やシリアライザの差し替えを検出する手がかりになります — ノイズとして無視する前に、なぜ変わったのかを一度確認する価値があります。
📖 使い方
-
1
2 つの JSON を貼り付け左に旧バージョン、右に新バージョンの JSON を貼り付けます。サンプルボタンですぐ試せます。
-
2
オプションを調整表示モード(ツリー / フラット / unified)、キー順序や配列順序の無視、型変化の厳密性を選択します。
-
3
差分を確認追加 (+)・削除 (-)・変更 (~) が JSON Pointer 付きで色分け表示されます。サマリで件数を一目で確認できます。
❓ よくある質問
JSON Pointer とは何ですか?
配列の順序を無視すると何が変わりますか?
文字列の "1" と数値の 1 はどう扱われますか?
🐛 このツールで問題が発生しましたか?
完全無料・登録不要。再現手順だけでも結構です。届いたご報告は運営者に直接届き、修正の参考にします。
ご報告ありがとうございます!
運営者に届きました。改善の参考にさせていただきます。