JSON Patch: APIデータ更新のスマートな方法

INEZA Felin-Michel

INEZA Felin-Michel

1 9月 2025

JSON Patch: APIデータ更新のスマートな方法

最新のAPIを構築しました。GETはデータを取得し、POSTは新しいリソースを作成します。ここまでは順調です。しかし、データの更新となると、話は複雑になります。

ユーザーがメールアドレスを変更したいだけだとしましょう。本当にユーザープロファイル全体を再送信してもらう必要がありますか?それは扱いにくく、非効率的で、エラーが発生しやすくなります。特に接続が遅い場合や、更新が競合する場合に顕著です。

より良い方法があります。JSON Patchです。
オブジェクト全体を送信する代わりに、変更点だけを送信します。まるで仕立て屋にスーツ全体を作り直してもらうのではなく、変更箇所のリストを渡すようなものです。

JSONがAPIの共通言語となった今、JSON Patchは部分的な更新のための軽量で洗練されたソリューションを提供します。

もちろん、JSON Patchを使ったAPIの設計とテストには適切なツールが必要です。そこでApidogの出番です。Apidogを使えば、JSON Patchリクエストを簡単に作成、テスト、検証できるため、コードを一行も書く前に意図したとおりに更新が機能することを確認できます。さらに、無料でダウンロードして今日から試すことができます。

💡
美しいAPIドキュメントを生成する優れたAPIテストツールをお探しですか?

最大限の生産性で開発チームが共同作業できる、統合されたオールインワンプラットフォームをお探しですか?

Apidogはあなたのすべての要求に応え、Postmanをはるかに手頃な価格で置き換えます
button

次に、JSON Patchとは何か、どのように機能するのか、そしてなぜあなたの次のプロジェクトに組み込むべきなのかを詳しく見ていきましょう。

問題点:「盲目的な」PUTリクエスト

JSON Patchがなぜこれほどまでに有用なのかを理解するためには、まずそれが解決する問題を理解する必要があります。従来、RESTful APIでリソースを更新するには、PUT HTTPメソッドが使用されてきました。

PUTリクエストはべき等(同じリクエストを複数回行っても、1回行ったのと同じ効果が得られる)であることを意図しており、通常はターゲットURLのリソース全体を、リクエストボディで提供された新しい表現に置き換えます。

ユーザープロファイルのリソースを想像してみましょう。

GET /users/123

{
  "id": 123,
  "username": "johndoe",
  "email": "john.old@example.com",
  "firstName": "John",
  "lastName": "Doe",
  "age": 30,
  "accountStatus": "active",
  "preferences": {
    "theme": "light",
    "notifications": true
  },
  "signUpDate": "2023-01-15"
}

さて、もしジョンがメールアドレスだけを変更したい場合、一般的なPUTリクエストは次のようになります。

PUT /users/123

{
  "id": 123,
  "username": "johndoe",
  "email": "john.new@example.com", // 変更されたフィールド
  "firstName": "John",
  "lastName": "Doe",
  "age": 30,
  "accountStatus": "active",
  "preferences": {
    "theme": "light",
    "notifications": true
  },
  "signUpDate": "2023-01-15"
}

問題点がお分かりでしょうか?データの99%は変更されていないにもかかわらず、すべてのフィールドを送り戻す必要がありました。このアプローチにはいくつかの欠点があります。

  1. 帯域幅の増加:不要なデータを大量に送信しています。大規模なリソースの場合、特にモバイルネットワークでは、これはパフォーマンスに大きな影響を与える可能性があります。
  2. 競合のリスクが高い:ジョンがメールを編集している間に、別のプロセスがageフィールドを更新した場合、ジョンのPUTリクエストは、彼が送信した古い値で新しい年齢を誤って上書きしてしまう可能性があります。
  3. クライアント側の複雑さ:クライアントアプリケーションは、まずリソース全体をGETし、特定のフィールドを変更し、それから全体をPUTし直す必要があります。これは複数のステップが必要であり、クライアントが全体の状態を管理する必要があります。

ここでHTTP PATCHメソッドが役立ちます。

解決策:HTTP PATCHとJSON Patchの導入

HTTP PATCHメソッドは、リソースの部分的な変更を可能にするために導入されました。リソース全体を置き換えるPUTとは異なり、PATCHはリソースに一連の変更を適用します。

しかし、落とし穴があります。HTTP標準は、これらの「変更」の形式を定義していません。独自の形式を発明することもできます。例えば、次のようなものを送信することも可能です。

{ "op": "change_email", "value": "new@example.com" }

しかし、これはカスタムで非標準であり、他の開発者はあなたの特定の言語を学ぶ必要があります。

このギャップを埋めるのがJSON Patchです。JSON Patch(RFC 6902で定義)は、JSONドキュメントに適用する変更を指定するための標準化された形式です。JSONドキュメントをどのように変更すべきかを正確に記述するための、明確で曖昧さのない言語を提供します。

HTTP PATCHメソッドとJSON Patchドキュメントとしてフォーマットされたボディを組み合わせることで、部分的な更新を実行するための強力で標準ベースの方法が得られます。

JSON Patchの仕組み:基本

JSON Patchドキュメントは常にJSON配列です。配列の各要素は操作オブジェクトです。これらの操作はターゲットドキュメントに順番に適用され、パッチ全体はアトミックです。つまり、いずれかの操作が失敗した場合、パッチ全体が中止され、ドキュメントは変更されません。

すべての操作オブジェクトには、実行するアクションを指定する必須のopメンバー(「operation」の略)があります。最も一般的な操作は、addremovereplacemovecopyです。

ジョンがメールアドレスを変更する先の例を見てみましょう。JSON Patchを使用すると、リクエストは劇的にシンプルになります。

PATCH /users/123

[
  { "op": "replace", "path": "/email", "value": "john.new@example.com" }
]

これだけです!私たちは1つの操作を送信しています。「パス '/email' の値をこの新しい値に置き換える」というものです。リクエストは小さく、明確で、意図がはっきりしています。他のフィールドには一切触れません。

pathプロパティの理解

pathプロパティはJSON Pointer(RFC 6901)であり、JSONドキュメント内をナビゲートして操作したい特定の値に到達するためにスラッシュベースの構文を使用する文字列です。

この構文は、ネストされたJSON構造をナビゲートするのに強力です。

JSON Patch vs JSON Merge Patch

開発者はJSON Patch(RFC 6902)とJSON Merge Patch(RFC 7386)を混同することがよくあります。明確にしましょう。

JSON Patch:

JSON Merge Patch:

要するに:

JSON Patchの操作

最も一般的な操作を例を挙げて見ていきましょう。ターゲットドキュメントとして同じユーザープロファイルを使用します。

1. add操作

add操作は、新しい値をオブジェクトまたは配列に挿入するために使用されます。

オブジェクトに新しいプロパティを追加する:

{ "op": "add", "path": "/twitterHandle", "value": "@johndoe" }

これは、ユーザーオブジェクトに新しいtwitterHandleフィールドを追加します。

配列に要素を追加する(特定のインデックスに):

ユーザーが"hobbies"配列を持っていると想像してください:["reading", "cycling"]

{ "op": "add", "path": "/hobbies/1", "value": "hiking" }

これはインデックス1に「hiking」を挿入し、結果として["reading", "hiking", "cycling"]となります。配列の末尾に追加するには、/-を使用できます:{ "op": "add", "path": "/hobbies/-", "value": "hiking" }

2. remove操作

remove操作は、指定された場所の値を削除します。

オブジェクトからプロパティを削除する:

{ "op": "remove", "path": "/age" }

これは、ユーザーオブジェクトからageフィールド全体を削除します。

配列から要素を削除する:

{ "op": "remove", "path": "/hobbies/0" }

これは、hobbies配列から最初の要素(インデックス0)を削除します。

3. replace操作

replace操作は、実質的に同じパスでのremoveaddの組み合わせです。既存の値を新しい値に置き換えます。メールの例は典型的なreplaceでした。

ユーザーのテーマ設定を変更する:

{ "op": "replace", "path": "/preferences/theme", "value": "dark" }

4. move操作

move操作は、ある場所から値を削除し、別の場所に追加します。

あるプロパティから別のプロパティに値を移動する:

{ "op": "move", "from": "/firstName", "path": "/first_name" }

これは、firstNameの値をfirst_nameという新しいプロパティに移動し、古いfirstNameプロパティを削除します。

5. copy操作

copy操作は、ある場所から別の場所に値をコピーします。元の値は変更されません。

設定のバックアップを作成する:

{ "op": "copy", "from": "/preferences/theme", "path": "/backupTheme" }

これは、現在のテーマの値を新しいbackupThemeフィールドにコピーします。

6. test操作

これは安全機能です。test操作は、ある場所の値が指定された値と等しいかどうかをチェックします。テストが失敗した場合、パッチ全体が中止されます。これは、競合を防ぐ(楽観的ロック)のに非常に役立ちます。

更新前に他の誰もメールを変更していないことを確認する:

[
  { "op": "test", "path": "/email", "value": "john.old@example.com" },
  { "op": "replace", "path": "/email", "value": "john.new@example.com" }
]

もし現在のemail"john.old@example.com"ではない場合(おそらく別のプロセスがすでに変更したため)、test操作は失敗し、replaceは実行されません。これにより、更新が最新の既知の状態に基づいていることが保証されます。

JSON Patchを使う理由:利点

  1. 効率性:最も明白な利点です。変更点のみを送信するため、ペイロードサイズが大幅に削減され、パフォーマンスが向上します。
  2. 並行性制御:test操作は、楽観的ロックのための組み込みメカニズムを提供し、更新の消失や競合状態を防ぐのに役立ちます。
  3. 原子性:パッチ適用が全か無かであるという性質により、データの一貫性が保たれます。10個の操作からなるパッチの5番目の操作が失敗した場合、最初の4つの操作はロールバックされます。
  4. 明確さと意図:リクエストボディは、新しい状態をただダンプするのではなく、変更の意図(「メールを置き換える」、「趣味を追加する」)を明確に記述します。これにより、ログが読みやすくなり、デバッグが容易になります。
  5. 標準化:IETF標準(RFC 6902)です。他の開発者も認識しており、様々なプログラミング言語の多くのライブラリやフレームワークには、JSON Patchドキュメントの解析と適用をサポートする機能が組み込まれています。

JSON Patchのよくある落とし穴と間違い

JSON Patchは強力ですが、開発者はしばしば次のような問題に遭遇します。

APIがJSON Patchを使用する理由

APIがJSON Patchを好むのは、次の理由からです。

例えば、GitHubのAPIは、リポジトリのメタデータを効率的に編集するためにJSON Patchをサポートしています。

REST APIにおけるJSON Patch

RESTful APIでは、JSON PatchはHTTP PATCHメソッドと組み合わせて使用されることがよくあります。

PATCH vs PUT:

JSON Patchの場合、Content-Typeは次のようになります。

application/json-patch+json

これは、ボディにJSON Patchドキュメントが含まれていることをサーバーに伝えます。

GraphQLおよびその他のプロトコルにおけるJSON Patch

JSON Patchは主にREST APIで使用されますが、次のような分野でも関連性があります。

JSON Patchが効率を向上させる方法

ユーザープロファイルを同期するモバイルアプリを想像してみてください。わずかな更新ごとに2MBのJSONファイルを再アップロードする代わりに、アプリは小さなパッチリクエストを送信するだけで済みます。

これは次のことを意味します。

課題と考慮事項

JSON Patchは強力ですが、複雑さがないわけではありません。

  1. サーバーでの実装の複雑さ:サーバーでパッチを正しく適用することは、新しいJSONオブジェクトを単純に受け入れるよりも複雑です。各操作を検証し、存在しないパスへのポインタを適切に処理し、シーケンス全体がアトミックに適用されることを保証する必要があります。幸いなことに、ほとんどの最新のWebフレームワークには、これを処理するためのライブラリ(例:Node.js用のjson-patch、Python用のjsonpatch、.NETのJsonPatchDocument)があります。
  2. エラーの可能性:不正な形式のパッチドキュメントや無効なポインタ(例:存在しないフィールドをreplaceしようとする)はエラーになります。APIはこれらを適切に処理し、明確なエラーメッセージ(通常は422 Unprocessable Entityまたは400 Bad Request)を返す必要があります。
  3. 万能薬ではない:非常にシンプルなリソースの場合、PUTの方が簡単な場合もあります。JSON Patchは、リソースが大規模な場合や、複雑な条件付き更新をサポートする必要がある場合に威力を発揮します。

ApidogでJSON Patchエンドポイントをテストする

JSON Patchを手動でテストするのはイライラすることがあります。ここで洗練されたAPIツールが非常に役立ちます。オールインワンのAPI開発プラットフォームであるApidogは、ここで大きな助けとなります。

button

Apidogでのワークフロー例:

  1. 新しいリクエストを作成します。
  2. メソッドをPATCHに設定します。
  3. Content-Type: application/json-patch+jsonを追加します。
  4. JSON Patch配列を入力します。
  5. 送信して即座に結果を確認します。

Apidogを使用することで、パッチが正しいかどうかを推測するのではなく、正しく構築されていることを知ることができます。これにより、JSON Patch APIを自信を持って実装および利用し、プロのようにJSON Patchのテストを開始できます。

JSON Patchのベストプラクティス

JSON Patchを効果的に使用するには:

  1. 送信する前にJSON Patchドキュメントを検証します。
  2. 一貫性が重要な場合はテスト操作を使用します。
  3. 効率のためにパッチを小さく保ちます
  4. JSON Patchを使用する場合はAPIを明確に文書化します。
  5. テストを効率化するためにApidogのようなツールを使用します。

結論:より効率的なAPI標準を採用する

では、JSON Patchとは何でしょうか?

それは、add、remove、replaceなどの操作を使用して、JSONドキュメントへの変更を記述する標準化された方法です。オブジェクト全体を送信する代わりに、変更点のみを送信できるため、APIをより効率的、信頼性、柔軟性のあるものにできます。

JSON Patchは、API経由でデータを更新する方法についての私たちの考え方を変革します。それは、ドキュメント全体の置き換えという鈍器から、外科的な変更の精度へと私たちを導きます。この標準を採用することで、より効率的で、競合が発生しにくく、意図が明確なAPIを構築できます。

サーバー側で少しばかり事前検討が必要になりますが、クライアントアプリケーションとネットワークパフォーマンスにもたらされるメリットは計り知れません。次に更新エンドポイントを設計する際には、デフォルトのPUTに抵抗し、「これはPATCHの仕事ではないか?」と自問してみてください。

開発者にとって、特に部分的な更新を扱う場合、JSON Patchを理解することは現代のAPIと連携するための鍵となります。そして、Apidogのようなツールを使えば、JSON Patchリクエストを簡単にテスト、検証、デバッグできます。

button

ApidogでAPIデザイン中心のアプローチを取る

APIの開発と利用をよりシンプルなことにする方法を発見できる