JSON Diffにおけるnullと欠落フィールドの違い
nullに設定されたJSONフィールドと完全に欠落しているフィールドの違いを理解します。diffツールがこの2つの状態をどのように区別するか、およびその影響について学びます。
Type & Value Edge Cases
詳細な説明
JSONでは、null値で存在するフィールドと完全に欠落しているフィールドには重要な区別があります。一見似ているように見えますが、異なる意味を持ち、JSON diffツールはそれらを根本的に異なる操作として扱います。
2つの状態:
// null値で存在するフィールド
{ "name": "Alice", "phone": null }
// 完全に欠落しているフィールド
{ "name": "Alice" }
これらは同じではありません。最初のドキュメントでは phone キーが明示的なnull値で存在し、「このフィールドは既知だが値がない」ことを示します。2番目のドキュメントでは phone キーは全く存在せず、「このフィールドは不明」または「このフィールドは適用されない」ことを意味する可能性があります。
diffツールの処理方法:
- nullから欠落: 削除として報告されます(キーが削除された)。
- 欠落からnull: 追加として報告されます(null値の新しいキーが追加された)。
- 値からnull: 値の変更として報告されます(値がnullに変更された)。
- nullから値: 値の変更として報告されます(nullが新しい値に置換された)。
// 変更前
{
"name": "Alice",
"phone": null,
"email": "alice@example.com"
}
// 変更後
{
"name": "Alice",
"email": "alice@example.com",
"address": null
}
diffの報告:
phone:削除(nullだったが、現在は欠落)address:null値で追加
現実世界での影響:
- PATCHセマンティクスのAPI: 多くのREST APIはPATCHリクエストで
"phone": nullを送信すると「phoneをnullに設定(クリア)する」ことを意味し、フィールドを省略すると「phoneを変更しない」ことを意味します。この2つの解釈を混同すると、データ損失のバグにつながります。 - データベースマッピング: SQLデータベースでは、NULLのカラム値とカラムが存在しないことは異なります。データベース行にマッピングするJSONドキュメントはこの区別を保持する必要があります。
- JSON Merge Patch(RFC 7396): この標準は削除を示すために明示的に
nullを使用します。{ "phone": null }を送信すると、ターゲットドキュメントからphoneフィールドが削除されます。
ベストプラクティス:
- null値と欠落キーを明示的に区別するdiffツールを使用してください。
- スキーマでnull vs 欠落フィールドのAPIの規約を文書化してください。
- JSON Schemaでは、値がnullであることとは独立して、
"required"を使用してフィールドの存在を強制してください。
ユースケース
フィールドをnullに設定するとクリアされ、フィールドを省略すると変更されないREST API PATCHエンドポイントのデバッグで、diffにより正しい動作を検証する。