HTTPメソッドの安全性と冪等性:POSTの再送が危なくてPUTは大丈夫な理由
RFC 9110 の安全なメソッドと冪等なメソッドの違いを整理しました。接続が切れたとき GET・PUT・DELETE は再送してよく、POST・PATCH はなぜ注意が要るのか、If-Match で防ぐ方法まで扱います。
レスポンスを受け取る前に接続が切れると、クライアントにはリクエストがサーバーに反映されたかどうかがわかりません。同じリクエストをもう一度送ってよいかはメソッドで決まります。HTTP のセマンティクスを定める RFC 9110 は、メソッドの性質を「安全(safe)」と「冪等(idempotent)」の二つで分けています。
安全:読み取りだけを求める
安全なメソッドとは、定義された意味が実質的に読み取り専用のメソッドです。クライアントはサーバーの状態の変更を要求も期待もしません(9.2.1節)。RFC 9110 が定義するメソッドのうち、GET、HEAD、OPTIONS、TRACE が安全です。
副作用がまったくないという意味ではありません。仕様は、リクエストごとにアクセスログを書くサーバーや、広告のクリックで広告アカウントに課金される場合も安全だとしています。大事なのは、クライアントがその動作を求めていないことです。逆に page?do=delete のように GET で削除が起きる作りなら、リソースの所有者は安全なメソッドでのアクセス時にその動作を無効にしなければなりません(MUST)。リンクチェックやプリフェッチ、検索インデックスの作成のように、あらゆる URI に GET を送る自動処理があるからです。
冪等:何度送っても意図した効果は一度分
冪等なメソッドとは、同じリクエストを何度送ってもサーバーへの意図した効果が一度送ったときと同じになるメソッドです(9.2.2節)。PUT、DELETE と安全なメソッドがこれにあたります。PUT は対象の状態を送った表現に置き換えるよう求めるので、同じ内容を二度送っても結果の状態は同じです。POST はリソース独自の方法で処理するよう求めるので、二度送ると注文が二件できることがあります。
同じレスポンスが返るという意味ではありません。仕様は、元のリクエストが成功していても、繰り返したときのレスポンスは違う場合があると書いています。たとえば同じ DELETE をもう一度送ると二回目は 404 になることがありますが、消えた状態という効果は同じです。サーバーがリクエストごとにログや変更履歴を残すことも許されています。
| メソッド | 安全 | 冪等 |
|---|---|---|
| GET, HEAD, OPTIONS, TRACE | はい | はい |
| PUT, DELETE | いいえ | はい |
| POST, PATCH | いいえ | いいえ |
再送のルール
この区別が効いてくるのは自動再送です。レスポンスを読む前に接続が閉じた冪等なリクエストは、クライアントが新しい接続で送り直せます。冪等でないリクエストは、実際には冪等だとわかる手段か、元のリクエストが反映されていないと確かめる手段がない限り、自動で再送すべきではありません(SHOULD NOT)。プロキシは冪等でないリクエストを自動で再送してはならず(MUST NOT)、クライアントは失敗した自動再送をさらに自動で再送すべきではありません(SHOULD NOT)。アイドル状態の持続的接続が切れたときに POST を送り直す、という危うい推測をするクライアントもあると仕様は書いています。
PATCH と If-Match
PATCH を定める RFC 5789 は、PATCH は安全でも冪等でもないと明記しています。ただし冪等になるように送ることはできます。特定の元の状態を前提とするパッチ形式なら、クライアントは条件付きリクエストを使うべきです(SHOULD)。たとえば最後に受け取った強い ETag を If-Match に入れておけば、その間にリソースが変わっていればリクエストは失敗します。If-Match の条件が偽ならサーバーはメソッドを実行してはならず(MUST NOT)、412 Precondition Failed で応答できます。同じ変更がすでに反映済みに見える場合は 2xx で応答することもできます(RFC 9110 13.1.1節)。ETag そのものは no-cache と no-store の違い で扱いました。
POST を再送しなければならないとき
仕様は、設計や設定によってそのリクエストのセマンティクスが実際には冪等だとわかっていれば、POST も自動で再送できるとしています。決済や注文 API で使われる方法の一つは、リクエストごとに一意のキーを受け取り、同じリクエストの再試行を識別し、処理済みなら以前の結果を返すことです。IETF にはそのための Idempotency-Key ヘッダーのドラフトがありますが、2026年10月8日の確認時点で RFC ではなく、ドラフトも失効しています。フォームの POST のあと結果ページへ移す 303 応答は 301・302・307・308 リダイレクトの違い にまとめました。
ボディを持つ安全なリクエスト:QUERY
2026年6月に発行された RFC 10008 は QUERY メソッドを定めています。POST のようにリクエストボディを送りますが、安全かつ冪等なので、接続が切れたあとでも送り直せます。ブラウザからクロスオリジンで QUERY リクエストを送る場合、QUERY は CORS セーフリスト対象メソッドではないため、プリフライトが必要です。新しい仕様なので、使うクライアント・サーバー・プロキシが対応しているかは別途確認してください。
参考にした文書
- RFC 9110 HTTP Semantics:9.2.1、9.2.2、9.3.3〜9.3.5、13.1.1節
- RFC 5789 PATCH Method for HTTP:2節
- RFC 10008 The HTTP QUERY Method:2節、4節
- IANA HTTP Method Registry
- IETF draft-ietf-httpapi-idempotency-key-header
リンクと内容は2026年10月8日に確認しました。