JSONの値の変更を検出する

2つのJSONドキュメント間での値の変更を特定する方法を学びます。diffアルゴリズムがプリミティブ、オブジェクト、配列の変更をどのように検出・表示するかを解説します。

Field Changes

詳細な説明

値の変更(または変更)は、同じキーが両方のJSONドキュメントに存在するが、異なる値を保持している場合に発生します。これはdiff操作の中で最も一般的な種類であり、文字列、数値、ブール値、null、さらには構造的な置換まで含みます。

値の変更検出の仕組み:

アルゴリズムは両方のドキュメントを同時に走査します。キーが両方に存在する場合、値が比較されます:

  • プリミティブ(文字列、数値、ブール値、null)は厳密等価で比較されます。異なる場合、古い値と新しい値の両方を示す「置換」操作が記録されます。
  • オブジェクトはネストされた構造に降りて再帰的に比較されます。
  • 配列は特別な処理が必要です(array-differencesの例を参照)。
// 変更前
{
  "version": "1.2.0",
  "maxRetries": 3,
  "debug": false,
  "endpoint": "https://api.example.com/v1"
}

// 変更後
{
  "version": "1.3.0",
  "maxRetries": 5,
  "debug": true,
  "endpoint": "https://api.example.com/v2"
}

このdiffは4つの値の変更を報告します。アルゴリズムは古い値と新しい値の両方を保持するため、何が変わったかを正確にレビューできます。

RFC 6902での表現:

JSON Patchは値の変更に "op": "replace" を使用し、ターゲット "path" と新しい "value" を含みます。古い値はパッチに含まれません(既知のオリジナルにパッチを適用することが前提です)。

値の変更の種類:

  1. 同一型の変更: "1.2.0" -> "1.3.0"(文字列から文字列)。最も一般的でレビューしやすいです。
  2. 型変更を伴う変更: false -> "no"(ブール値から文字列)。バグまたは意図的なスキーマ移行の可能性があります。
  3. 構造的な変更: "Portland" -> { "city": "Portland", "state": "OR" }(スカラーからオブジェクト)。大規模なリファクタリングです。

値のdiffレビューのベストプラクティス:

  • パスの深さでソートし、トップレベルの変更を最初に確認します。
  • 大規模なdiffをレビューする際は、型でフィルタリング(例:数値の変更のみ表示)します。
  • 型変更を伴う変更には特に注意してください。意図しないデータ破損を示す可能性があります。

ユースケース

本番環境とステージング環境の設定ファイルを比較し、意図した値(APIエンドポイントやフィーチャーフラグなど)のみが2つの環境間で異なることを確認する。

試してみる — JSON Diff

フルツールを開く