「Webを支える技術」を読みました(2)
勉強記録
今日は「Webを支える技術」を読んだので、重要そうなところを中心にまとめました。
ここでは第3部のHTTPについてまとめています。
<第3部> HTTP
HTTPの基本
インターネットのネットワークプロトコルは階層型になっている。
上から順にアプリケーション層、トランスポート層、インターネット層、ネットワークインターフェース層となっている。
HTTPではクライアントが出したリクエストをサーバーで処理してレスポンスを返す。
クライアントで行われること
クライアントでは、1つのリクエストを送信してレスポンスを受信するまで以下のような流れになっている。
1.リクエストメッセージの構築
2.リクエストメッセージの送信
3.レスポンスが返るまで待機
4.レスポンスメッセージの受信
5.レスポンスメッセージの解析
6.クライアントの目的を達成するための処理(ブラウザであればHTMLをレンダリングしてウィンドウに表示する処理など)
サーバで行われること
クライアントからリクエストを受けたサーバは以下の流れでレスポンスを送信する。
1.リクエストメッセージの受信
2.リクエストメッセージの解析
3.適切なアプリケーションプログラムへの処理の委譲
4.アプリケーションプログラムから結果を取得
5.レスポンスメッセージの構築
6.レスポンスメッセージの送信
リクエストメッセージ
リクエストライン、ヘッダ、ボディの構造になっている
レスポンスメッセージ
ステータスライン、ヘッダ、ボディの構造になっている
HTTPのステートレス性
ステートフルは、サーバがクライアントのそれまでの注文を覚えているから、やりとりが簡潔。
ステートレスは、クライアントが毎回すべての注文を繰り返しているから、やりとりが冗長。
ステートフルはやりとりが簡潔だけど、クライアントの数が増えたときにスケールアウトさせにくい。
ステートレスはサーバー側のシステムが単純。クライアントが増えたら、単純にサーバーを増設すれば良い。
ステートレスの欠点
パフォーマンスの低下、通信エラーへの対処(ネットワークトラブルが起きた時にリクエストが処理されたかどうかわからない)
HTTPメソッド
HTTPメソッドは8つ
-GET リソースの取得
-POST 子リソースの作成、リソースへのデータ追加
-PUT リソースの更新、リソースの作成
-DELETE リソースの削除
-HEAD リソースのヘッダの取得
-OPTIONS リソースがサポートしているメソッドの取得
-TRACE 自分宛にリクエストメッセージを返す(ループバック)試験
-CONNECT プロキシ動作のトンネル接続への変更
RESTはURIでリソースを表現している。HTTPメソッドで処理の内容(ふるまい)を表現している。
HTTPメソッドとCRUD
GET、POST、PUT、DELETEはCRUDを満たすための代表的なメソッド。
POSTとPUTの使い分け
POSTでもPUTでもリソースの作成ができる。
POSTでリソースを作成する場合、URIの決定権はサーバにある。
PUTでリソースを作成する場合、URIはクライアントが決定する。
特別な理由がない限り、リソースの作成はPOSTで行いURIもサーバ側で決定する。
POSTでPUT/DELETEを代用する方法
HTMLのフォームで指定できるメソッドはGETとPOSTのみ。
現在は、この制限も解消されつつあるが、それでもGETとPOSTのみしか使えない場合もある。
_methodパラメータを用いる方法や、X-HTTP-Method-Overrideヘッダなどを利用して、POSTでPUT/DELETEを代用できる。
条件付きリクエスト
HTTPメソッドと更新日時など、ヘッダを組み合わせることでメソッドを実行するかどうかを、リソースの更新日時を条件にサーバが選択できるようになる。
べき等性と安全性(重要!)
べき等とは「ある操作を何回やっても結果が同じこと」を意味する。
予期せず複数回処理が走ったときに、予期しない不具合によって障害に発展する可能性があるので、すべてのプログラムはべき等に設計すべきである。
GET、DELETE、PUTはべき等かつ安全である。POSTはべき等ではないので慎重に行わなければならない。
メソッドの誤用
GETでリソースを更新したり、削除したりするのは誤った使い方。
ほかのメソッドでは対応できない処理をPOSTはしてくれるが、ほかのメソッドでできることでもPOSTを使うのは間違っている。
PUTでリソース内容の相対的な差分を送信すると、PUTはべき等ではなくなってしまう。
エイリアスソースのような特殊なリソースは、特別な理由がない限り更新や削除などの操作ができないようにしないと、DELETEがべき等でなくなる。
ステータスコード
-1XX : 処理中
-2XX : 成功
-3XX : リダイレクト
-4XX : クライアントエラー
-5XX : サーバエラー
(よく使われるステータスコード)
200 OK : リクエスト成功
201 Created : リソースの作成成功
301 Moved Permanently : リソースの恒久的な移動
303 See Other : 別URIの参照
400 Bad Request : リクエストの間違い
401 Unauthorized : アクセス権不正
404 Not Found : リソースの不在
500 Internal Server Error : サーバ内部エラー
503 Service Unavailable : サービス停止
ステータスコードとエラー処理
4XX系と5XX系のステータスコードはどちらもエラーを表現している。
ボディにどんなメッセージを入れるかは規定していないので、エラー内容がわかりやいようにメッセージ入りのHTMLをボディに加えることが一般的。
ステータスコードの誤用
一部のWebサービスなどで、エラーを200 OKで返すことがあるがダメ。
HTTPヘッダ
認証やキャッシュなどのHTTPの機能は、ヘッダをメソッドやステータスコードと組み合わせて初めて実現できる。
主なヘッダについて
日時
値に日時を持つヘッダ。DateやExpires。
MIMEメディアタイプ
メッセージでやりとりするリソースの表現の種類を指定する。
Content-Typeヘッダはメディアタイプを指定、charsetパラメータは文字エンコーディングを指定。
言語タグ
リソース表現の自然言語を指定する。Content-Languageヘッダ。
コンテントネゴシエーション
Acceptヘッダで処理できるメディアタイプを伝える。Accept-Charsetで処理できる文字エンコーディングを伝える。Accept-Languageで処理できる言語を伝える。
Contet-Lengthとチャンク転送
Content-Lengthヘッダはボディの長さを指定する。Transfer-Encodingヘッダにchunkedを指定すると、最終的なサイズがわからないボディを少しずつ転送できるようになる。
認証
Basic認証とDigest認証がある。
Basic認証はHTTPが元々用意してくれている認証機能。ユーザー名とパスワードによる認証方法。
Digest認証は入力されたユーザーIDとパスワードをハッシュ関数を用いて、解析されにくい状態で送信する。
キャッシュ
キャッシュとは、サーバーから取得したリソースをハードディスクなどのローカルストレージに蓄積して、再利用する手法のこと。(クライアントキャッシュ)
削除方法はいろいろあって、macならcommand + shift + R
また、プライベートブラウザならキャッシュがない
持続的接続
Connectionヘッダにcloseという値を指定すれば、コネクションを切断できる。
そのほかのHTTPヘッダ
Content-Dispostion ファイル名を指定する
Slug ファイル名のヒントを指定する