- JSON Patchは、RFC 6902で定義された標準形式で、JSONドキュメントを修正する方法。
- HTTPを通じてリソースを部分的に更新する、シンプルで効率的な方法を提供。
- 従来の
PUTおよびPOSTメソッドではデータ全体を送信する必要があったが、PATCHメソッドでは部分更新を許可。
- JSON Patchは、JSONドキュメントに対する明確で簡潔な変更表現を提供し、帯域幅を削減してWebアプリケーションのパフォーマンスを向上させる。
JSON Patchの動作原理
- JSON Patchは、JSONドキュメントに対する一連の原子的な操作として動作する。
- 各操作には
opフィールドとpathフィールドが含まれ、ドキュメントの特定の位置で処理を実行する。
- たとえば、
add操作は新しいフィールドを追加し、replace操作は既存のフィールドを置き換える。
JSON Pointer
- JSON Patchは、JSON Pointerを使用してドキュメントの特定部分を識別する。
- JSON Pointerはスラッシュ(
/)で区切られたトークン文字列で、ドキュメントの階層構造を識別する。
- たとえば、
/user/nameはuserオブジェクト内のnameフィールドを識別する。
JSON Patchの長所と短所
長所
- 精密性: 複雑な構造の中で特定の要素を正確に修正できる。
- 効率性: 変更点だけを送信することで、データ転送量と遅延を最小化する。
- 原子性: 操作が失敗した場合、処理全体をロールバックできる。
- 冪等性: 安全にリトライできる。
- 複雑な操作: 要素を移動したりコピーしたりできる。
- 検証: APIは受信したパッチを検証し、不正なリクエストを減らせる。
- 標準ベース: さまざまなクライアントやサーバーと容易に統合できる。
- フィールドレベルのアクセス制御: 細かな粒度で変更制限を設定できる。
- バッチ操作: 複数の変更を1つのリクエストで処理できる。
短所
- 複雑性: 複雑なJSON構造を扱うのが難しい。
- 保守コスト: APIが進化するにつれてパスが無効になる可能性がある。
- デバッグの難しさ: 複数の操作がまとめてバッチ化されると追跡が難しい。
- オブジェクト順序の保持:
move操作ではオブジェクトの順序が保証されない。
- セキュリティ上の問題: 不正なリクエスト処理時に脆弱性が発生する可能性がある。
JSON Patch操作の例
- Add: 新しいフィールドを追加する。
- Remove: 既存のフィールドを削除する。
- Replace: 既存のフィールドを新しい値に置き換える。
- Move: 要素を別の場所へ移動する。
- Copy: 要素を別の場所へコピーする。
- Test: 特定のパスに値が設定されているかどうかをテストする。
ツールとライブラリにおけるJSON Patch
- さまざまなプログラミング言語でJSON Patchをサポートするライブラリが存在する: fast-json-patch、python-json-patch、.NETのJsonPatchライブラリ など。
- JSON Patchを学ぶための優れたツールとして、JSON Patchコマンドを実行する無料のオンラインサービスであるjsonpatch.meがある。APIも提供されている。
GN⁺のまとめ
- JSON Patchは、JSONドキュメントの部分更新を効率的に実行できる強力なツール。
- 複雑なJSON構造を扱うのは難しい場合もあるが、さまざまなライブラリやツールによってそれを克服できる。
- JSON Patchはデータ転送量を減らし、Webアプリケーションのパフォーマンス向上に役立つ。
- JSON Merge Patchのような代替案も検討でき、API開発におけるJSON Patchの利用は効率向上につながる。
1件のコメント
Hacker Newsのコメント
JSON Patch はあらゆる JSON ドキュメントを変更できるよう設計されているため、複雑に感じられる。データセットを少し制限すれば、ドキュメントをもっと簡単にパッチできる。たとえば Firebase では null 値を保存できず、null に設定することは削除を意味する。このような単純な制約によって PATCH を簡単に実装できる。「null は削除を意味する」という点以外に新しく学ぶ必要がないのは、API の優れた特徴だ。
JSON の区切り文字として
/を使うのは奇妙な選択だ。JSON は JS のサブセットなので、区切り文字には.を期待していた。/を見るとバックエンドの人たちが書いた仕様のように感じられ、パスを URL にして相対パス/絶対パスの曖昧さを解消しようとしているように思える。パスは文字列ではなく配列であるべきだと思う。そうでなければ、キー内の
/をエスケープしなければならず、さらにパス文字列を構文解析しなければならない。これでは任意の JSON ドキュメントを扱えなくなる。JSON Patch を一度使ったことがあり、予期しない問題をすばやく解決するためのハックとして使った。海外の契約者がテキストデータに単語単位で注釈を付けられるような Web インターフェースを構築した。データは小さなチャンクごとに注釈される想定だったが、文書全体に割り当てられてしまい、注釈が保存されない問題が起きた。JSON Patch を見つけて、アップロードコードをパッチのみ使うように修正した。
JSON Patch のパス指定方式には、配列の項目をインデックスではなく識別用のキーと値の組で選択できる標準構文が必要だ。これは特に、項目を追加したり、以前のバージョンの JSON 項目との差分を分析したりするときに重要だ。
JSON Patch の強みの一つは冪等性だ。JSON Patch の操作は、意図しない副作用なしに安全に再試行できる。しかし、配列に項目を追加できないという点には驚いた。
MongoDB の更新クエリと似たように動く。ローカルファイル上で、MongoDB 全体を実行せずにこの更新言語を使えるのか気になる。
JSONDiffpatch と JSON Patch の比較が必要だ。JSONDiffpatch はブラウザや Node/Cloudflare Workers などでうまく動作する。
JSON Patch を外部パートナーに学んでもらうよう説得するのは難しかった。顧客向け API で使っており、ユーザーに理解して採用してもらうために多くの努力を払った。
JSON Pointer の仕様は「URLっぽく」感じられ、メタ JSON 構文を飛ばせそうに思える。「test」と「copy」は JSON Patch 仕様に固有で、複数の編集を一度に行う「トランザクション」も可能だ。