Java | Web 基礎・HTTP・REST:HTTP 基礎 - PUT の役割

Java Java
スポンサーリンク

PUT を一言でいうと

PUT は
「この場所のデータを“丸ごとこの内容で上書きして”というメソッド」
です。

POST が「新しく作って」だとしたら、
PUT は「ここにあるものを、このデータで置き換えて」です。
そして 同じ PUT を何回送っても結果が変わらない(冪等) という性質が、とても重要なポイントです。


PUT の基本イメージ:全体を置き換える更新

例:ユーザー情報を丸ごと更新する

ユーザーの情報を「丸ごと更新」したいケースを考えます。

ID=1 のユーザーがいて、
名前・メールアドレス・年齢を全部新しい値にしたいとします。

そのときの PUT リクエストは、こんなイメージです。

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

{
  "id": 1,
  "name": "New Name",
  "email": "new@example.com",
  "age": 30
}
HTTP

意味は
/api/users/1 という場所にあるユーザーを、この JSON の内容で“丸ごと”上書きして」
です。

ここでのポイントは、
「送っていない項目はどうなるか?」ではなく、
「送った JSON が“そのリソースの完全な姿”だとみなす」
という考え方です。


PUT の重要な性質:冪等(べきとう)

同じ PUT を何回送っても結果が変わらない

PUT の大事な性質は「冪等」です。
これは、

同じリクエストを 1 回送っても、10 回送っても、
最終的なサーバー側の状態は同じ

という意味です。

先ほどの例で、
/api/users/1 に対して同じ JSON で PUT を 3 回送っても、
ユーザーの情報は「New Name / new@example.com / 30」のままです。
増えもしないし、変な副作用も増えません。

これが POST との大きな違いです。
POST は「新規作成」が多いので、
同じ POST を 3 回送ると、ユーザーが 3 人できてしまうことがあります。

PUT は「上書き」なので、
何度送っても「上書き後の状態」は変わらない、というわけです。


Java(Spring)での PUT の書き方

@PutMapping を使う

Spring では、PUT は @PutMapping で表現します。

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

ここでやっていることは、

URL の {id} で「どのユーザーか」を特定し
ボディの JSON(UserUpdateRequest)で「どう更新するか」を受け取り
サービス層で「上書き更新」を実行し
更新後のユーザー情報を返す

という流れです。

「全体更新」として設計する意識

PUT を使うときは、
「このリクエストボディが、そのリソースの完全な状態を表している」
という前提で設計するのが基本です。

つまり、
「このフィールドは送ってこなかったから、前の値を残そう」
というよりは、
「送ってこなかったフィールドは null やデフォルトになる」
という扱いが本来の PUT に近いです。

実務では、
「全体更新は PUT」「一部更新は PATCH」
と分けるか、
「更新は全部 PATCH に寄せる」
など、チームごとの流儀がありますが、
PUT の本来の意味は「全体を置き換える」と覚えておくとブレません。


PUT と POST の違いを整理する

何をしたいかの違い

POST:
「この集合に新しいものを追加して」
例:POST /api/users → 新しいユーザーを作る

PUT:
「この場所のものを、この内容で置き換えて」
例:PUT /api/users/1 → ID=1 のユーザーを上書き

URL の意味も変わります。

POST は「集合(/users)」に対して「新規追加」
PUT は「個体(/users/1)」に対して「上書き」

というイメージです。

性質の違い(冪等かどうか)

POST:
同じリクエストを何度も送ると、
同じものが何個も作られる可能性がある(非冪等)。

PUT:
同じリクエストを何度送っても、
最終状態は同じ(冪等)。

この違いは、
リトライやネットワーク障害時の挙動を考えるときに効いてきます。


PUT を使うときに気をつけたい設計ポイント

「本当に全体更新にしたいか?」を自問する

実務では、
「一部だけ変えたいことの方が多い」
という現実があります。

例えば、
ユーザーの名前だけ変えたい
メールアドレスだけ変えたい

といったときに、
「全フィールドをクライアントに持たせて PUT させる」のは、
フロントエンド側の負担が大きくなります。

そのため、

全体更新が自然なリソース → PUT
部分更新が多いリソース → PATCH を使う or 更新 API を POST に寄せる

といった判断をすることもあります。

ただし、
HTTP 的な意味としては
「PUT=全体置き換え」
という軸を忘れないことが大事です。

ID をどこで決めるか

PUT には、
「クライアントがリソースの場所(URL)を決めて PUT する」
という使い方もあります。

例えば、

PUT /api/files/manual.pdf
HTTP

のように、
「manual.pdf という名前のファイルを、この内容で置き換えて」
という意味で使うこともできます。

一方、
POST は「サーバー側が ID を採番する」ことが多いです。

POST /api/users → サーバーが ID=123 を発行して /api/users/123 ができる

PUT は「クライアントが URL を指定して上書き」、
POST は「サーバーが新しい URL を決める」、
という違いも頭の片隅に置いておくと、REST の設計がよりクリアになります。


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

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

PUT は、
「この URL にあるリソースを、このデータで“丸ごと上書きして”」
とサーバーに頼むメソッド。

新規作成がメインの POST と違い、
既存リソースの全体更新がメインの役割。
同じ PUT を何度送っても最終状態が変わらない「冪等」という性質を持つ。

Java(Spring)では @PutMapping で表現し、
URL で対象を特定し、
ボディで新しい完全な状態を渡して、
サービス層で上書き更新のロジックを書く。

もしよければ、
「ユーザー更新 API」を題材にして、
POST 版と PUT 版をどう設計し分けるか、一緒に書き出してみよう。
そこを自分で説明できるようになると、HTTP メソッド設計の解像度が一段上がるから。

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