技術研修で読み進めているWebを支える技術について、各章のまとめを順次上げていく。 前Webを支える技術6章 次
HTTPメソッドには8つの種類がある。
メソッド | 意味 |
---|---|
GET | リソースの取得 |
POST | 小リソースの作成、リソースへのデータの追加、その他処理 |
PUT | リソースの更新、リソースの作成 |
DELETE | リソースの削除 |
HEAD | リソースのヘッド(メタデータ)の取得 |
OPTION | リソースがサポートしているメソッドの取得 |
TRACE | 自分宛てにリクエスト・メッセージを返す(ループバック)試験 |
CONNECT | プロキシ動作のトンネル接続への変更 |
この8つのうちTRANCE
と````CONNECT```はあまり使われないため
現在のHTTTPはたった6種類のメソッドで表現されている。
以降、各メソッドについて見ていく。 また、ステータスコードについては、次の第8章で述べる。
各ヘッダの確認方法はGoogle Choromeの場合 この記事のレスポンスヘッダのコピーを参照
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メソッドでは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は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が存在していた場合は、更新として処理される。
どちらも新しいリソースの作成を行えるが、それぞれの使い分ける指針として、 __リソースのURI決定権__が挙げられる。
POSTでリソースを作成する場合、URIの決定権は サーバ側にある。 なので、レスポンスヘッダー内でLocationとして返ってきた。 この動作の例としては、TwitterのようにUTIをサーバーが自動的に作成する場合が挙げられる。
PUTでリソースを作成する場合、 クライアントが決めたURIがそのままサーバ側で使用される。 なので、レスポンスヘッダー内でLocationとして返ってこない。 この動作の例としては、Wikiのようにクライアントが決めたタイトルがそのままURIになるものが挙げられる。
名前の通りリソースの削除を行うメソッド。
DELETE /list/item2 HTTP/1.1
Host: example.jp
HTTP/1.1 200 OK
一般にDELETEのレスポンスはボディーを持たない。 そのため、ステータスコードにボディーがないという意味の204 No Contentが使われる場合がある。
今現在、一番よく利用されているのが、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が採用している
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 /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: /resources/1/delete HTTP/1.1
Host: example.jp
このようにGETで要求しているにもかかわらず、example.jp/resources/1 を削除しようとするろ時、安全性がなくなる。
価格の更新に対して、現在の価格の50%増加させるといったように、今の差分から処理を行う時 毎回結果が変わってくるため、べき等性がなくなる。