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により正しい動作を検証する。

試してみる — JSON Diff

フルツールを開く