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.2.0" -> "1.3.0"(文字列から文字列)。最も一般的でレビューしやすいです。 - 型変更を伴う変更:
false -> "no"(ブール値から文字列)。バグまたは意図的なスキーマ移行の可能性があります。 - 構造的な変更:
"Portland" -> { "city": "Portland", "state": "OR" }(スカラーからオブジェクト)。大規模なリファクタリングです。
値のdiffレビューのベストプラクティス:
- パスの深さでソートし、トップレベルの変更を最初に確認します。
- 大規模なdiffをレビューする際は、型でフィルタリング(例:数値の変更のみ表示)します。
- 型変更を伴う変更には特に注意してください。意図しないデータ破損を示す可能性があります。
ユースケース
本番環境とステージング環境の設定ファイルを比較し、意図した値(APIエンドポイントやフィーチャーフラグなど)のみが2つの環境間で異なることを確認する。