合同会社小村ソフト
第 2 章

HTTP メソッド — 安全・冪等という約束

GET・POST・PUT・DELETE・HEAD を「何をしたいか」で使い分け、安全(サーバの状態を変えない)と冪等(何度やっても同じ)という約束で線引きして、リトライの判断に使えるようにする。

「とりあえず全部 POST」で作っていないか

フォームも取得も削除も、動くからと全部 POST で作ってしまう。あるいは逆に、送信ボタンの再クリックで注文が二重に登録されてしまい、原因が分からない — メソッドの使い分けは、動くだけなら曖昧でも通ってしまうぶん、事故になってから効いてくる知識です。

前章で読んだとおり、リクエスト行の先頭にあるメソッドは、往復書簡の動詞です。HTTP にはメソッドがいくつもありますが、まずはこの 5 つを使い分けられれば十分です。

GET
「これをください」— リソースの取得。ページを開く、画像を読む、API から一覧を得る
HEAD
「GET と同じ答えを、本文抜きで」— サイズや更新日時などヘッダだけ確認したいとき
POST
「これを処理してください」— フォーム送信、新規作成、その他の処理依頼。効果は実行のたびに積み上がり得る
PUT
「この URL の中身を、この内容にしてください」— 宛先を指定した置き換え(上書き保存)
DELETE
「この URL のものを消してください」— 削除の依頼

たとえば PUT /users/42/profile は「42 番のユーザのプロフィールをこの内容にせよ」、POST /orders は「この注文内容を処理して新しい注文を作れ」。宛先が決まっている置き換えは PUT、新しく生まれるものや処理の依頼は POST、というのが基本の使い分けです。

小問 2-1 — 5 つの動詞を使い分ける

「何をしたいか」から適切なメソッドを選ぶ練習です。

Q1. オンラインショップ https://shop.example.com で、注文フォームに入力した内容を送信して新しい注文を作るとき、最も適切なメソッドはどれですか。

Q2. 巨大な動画ファイルについて、ダウンロードはせずにサイズや更新日時だけ知りたいとき、最も適切なメソッドはどれですか。

Q3. PUT と POST の違いの説明として最も適切なものはどれですか。

2 つの約束 — 安全と冪等

5 つの動詞を暗記するより大切なのが、メソッドに紐づく2 つの約束です。この 2 語は仕様書にもエラー調査にも頻出します。

安全(safe)— サーバの状態を変えない
「読むだけ」の約束。GET と HEAD が該当。何回呼んでもサーバのデータは変わらない
冪等(idempotent)— 何度やっても最終状態が同じ
1 回実行しても 10 回実行しても、サーバの最終状態が同じという約束。GET・HEAD に加え、PUT と DELETE も該当

ここで手を動かして確かめましょう。PUT /users/42/profile で「名前 = 小村」に置き換えるリクエストを 3 回送っても、最終状態は「名前 = 小村」— 1 回のときと同じです。DELETE /orders/7 を 2 回送っても、7 番の注文が消えているという最終状態は同じです(2 回目は 404 が返るかもしれませんが、冪等性が見るのはサーバ側の最終状態です)。一方 POST /orders を 3 回送れば注文が 3 件できる — POST は冪等ではありません。

関係を整理すると、安全なら必ず冪等です(何も変えないのだから、何度やっても同じ)。逆は成り立たず、PUT と DELETE は「変えるけれど、何度やっても同じ」— 冪等だが安全ではない、という中間の帯に入ります。

GET・HEAD・POST・PUT・DELETE の各 HTTP メソッドについて、安全か・冪等か・主な用途を対応づけた表

5 つのメソッドを安全・冪等の 2 軸で並べた地図です。GET/HEAD は両方の約束を守り、PUT/DELETE は冪等のみ、POST はどちらの約束もしません。この地図が「リトライしてよいか」の判断表になります。

実務での効き目 — 更新のリトライは冪等性を確認してから

この 2 つの約束が実務で最も効くのは、通信が失敗したときの再送(リトライ)の判断です。

リクエストを送ってタイムアウトしたとき、実は 2 つの可能性があります。「リクエストがサーバに届かなかった」のか、「届いて処理も済んだのに、返事だけが失われた」のか — クライアントからは区別できません。ここで冪等性が効きます。

冪等なメソッド(GET/HEAD/PUT/DELETE)
仮に処理済みでも、再送して最終状態は変わらない。安心してリトライできる
冪等でないメソッド(POST)
処理済みだった場合、再送は二重処理(注文 2 件・決済 2 回)になる。無条件のリトライは危険

だからこそ、ブラウザは POST の結果画面でリロードすると「フォームを再送信しますか?」とわざわざ確認してきます(この場面は第 7 章のケースで再登場します)。また、自動リトライを組み込むライブラリの多くが既定で GET だけを再送するのも、この約束が根拠です。「更新のリトライは、そのメソッドが冪等か確認してから」 — 手が覚えるまで唱えてください。

小問 2-2 — 安全と冪等の線引き

2 つの約束を正確に言い分け、実務の「リトライしてよいか」に結びつけます。

Q4. メソッドが「安全(safe)」であるとは、どういう約束ですか。

Q5. 「冪等(べきとう)だが安全ではない」メソッドの組み合わせはどれですか。

Q6. 更新系の API リクエストを送ったところ、応答が返らずタイムアウトしました。もう一度同じリクエストを送る前に確認すべきこととして最も適切なものはどれですか。

この章で持ち帰ること

  • メソッドは往復書簡の動詞。取得は GET、本文抜きの確認は HEAD、処理依頼・新規作成は POST、宛先指定の置き換えは PUT、削除は DELETE
  • 安全 = サーバの状態を変えない(GET/HEAD)。冪等 = 何度やっても最終状態が同じ(GET/HEAD/PUT/DELETE)。安全なら必ず冪等
  • POST は安全でも冪等でもない。タイムアウト後の無条件リトライは二重処理の危険がある
  • 更新のリトライは冪等性を確認してから — この一文が実務での効き目

頼みごとの読み方が身についたので、次章は往復書簡のもう片側 — サーバからの返事です。3 桁のステータスコードを、百の位から順に読み解きます。