コンピューターサイエンス:アルゴリズム / OS / ネットワーク / DB
HTTP メソッド
絞り込んだ検索結果の URL を、同僚に送れない
検索フォームを作ったら、条件を入れた後の画面を「これ見て」と共有できませんでした。原因は送り方を POST にしていたことです。条件がどこに乗るかで、後からできることが変わります。
取りに行くのか、送るのか、消すのか
メソッドは、リクエストの 1 行目に書く用件の種類です。仕様にはいくつも並んでいますが、日々書くのは 4 つに絞れます。
- 取りに行く —
GET。条件は URL に乗る。URL をコピーすれば同じ画面が再現でき、ブックマークもキャッシュも効く - 送る —
POST。中身は本文に乗る。URL に出ないので、長いデータや見せたくないデータを渡せる - 置き換える —
PUT。渡した内容でまるごと上書きする - 消す —
DELETE
検索やページ遷移が GET、フォーム送信や決済が POST になるのは、この「条件がどこに乗るか」の違いから来ています。共有したい画面なら GET、URL に残ってほしくない情報を含むなら POST です。
もう 1 つ、GET には守るべき約束があります。状態を変えてはいけません。削除の操作を /delete?id=3 のような普通のリンクで作ると、検索エンジンの巡回や、ブラウザの先読み機能が勝手にそれを踏みます。誰も押していないのにデータが消えていく、という事故はこの形で起きます。消す操作は GET で書かない、と決めておくだけで防げます。
もう一度送ってよいのか、送ってはいけないのか
通信が途中で切れて返事が来なかったとき、同じリクエストをもう一度投げてよいでしょうか。判断の基準は「何回呼んでも結果が変わらないか」です。この性質を冪等 (べきとう) と言います。
GET は何回取っても中身は変わりません。PUT は同じ内容で上書きし直すだけなので、2 回でも 3 回でも同じです。DELETE も、消えているものをもう一度消せば消えたままです。この 3 つは、返事が来なければ安心して再送できます。
DELETE の 2 回目は「そんなものは無い」と返ってくるかもしれません。返事の内容は変わりますが、終わった後の状態は 1 回目と同じです。冪等が言っているのはこちらで、返り値が毎回同じ、という意味ではありません。
危ないのは POST です。注文を作る POST を 2 回送れば、注文が 2 件できる可能性があります。決済 API に「同じ受付番号のリクエストは 1 回しか処理しない」という仕組みがあるのは、この再送事故を防ぐためです。呼ぶ側は迷わず再送でき、受ける側は二重処理を避けられます。
「在庫を 1 増やす」は 2 回呼ぶと 2 増える
冪等かどうかは、メソッドの名前ではなく操作の中身で決まります。部分更新に使う PATCH で考えてみます。
プレーンテキスト
在庫を 1 増やす → 2 回届くと 2 増える (冪等でない)
在庫を 10 にする → 何回届いても 10 (冪等)同じ PATCH でも、相対値で書くか絶対値で書くかで性質が変わります。API を自分で設計するときは、絶対値で表せないかを先に考えると、再送に強い作りになります。
復習ミニクイズ
次のうち冪等 (idempotent) ではないメソッドはどれですか