Java | Web 基礎・HTTP・REST:HTTP 基礎 - PATCH

Java Java
スポンサーリンク

PATCH を一言でいうと

PATCH は
「このリソースの“一部だけ”を変えてほしいときに使うメソッド」
です。

PUT が「丸ごと上書きして」なら、
PATCH は「ここだけ直して(パッチを当てて)」というイメージです。
部分更新を表現するための HTTP メソッドだと思ってください。


PUT と PATCH の違いからイメージする

PUT は「全体をこの状態にして」

PUT は「この JSON が、そのリソースの完全な姿です」という前提で、
全体を置き換えるメソッドでした。

PUT /api/users/1
Content-Type: application/json

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com",
  "age": 30
}
HTTP

「ID=1 のユーザーを、この JSON の内容で丸ごと上書きして」という意味です。

PATCH は「この部分だけ変えて」

一方 PATCH は、
「全部は送らないから、書いてあるところだけ変えて」というメソッドです。

PATCH /api/users/1
Content-Type: application/json

{
  "name": "Bob"
}
HTTP

意味は
「ID=1 のユーザーの name だけ Bob に変えて。他の項目はそのまま」
です。

この「部分更新」が PATCH の一番の役割です。


Java(Spring)での PATCH の書き方

@PatchMapping を使う

Spring では、PATCH は @PatchMapping で表現します。

@PatchMapping("/api/users/{id}")
public UserResponse patch(
        @PathVariable Long id,
        @RequestBody UserPatchRequest request
) {
    var user = userService.patch(id, request);
    return UserResponse.from(user);
}
Java

UserPatchRequest は、
「どの項目を更新する可能性があるか」を表す DTO です。

例えば、こういうイメージです。

public class UserPatchRequest {
    private String name;
    private String email;
    // setter / getter
}
Java

サービス層では、
「null じゃない項目だけ反映する」
というロジックを書くことが多いです。

public User patch(Long id, UserPatchRequest req) {
    var user = userRepository.findById(id).orElseThrow(...);

    if (req.getName() != null) {
        user.changeName(req.getName());
    }
    if (req.getEmail() != null) {
        user.changeEmail(req.getEmail());
    }
    return user;
}
Java

こうして、
「送られてきた項目だけを更新する」
という PATCH らしい振る舞いを実現します。


PATCH の設計で大事なポイント

どの形式の PATCH を採用するか

HTTP の仕様上、PATCH のボディにはいくつか“流儀”がありますが、
実務ではだいたい次のどちらかです。

1. 「普通の JSON で“変更したいフィールドだけ”送る」方式

さっきの例のように、
単純な JSON を使って「変えたいところだけ送る」やり方です。

実装が分かりやすく、
フロントエンド側も扱いやすいので、
一番よく使われます。

2. JSON Patch(application/json-patch+json)を使う方式

もう少し厳密にやる場合は、
「どのフィールドに、どんな操作をするか」を配列で表現する
JSON Patch という形式を使うこともあります。

[
  { "op": "replace", "path": "/name", "value": "Bob" },
  { "op": "remove",  "path": "/age" }
]
JSON

ただし、
初心者のうちは「PATCH=部分更新」「普通の JSON で必要な項目だけ送る」
くらいの理解で十分です。

PUT と PATCH をどう使い分けるか

理想的には、

全体更新 → PUT
部分更新 → PATCH

と分けるのがきれいです。

ただ、現場では
「更新は全部 PATCH に寄せる」
「PUT はほとんど使わない」
というプロジェクトもあります。

それでも、
HTTP 的な意味として
PUT=全体置き換え
PATCH=部分更新
という軸を知っておくと、
他人の API を読むときに混乱しにくくなります。


PATCH の性質:冪等かどうか

本来は「冪等に設計するのが望ましい」

PATCH は、仕様上「必ず冪等でなければならない」とまでは決められていません。
ですが、実務では できるだけ冪等になるように設計する のが望ましいです。

例えば、
「name を Bob に変える PATCH」を何度送っても、
最終的に name が Bob であることは変わりません。

こういう設計なら、
PUT と同じように「何度送っても最終状態は同じ」と言えます。

逆に、
「ポイントを +10 する PATCH」
のように「相対的な変更」を PATCH でやると、
同じリクエストを 3 回送ると +30 になってしまい、
冪等ではなくなります。

だから、
PATCH を設計するときは、

「この PATCH は“最終状態”を指定しているか?」
「それとも“変化量”を指定しているか?」

を意識して、
できるだけ前者(最終状態)に寄せると扱いやすくなります。


Java 初心者が PATCH をどう捉えればいいか

まずは「部分更新が必要になったら思い出すメソッド」として覚える

最初から PATCH を完璧に使いこなす必要はありません。

まずは、

「ユーザーの一部だけ変えたい」
「設定の一部だけ更新したい」

といった要件が出てきたときに、
「あ、これ PATCH というメソッドが向いてそうだな」
と思い出せるようになることが大事です。

Spring での型設計に慣れていく

PATCH を使うときは、
「どのフィールドが更新対象になり得るか」を表す DTO を作り、
サービス層で「null じゃないところだけ反映する」
というパターンに慣れていくとよいです。

このとき、
エンティティのメソッド(changeName など)をちゃんと用意して、
「どこで何を変えているか」が分かるようにしておくと、
ドメインモデルとしてもきれいになります。


初心者向けまとめ:PATCH を自分の言葉で説明するなら

あなたの言葉で整理すると、こうなります。

PATCH は、
「このリソースの一部だけを更新してほしい」ときに使うメソッドで、
PUT のような「全体置き換え」ではなく、
「送った項目だけを変える」ために使う。

Java(Spring)では @PatchMapping で表現し、
部分更新用のリクエスト DTO を用意して、
サービス層で「null じゃないフィールドだけ反映する」などのロジックを書く。

全体更新は PUT、部分更新は PATCH、
という軸を頭に置いておくと、
REST API の設計が一段クリアになる。

もしよければ、
「ユーザーの名前だけ変える API」「メールアドレスだけ変える API」を
PUT でやる場合と PATCH でやる場合を、一緒に書き比べてみよう。
その違いを自分の言葉で説明できるようになったとき、PATCH はもう“怖いメソッド”ではなくなるから。

タイトルとURLをコピーしました