Skip to content

Instantly share code, notes, and snippets.

@pokotyamu
Created May 2, 2016 01:45
Show Gist options
  • Save pokotyamu/6afb6e7bfe546a0618a3d25199d5e0c6 to your computer and use it in GitHub Desktop.
Save pokotyamu/6afb6e7bfe546a0618a3d25199d5e0c6 to your computer and use it in GitHub Desktop.

[@otofu_square レビュー待ち] Webを支える技術 第7章 HTTPメソッド 冨田

この記事について

技術研修で読み進めているWebを支える技術について、各章のまとめを順次上げていく。 前Webを支える技術6章

HTTPメソッドの概要

HTTPメソッドには8つの種類がある。

メソッド 意味
GET リソースの取得
POST 小リソースの作成、リソースへのデータの追加、その他処理
PUT リソースの更新、リソースの作成
DELETE リソースの削除
HEAD リソースのヘッド(メタデータ)の取得
OPTION リソースがサポートしているメソッドの取得
TRACE 自分宛てにリクエスト・メッセージを返す(ループバック)試験
CONNECT プロキシ動作のトンネル接続への変更

この8つのうちTRANCEと````CONNECT```はあまり使われないため 現在のHTTTPはたった6種類のメソッドで表現されている。

以降、各メソッドについて見ていく。 また、ステータスコードについては、次の第8章で述べる。

各ヘッダの確認方法はGoogle Choromeの場合 この記事のレスポンスヘッダのコピーを参照

GETメソッド

GETでは、指定したURIの情報を取得する。 Webページの取得、画像の取得、映像の取得、フィードの取得など、実際にブラウザを利用している時に一番使われるメソッドがGETメソッドである。

GET / HTTP/1.1
Host: www.hottomotto.com
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Date: Tue, 26 Apr 2016 03:27:37 GMT
Server: Apache
Vary: Accept-Encoding
X-IIJ-Cache: MISS
Transfer-Encoding: chunked

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- 途中略 -->
</body>
</html>

例からサーバに指定されたURIに対応するデータをレスポンスとして返している。

POSTメソッド

POSTメソッドでは3つの役割が存在する。

子リソースの作成

ブログ記事の投稿などがこれに当たる。

POST /list HTTP/1.1
Host: example.jp
Content-Type: text/plain; charset=utf-8

こんにちは!
HTTP/1.1 201 Created
Content-Type: text/plain; charset=utf-8
LocationL http://example.jp/list/item5

こんにちは!

201 Createというステータスコードが返ってきたが、これは正常にリソースの作成が出来たことを示す。 Locationヘッダにその新しいリソースのURIが入っている。

リソースへのデータの追加

ログリソースの追加などがこれに当たる。

POST /log HTTP/1.1
Host: example.jp

2016-04-25T10:13:00Z, GET /log, 200
HTTP/1.1 200 OK

ここではPOSTのレスポンスとして、200が返ってきたが、これは、リソースの作成ではなく、データの追加であるから。 POSTがデータ作成を意味するか、データ追加を意味するかは実装に依存するため、WebAPIの仕様書などを調べる必要がある。

他のメソッドでは対応出来ない処理

URIの長さには実装上2000文字以内などの制約が入る場面がある。 そのような長いキーワードの場合、URIにキーワードを入れてGETする方法は利用出来ない。 この時に POSTを利用する。

POST /search HTTP/1.1
Content-Type: application/x-www-form-urlencoded

q=very+long+keyword+hogehogehogeo......

PUTメソッド

PUTは2つの役割が存在する。

リソースの更新

先ほどのPOSTの記事作成で作ったリソースの内容を更新する。

PUT /list/item5 HTTP/1.1
Host: example.jp
Content-Type: text/plain; charset=utf-8

こんばんは!
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8

こんばんは!

このように、PUTメソッドでは、元のリソースを更新するときに使う

リソースの作成

**http://example.jp/newitem**が存在してないものとする。

POST /newitem HTTP/1.1
Host: example.jp
Content-Type: text/plain; charset=utf-8

新しいリソース/newitemの内容
HTTP/1.1 201 Created
Content-Type: text/plain; charset=utf-8

新しいリソース/newitemの内容

PUTは存在しないURIへのリクエストのため、サーバはリソースを新しく作成すると解釈し、201 Createdを返す。 /newitemが存在していた場合は、更新として処理される。

POSTとPUTの使い分け

どちらも新しいリソースの作成を行えるが、それぞれの使い分ける指針として、 __リソースのURI決定権__が挙げられる。

POSTでリソースを作成する場合、URIの決定権は サーバ側にある。 なので、レスポンスヘッダー内でLocationとして返ってきた。 この動作の例としては、TwitterのようにUTIをサーバーが自動的に作成する場合が挙げられる。

PUTでリソースを作成する場合、 クライアントが決めたURIがそのままサーバ側で使用される。 なので、レスポンスヘッダー内でLocationとして返ってこない。 この動作の例としては、Wikiのようにクライアントが決めたタイトルがそのままURIになるものが挙げられる。

DELETEメソッド

名前の通りリソースの削除を行うメソッド。

DELETE /list/item2 HTTP/1.1
Host: example.jp
HTTP/1.1 200 OK

一般にDELETEのレスポンスはボディーを持たない。 そのため、ステータスコードにボディーがないという意味の204 No Contentが使われる場合がある。

POSTでPUT/DELETEを代用する

今現在、一番よく利用されているのが、GETとPOSTメソッドである。 HTMLのフォームで指定出来るのもこの2つだったが、技術の発展とともに、AjaxのXMLHttpRequestというモジュールを利用することで、任意のメソッドを発行できるようになった。 しかし、XMLHttpRequestをサポートしない携帯電話向けブラウザでは2つのメソッドしか利用出来ない。 また、プロキシサーバではPUTによって勝手にサーバーに関する情報をクライアントに追加させたり置き換えさせたりするため、セキュリティの問題で2つのメソッド以外のアクセスを制限する場合がある。

このような状況で、サーバにPUTやDELETEを伝えるためには、

  • _methodパラメータ
    • フォームの隠しパラメータに_methodというパラメータを入れる
    • その中に本来送りたかったメソッドの名前を入れる
    • Ruby on Railsが採用している
  • X-HTTP-Method-Overrde
    • XMLなどの場合に使用
    • X-HTTP-Method-Overrdeヘッダにメソッド名を指定することで、実現する
    • GoogleのGoogle Data Protocolが採用している

HEADメソッド

GETとよく似ていているが、GETはリソースを取得、HEADはリソースのヘッダ(メタデータ)のみを取得するメソッド。

HEAD /list/item1 HTTP/1.1
Host: example.jp
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8

先述した通り、ヘッダのみ返すため、HEADへのレスポンスにはボディーを含まない。 利用用途としては、ネットワークの帯域を節約しつつ、リソースの大きさや、更新日時を調べるために使う。

OPTIONS

OPTIONSでは、そのリソースがサポートしているメソッドの一覧を返す。

OPTIONS /list HTTP/1.1
Host: example.jp
HTTP/1.1 200 OK
Allow: GET, HEAD, POST
OPTIONS /list/item1 HTTP/1.1
Host: example.jp
HTTP/1.1 200 OK
Allow: GET, HEAD, PUT,DELETE

OPTIONS自体は、Allowヘッダには含めない。 使いみちがいまいち思いつかない。。。

べき等性と安全性

べき等とは「ある操作を何回行っても結果は同じという考え方」である。 数学の絶対値、0の乗算(3 * 0 = 0)などがあげられる。

また、安全性とは「捜査対象のリソースの状態を変化させないこと」を意味している。

これらをGET、POST、PUT、DELETE、HEADに当てはめると次のような図に分類出来る

安全性あり 安全性なし
べき等 GET、HEAD PUT、DELETE
べき等でない POST

GETとHEADについては、値を取ってくるだけなのでべき等かつ安全なのは自明である。 PUTとDELETEは値を更新や作成、削除する点から変化を与えるため安全性のみなし。しかし、何度やっても値は同じなのでべき等性はあり。 POSTは、リクエストの結果次第で何が起こるか分からないためべき等性はなし。更に、変化も与えるため安全性もなし。 POSTの例としては、通販サイトでのブラウザの戻るボタンを押してしまった時に2重注文のような問題が発生する可能性を示している。

### メソッドの誤用 先ほど、べき等性と安全性の対応表を出したが、全てがあの表に当てはまるとは限らない。 そのパターンについて述べる。

なお、これらのパターンは開発者の問題であることが多く、前述した図が基本と考えて良い

GETが安全でなくなる場合

GET: /resources/1/delete HTTP/1.1
Host: example.jp

このようにGETで要求しているにもかかわらず、example.jp/resources/1 を削除しようとするろ時、安全性がなくなる。

PUTがべき等でなくなる場合

価格の更新に対して、現在の価格の50%増加させるといったように、今の差分から処理を行う時 毎回結果が変わってくるため、べき等性がなくなる。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment