JSON Patch
JSON ドキュメントの部分更新操作を記述する標準フォーマット (RFC 6902)
データ形式API
JSON Patch とは
JSON Patch (RFC 6902) は、JSON ドキュメントに対する部分更新操作を配列形式で記述する標準フォーマットである。HTTP PATCH メソッドと組み合わせて、リソースの一部だけを更新する REST API を実装する際に使われる。Content-Type は application/json-patch+json を指定する。
PUT がリソース全体の置換であるのに対し、PATCH + JSON Patch は「何をどう変更するか」を明示的に記述する。大きなリソースの一部だけを更新する場合、転送データ量が大幅に削減される。
6 つの操作
[
{ "op": "add", "path": "/tags/2", "value": "urgent" },
{ "op": "remove", "path": "/tags/0" },
{ "op": "replace", "path": "/status", "value": "active" },
{ "op": "move", "from": "/old_name", "path": "/new_name" },
{ "op": "copy", "from": "/template", "path": "/config" },
{ "op": "test", "path": "/version", "value": 3 }
]
| 操作 | 説明 | 用途 |
|---|---|---|
| add | 値を追加 (配列の挿入、新フィールドの追加) | 新しいタグの追加 |
| remove | 値を削除 | 不要なフィールドの削除 |
| replace | 値を置換 | ステータスの更新 |
| move | 値を移動 (remove + add) | フィールド名の変更 |
| copy | 値をコピー | テンプレートからの複製 |
| test | 値が期待通りか検証 (楽観的ロック) | 競合検出 |
test 操作による楽観的ロック
test 操作は JSON Patch の最も重要な機能だ。更新前に現在の値を検証し、他のクライアントが同時に変更していないことを確認する。
[
{ "op": "test", "path": "/version", "value": 3 },
{ "op": "replace", "path": "/status", "value": "shipped" },
{ "op": "replace", "path": "/version", "value": 4 }
]
version が 3 でなければ、パッチ全体が失敗する (409 Conflict)。DynamoDB の条件付き書き込みと同じ概念だ。
PUT vs PATCH vs JSON Patch
// PUT: リソース全体を置換 (全フィールドを送信)
PUT /orders/123
{ "id": "123", "status": "shipped", "items": [...], "address": {...}, "total": 5000 }
// PATCH + JSON Merge Patch: 変更フィールドだけ送信 (シンプル)
PATCH /orders/123
Content-Type: application/merge-patch+json
{ "status": "shipped" }
// PATCH + JSON Patch: 操作を明示的に記述 (高機能)
PATCH /orders/123
Content-Type: application/json-patch+json
[{ "op": "replace", "path": "/status", "value": "shipped" }]
| 方式 | 長所 | 短所 |
|---|---|---|
| PUT | シンプル、べき等 | 全フィールド送信が必要 |
| JSON Merge Patch | シンプル、直感的 | 配列操作が苦手、null で削除 |
| JSON Patch | 配列操作、test 操作、高精度 | 記述が冗長 |
JSON Patch が適するケース
- 大きなリソースの一部だけを更新する API
- 配列の特定要素を操作する必要がある場合
- 楽観的ロック (test 操作) が必要な場合
- 変更履歴を操作単位で記録したい場合
理論と実装の両面から学ぶなら関連書籍が参考になる。