Java | Web 基礎・HTTP・REST:HTTP 基礎 - 冪等性

Java Java
スポンサーリンク

冪等性を一言でいうと

冪等性(べきとうせい)は、
「同じ操作を何回繰り返しても、最終的な結果が変わらない性質」
のことです。

1 回やっても、10 回やっても、「状態」が同じなら冪等。
回数によって結果が変わるなら非冪等。

HTTP メソッドや API 設計を考えるときに、めちゃくちゃ重要なキーワードです。


まずは直感イメージからつかむ

冪等な操作の例

玄関の電気のスイッチを「消す」ボタンだとします。

「消す」ボタンを 1 回押して電気が消えた。
2 回目押しても、3 回目押しても、電気は「消えたまま」。

このとき、
「電気を消す」という操作は、
何回やっても最終状態(消えている)が変わらないので、冪等です。

非冪等な操作の例

貯金箱に 100 円を入れる操作を考えます。

1 回入れたら +100 円。
2 回入れたら +200 円。
3 回入れたら +300 円。

回数によって結果(残高)が変わります。
これは冪等ではありません。


HTTP と冪等性の関係

HTTP メソッドごとの冪等性

HTTP の世界では、
メソッドごとに「冪等かどうか」が決まっています(設計上そうあるべき、とされている)。

GET:冪等
PUT:冪等
DELETE:冪等
POST:非冪等(が普通)

ここがとても大事です。

GET が冪等な理由

GET は「読むだけ」です。
同じ URL に対して GET を 1 回送っても、10 回送っても、
サーバー側の状態は変わりません。

だから冪等です。

PUT が冪等な理由

PUT は「このリソースを、この内容で上書きして」です。

PUT /users/1
{
  "name": "Alice",
  "age": 20
}
HTTP

この PUT を 1 回送っても、10 回送っても、
最終的にユーザー 1 の状態は「Alice, 20」のままです。

だから冪等です。

DELETE が冪等な理由

DELETE /users/1 を 1 回送ると、ユーザー 1 は削除されます。
2 回目以降送っても、すでにいないので「いない状態」のままです。

最終状態は「ユーザー 1 は存在しない」で変わらないので、冪等です。

POST が冪等ではない理由

POST /users で新規ユーザーを作る API を考えます。

同じ POST を 3 回送ると、
ユーザーが 3 人作られる可能性があります。

回数によって結果が変わるので、非冪等です。


なぜ冪等性がそんなに重要なのか

ネットワークは「同じリクエストを複数回送る」ことがある

現実のネットワークでは、
タイムアウトやエラーが起きたときに、
クライアントや中継サーバーが「同じリクエストを再送」することがあります。

もしそのリクエストが冪等なら、
何度送られても最終状態は変わらないので、安全です。

もし非冪等なら、
再送によって「意図しない重複作成・重複更新」が起きる危険があります。

だから、
「この操作は冪等であるべきか?」
「冪等でないなら、どうやって二重実行を防ぐか?」

を考えることが、堅牢な API 設計には欠かせません。

キャッシュや中継サーバーの最適化にも関わる

GET が冪等であることを前提に、
ブラウザや CDN は GET の結果をキャッシュしたり、
中継サーバーがリクエストをまとめたりできます。

もし GET が副作用を持っていたら、
こうした最適化は危険になってしまいます。

冪等性は、
「ネットワーク全体が安心して賢く振る舞えるための前提条件」
でもあります。


Java(Spring)で冪等性を意識する場面

更新系 API を設計するとき

例えば、ユーザー更新 API を考えます。

「この API を何回叩いても、最終状態は同じか?」
と自問してみてください。

PUT で「この状態にして」と送るなら、
同じ PUT を何回送っても結果は同じ → 冪等。

一方、
「ポイントを +10 する API」を PUT や PATCH で作ると、
同じリクエストを 3 回送ると +30 になってしまい、非冪等です。

そういう「加算系」「インクリメント系」は、
冪等ではないことを理解したうえで、
二重送信対策(トークン、リクエスト ID など)を考える必要があります。

サービス層の設計で「最終状態」を意識する

冪等な API を作りたいときは、
「変化量」ではなく「最終状態」を指定する設計に寄せるとよいです。

変化量:「ポイントを +10 して」 → 回数で結果が変わる
最終状態:「ポイントを 100 にして」 → 何回やっても 100

サービス層のメソッドも、

addPoint(userId, 10) より
setPoint(userId, 100)

の方が冪等にしやすい、という感覚を持っておくと、
設計の選択肢が変わってきます。


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

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

冪等性とは、
「同じ操作を何回繰り返しても、最終的な状態が変わらない性質」のこと。

HTTP では、
GET・PUT・DELETE は冪等、
POST は普通は冪等ではない。

ネットワークの再送やキャッシュを安全に行うために、
どの API を冪等にするか、
どの API は非冪等として扱うか、
を意識して設計することが大事。

もしよければ、
今あなたがイメージしている API を一つ挙げて、
「これは冪等か? 同じリクエストを 3 回送ったらどうなるか?」
を一緒に言語化してみよう。
その問いを自分で回せるようになると、設計の“怖さ”がかなり減っていくから。

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