2つのJSONドキュメントを(コード用の)普通のテキストdiffで比較すると、結果はしばしば誤解を招きます。同じデータでもキーの順序、インデント、空白の数が異なる書き方ができ、テキストdiffは実際には同一のデータに対して「違い」を表示してしまいます。
構造的な比較
構造的なJSON Diffは両方のドキュメントを値のツリーとしてパースし、実際のデータそのものを比較します。フィールドが存在するか、どんな値を持つか、型が一致するかどうかです。オブジェクトのキーの順序、余分な空白、インデントのスタイルは考慮されません — これらはデータそのものの一部ではないからです。
diffが示すもの
典型的な構造的比較の結果は、3種類の変更を強調表示します。2番目のドキュメントで追加されたフィールド、1番目のドキュメントから削除されたフィールド、両方に存在するが値が異なるフィールドです。配列の場合はより複雑で、要素を位置で比較するか、似たオブジェクトをマッチさせようとするかを決める必要があります。
なぜ必要なのか
- バックエンドの変更の前後でAPIレスポンスを比較し、データの実際の変化を確認する。
- 設定ファイルへの変更が意図しない箇所に影響していないことを確認する。
- 期待されるJSONと実際のJSONが異なるテストでの回帰を見つける。
元号が変わった日、日付設定JSONに何が起きたか
2019年5月に平成から令和に変わったとき、和暦(元号)で日付を扱う日本の業務システムでは、設定ファイルやマスタデータのJSON内にある元号コードや変換テーブルを一斉に更新する必要がありました。この種の移行では、更新前後の設定JSONを構造的diffで比較することが、意図した箇所(新元号のエントリ追加)以外に何も壊れていないかを確認する実務上の手段になります。テキストdiffでは行の並び替えやインデントの違いに埋もれてしまう本質的な変更点を、構造的diffは値のレベルで正確に拾い出せます。
配列の比較: 位置ベースかキーベースか
もっとも単純な方法は、配列の要素をインデックスごとに比較することですが、配列の途中に新しい要素が挿入されると、それ以降のすべての位置が「ずれて」しまい、実際には1つしか変わっていないのに、挿入位置以降のすべての要素で差分が表示されてしまいます。より賢いツールは、要素を一意なフィールド(例えば id)で対応付けようとし、無関係な変更の連鎖ではなく、本当の挿入や削除だけを示そうとします。