6章 HTTPの基本

<h3>6.1 HTTPとは?</h3>
HTTPは、ハイパーコンテキストの転送用のプロトコル。
データを送信する役割を持つもの。
特徴は以下
●ステートレステキスト
●RESTと言われる統一インターフェーイス
● キャッシュ

<h3>6.2 TCP/IPとは</h3>
TCP
IP
これらは、ネットプロトコルである。
ネットプロトコルは階層型プロトコル　になっている。
層ごとに抽象化していけば、下位層の具体的な状況に詐取することなく、上位層を実現できる。

●ネットワークインターフェイス層
物理的なケーブルやネットワークアダプターに相当する。

●インターネット層
こちらでは　、データを送信する層である。TCP/IPでは、IPが担当する。
IPという送り先にパケットと呼ばれる通信単位でデータをやり取りして通信する層である。
※IPでは、自身のネットワークインタフェースでデータを送り出すことだけを保証している。

複数のデータが、多数のネットワークを経由して最終的な送り先に届くことは保証していない。

●トランスポート層
トランスポート層では、インターネット層が保証しなかった、「送り先へ届ける確実な保証」を担う。
接続先に対して、コネクションを張る。コネクションを使って、データ　の抜け漏れをチェックし、
**データの到達**を保証する。

TCPで接続したコネクションで転送するデータが、どのアプリケーションに渡るのか、決定づけるのが**ポート番号**である。
※HTTPデフォルト時は、80番ポートである。

●アプリケーション層
アプリケーション層では、インターネットやメール、HTTPなどがある。
TCPでプログラムを扱う場合は、実際ソケットと呼ばれるライブラリを使う。
ソケットは接続するAPIで役割が、「接続」、「切断」、「送信」、「受信」がある。
HTTPブラウザは、一般的にソケットを使うのが一般的である。
ほとんどんのプログラミング言語では、デフォルトでHTTPを実装したライブラリがついているため、　ソケットを使った独自のHTTPを実装することはない。
しかし、WebAPIなど、フレームワークにおいて**細かな設定**、プロトコルがどのような影響を与えるかについては、*把握する必要がある。*

<h3>6.3 HTTPの歴史 (HTTPバージョン)</h3>
簡潔に話すが、HTTP1.1が現在使われている。その前のHTTP versionにおいては
「チャンク転送」、「Accept Headerによるネゴシーエーション」、「複雑なキャッシュコントロール」、「持続的な接続」などはなかった。HTTP1.1から、新たに加わった機能である。

その後、さまざまな議論がなされてきたが、現在まで HTTP1.1のままで変わっていないようである。

<h3>6.4 クライアントとサーバ</h3>
クライアントとサーバの関係性は言うまでもなく、「クライアントがサーバに対してリクエストを送り、」サーバがリクエストを受け取って、レスポンスを返す。
HTTP1.1では、ここに新たな**ユーザエージェント**が追加された。
ユーザエージェントは、「サーバに　対して、具体的なリクエストを発行する役割を持つ」。
※ Webを支える技術に関して言えば、「　そこまで区分することはなさそうである。」

<h3>6.5　リクエストとレスポンス</h3>
クライアントはリクエストを送り、サーバは、リクエストを返す、役割である。
クライアントは、リクエストを送り、サーバはリクエストをたいきする。

それが一般的である。
しかし、そのほかにもまだ種類がある。

◆<h4>クライアントで行われていること</h4>
クライアントは以下の役割を担う。

●リクエストメッセージの構築
●リクエストメッセージの送信
●(レスポンスがかえるまでたいき)
●レスポンスメッセージの受信
●レスポンスメッセージの解析
●クライアントの目的を達成するために必要な処理「



◆<h4>サーバで行われていること</h4>
サーバは以下の役割を担う。

●リクエストの待機
●リクエストメッセージ受信
●リクエストメッセージの解析
●適切なアプリケーションプログラムへの処理の移譲
●アプリケーションプログラムから結果を取得
●レスポンスメッセージの構築
●レスポンスメッセージの送信

<h3>6.6 HTTPメッセージ</h3>
HTTPメッセージは、「リクエストメッセージ」と「レスポンスメッセージ」がある。

<h4>リクエストメッセージ</h4>
リクエストメッセージは最小限のものは次のようなものです。

| -------- | ----------- | --- | 
| GET/test | HTTP 1.1    |     | 
| Host     | example.com |     | 

1行目は「リクエストライン」と呼ばれる。
メソッド、リクエストURI、プロトコルバージョン。
リクエストURIに対して、行いたい処理を明記する、


<h4>レスポンスメッセージ</h4>
レスポンスメッセージは基本的には以下です。

| ----------------------------- | ------------------------------------ | --- | 
| HTTP/1,1                      | 200 OK                               |     | 
| Content-type                  | application/xml+html; charset:=utf-8 |     | 
| <html xmln="〜〜〜〜"></html> |                                      |     | 

レスポンス1行目は、HTTPバージョンとステータスラインとテキストフレーズである。
リクエストはステートライン。200や３００,400, 500番だいなどを表記される。

2行目は、レスポンスタイプが表記される。
HTMLのMINEメディアタイプとその文字エンコーディングが表記される。

レスポンスメッセージには、ボディとレスポンスが空行で区切られます。

:::note
<h4>HTTPメッセージの構成要素</h4>
HTTP目セージの構造を整理すると、以下の図のようになる。

1行目・・・・スタートライン。スタートラインは、リクエストメッセージの場合はリクエストライン、レスポンスメッセージの場合は、ステータスラインである。

２行目・・・・ヘッダ。ヘッダの各行は、改行はCRLF。ヘッダの終了は空行で識別する。ヘッダは省略可能である。

３行目・・・・ボディ。ボディにはテキストだけでなく、バイナリーデータも入るボディも省略可能である。

<図解>
```mermaid
graph LR
    style rect fill:#fff,stroke:#000,stroke-width:2px
    subgraph rect
        style Box1 fill:#fff,stroke:#f00,stroke-width:2px
        style Box2 fill:#fff,stroke:#00f,stroke-width:2px
        style Box3 fill:#fff,stroke:#ff0,stroke-width:2px
        style Box4 fill:#fff,stroke:#0f0,stroke-width:2px

        Box1[スタートライン]
        Box2[ヘッダ]
        Box3[空行]
        Box4[ボディ]
        
        Box1 --> Box2
        Box2 --> Box3
        Box3 --> Box4
    end
```
:::
6.7 HTTPステートレス

HTTPは、ステートレスな状態である。ステートレスとは、「サーバがクライアントのアプリケーション状態を保持しないことである」。

<h4>アプリケーションの状態</h4>
ステートレスなやり取りでは、クライアントがサーバに対して毎回同じリクエストを繰り返さなければならない。一方で、ステートフルなやり取りでは、リクエストの差分のみ追加で説明すれば良い。ステートフルなやり取りでは、サーバがクライアントのやり取りをずっとおぼえていることを前提としている。リクエストのクライアントの情報を「アプリケーション状態」と呼ぶ。

<h4>ステートフルの欠点</h4>
サーバがクライアントのアプリケーション状態を覚えることは、クライアントの数が増えるに従って、難しくなる。1つのサーバが同時に相手できるクライアントの数には上限がある。

:::note info
クライアントごとに、相手をするサーバを1つに決められればいいのですが
不特定多数のクライアントを相手にする場合はクライアントごとに接続するサーバを特定できません。従って、複数のサーバ間でアプリケーション状態を扱えるようにしなければならない。
しかし例えば、2台のサーバ間でアプリケーション状態を**複製できたとしても**、3台, 4台...100台と増えていくと、データを同期する**オーバーヘッド**が無視できなくなる。
このように、ステートフルなアーキテクチャでは、*クライアントの数が*増えた場合にスケールアウトさせにくくなる。
:::


<h4>ステートレスなメリット</h4>
この問題を解決するのが、「ステートレスなアーキテクチャ」である。
ステートレスでは**クライアントがリクエストメッセージに必要な情報を全て含める。**
サーバは過去のやり取り、つまりリクエストを覚えていなくても、リクエストを理解することができる。
 このようにそのリクエスト処理に**必要な情報がすべて含まれているメッセージ**を「自己記述的メッセージ」と呼ぶ。　ステートレスなアーキテクチャでは、*サーバがクライアントのアプリケーション状態を覚える代わりに*、クライアントが自らのアプリケーション状態を覚え、全てのリクエストを自己記述的メッセージで送信する。

<h4>ステートレスの欠点</h4>
ステートレスなアーキテクチャはスケーラビリティの面で大きな威力を発揮するが、デメリットもある。

    <h5>パフォーマンスの低下</h5>
サーバをステートレスにするためには、クライアントは毎回必要な情報を全て送信しなければならない。これは、パフォーマンスに影響を与える。
    理由
    1.  送信すると、データ量が多くなる。
    2.  認証など、サーバに負荷がかかる処理を繰り返す。
    
これは、自己記述的なメッセージはどうしても冗長になる。ステートフルな例では前回のメッセージとの差分でよかったが、ステートレスでは全ての情報を送りなおす必要がある。従って、**データ量によってはネットワーク帯域を消費することを意味する
    
また、認証処理などによるサーバ負荷の問題もある。認証処理の実装方法にもよるが、例えばデータベースにユーザ情報とPWが入っている場合、認証をするたびにデータベースへアクセスする必要がある。
    一般にデータベースへのアクセスは重い処理なので、これを毎回繰り返すとパフォーマンスが落ちる。