【読書メモ】「ネットワークはなぜつながるのか」No.1　HTTPリクエストを送り、レスポンスが返るまで

# はじめに
　 学習をする中で、Webページがどのように表示されるのか、リクエストを送りレスポンスを受け取るまで何が行われているのか理解が浅く言語化できないことに気づきました。
　そこでネットワークはなぜつながるのか」を読み学んだこと、気づいたことをまとめることで自身の理解を深めていきたいと思います。長い本なので何回かに分けてまとめていく予定です。同じような悩みを抱える初学者の参考にもなれば幸いです。
 **※本の内容全てを網羅しているわけではないのでその点ご注意ください**

 # Webブラウザがデータを取得し、表示するまでの流れ
 Webブラウザがデータを取得する一連の流れは簡単にまとめる以下のようになります

* HTTPリクエスト・メッセージを作成する
* WebサーバのIPアドレスをDNSサーバーに問い合わせる
* DNSから取得したIPアドレスをもとにリクエスト・メッセージを送信する
* サーバーから返却されたレスポンスを受信する

ざっくり言うとこのような形になります。

せっかくなので、前回使用したPokeAPIを題材に、これらの流れを見ていきたいと思います。

PokeAPIの記事はこちら

https://qiita.com/rikuya98/items/c2009cfacdd9f8a9e66d

### URLとは？
全てはURLを入力し解説するところから始まります。
それではPokeAPIのURLを見てみましょう。

```
https://pokeapi.co/api/v2/ability/pikachu/
```
このURLには様々な情報が含まれています。

```
https:
```
先頭の部分はプロトコルの種類が書かれています。
簡単に言うとアクセスする方法ですね。
Webサーバーにアクセスする場合は HTTPというプロトコルを使用するので
httpsと指定しています。この後ろのsは「セキュア」を表すようで。TLS（またはSSL）を使用してHTTPリクエストやレスポンスを暗号化する役割を持つようです。

プロトコルは他にも
```javascript
mailto:   //メールを送信する
ftp: //ファイルをダウンロードしたり、アップロードする
file: //自身のパソコンのファイルからデートを読み込む
```
等様々なものがあります。

それでは他の部分はそれぞれどういった意味があるのかURLを分解しながら見ていきます。
```
//pokeapi.co
```
この部分はWebサーバーの名前となります。
//　⇦　スラッシュ２つは、後に続く文字列がサーバーの名前であることを表してくれています。
```
/api/v2/ability/pikachu
```
こちらはファイルのパス名を表しています。データの所在地ですね。
つまり上記のURLを翻訳すると

**httpsっていうアクセス方法でpokeapi.coという名前のwebサーバーのapiフォルダ⇨v2フォルダ⇨abilityフォルダの中にあるpikachuという名前のファイルにアクセスしてね！**
という意味になります。

このようにURLを解析する役割もWebブラウザが担っています。

## HTTPのリクエスト・メッセージを作る
URLを解析し終わったら、リクエストメッセージを作っていきます。
リクエストメッセージの内容をGoogle Chromeのデベロッパツールで見てみます。
 **※一部のみ抜粋してます**
``` javascript
:authority:
pokeapi.co //webサーバーの名前
:method:
GET //HTTPのメソッド
:path:
/api/v2/pokemon/pikachu // 場所を指し示すURI(データの所在地）
:scheme:
https //プロトコルの種類
```
上記リクエスト・メッセージの中には
「何を」「どうして」欲しいのかが書かれています。
「何を」に相当するものが**URI**になります。
上記のpathの部分ですね。
「どうして」に相当するものが**メソッド**になります。
このメソッドを通してWebサーバにどのような動作をして欲しいのかを伝えます。
以下のようなものがあります。

| メソッド | 意味 |
| ------- | ---- |
| GET     | サーバーから情報を取得するために使用されます。 |
| POST    | サーバーに情報を送信し、リソースを作成するために使用されます。 |
| PUT     | サーバーの既存のリソースを更新するために使用されます。 |
| DELETE  | サーバーのリソースを削除するために使用されます。 |
| HEAD    | GETと同様ですが、レスポンスボディは含まれず、ヘッダー情報のみを取得します。 |
| CONNECT | プロキシ機能との接続を確立するために使用されます。 |
| OPTIONS | サーバーでサポートされているHTTPメソッドを調査するために使用されます。 |
| TRACE   | クライアントからサーバーへのルートを追跡するために使用されます。 |

これらの中でよく使うのがGETメソッドです。
Webサーバーにアクセスして、ページを読み出す際に使うがGETメソッドだからです。
今回もポケモンの情報を読み出したいので、GETが使われています。
次に使われるのがPOSTメソッドです。
例えばfromにデータを記入してWebサーバーに送信する場合に使用します。
POSTメソッドを使う場合は、URIにはWebサーバマシン内で動作するアプリケーションプログラムのファイル名を書きます。
そしてリクエストメッセージの中に、プログラムに渡すデータ、つまりユーザが入力した値のことです。そうしてサーバに届いたら、URIで指定したプログラムにメッセージを渡してDBに登録してもらったり、それを反映したり何かしらの処理を行うわけですね。

## リクエストを送るとレスポンスが返ってくる
そうして作成したHTTPのリクエスト・メッセージを送るとWebサーバーからレスポンス・メッセージが返ってきます。
リクエスト・メッセージとフォーマット等も基本的には同じなのですが、レスポンスにはリクエストの実行結果を表す
ステータスコードとレスポンスフレーズが含まれます。
ステータスコードはプログラムに実行結果を知らせるもので以下のような種類があります。
| コード値 | 説明 |
| ------- | ---- |
| 1xx     | 処理の経過状況などを通知する。|
| 2xx    | 正常終了 |
| 3xx     | 何らかの別アクションが必要であることを表す。 |
| 4xx  | クライアント側のエラー。 |
| 5xx  | サーバー側のエラー。|

そうして、レスポンスメッセージが返ってきたらそこからデータを取り出して画面上に表示します。
PokeAPIなどの場合は、JSON形式で返ってきます。
このような形式になります（一部抜粋）
```
 "name": "pikachu",
    "order": 35,
    "past_abilities": [],
    "past_types": [],
    "species": {
        "name": "pikachu",
        "url": "https://pokeapi.co/api/v2/pokemon-species/25/"
    }
```
これらをjavaScriptなどのプログラミング言語を用いて解析操作し、画面上に表示します。

通常は、HTML形式で返ってきます。
そしてブラウザがHTMLを解析します。その過程で、画像タグ(<img>など)が含まれている場合、ブラウザは自動的にそれらの画像のURLに対して別のHTTPリクエストを発行し、それらを取得します。
何故なら、一度のリクエストに対して１つしかURIを指定することができないからです。
そうして、全て取得し終えるまで、上記の工程を繰り返します。

以上がサーバーからデータを取得する大まかな流れとなります。

## DNSとは？
DNS(ドメインネームサーバ）の略です。
サーバにリクエストを送る際、実際に実行するのはブラウザではなくOSになります。
ブラウザはURLを解析した後にOSにリクエストの送信を依頼しています。
その際に、サーバの所在地を示すIPアドレスを知る必要があります。
IPアドレスはインターネット上の住所のようなものです。

https://ja.wikipedia.org/wiki/IP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9

URLに含まれるドメイン名からIPアドレスを知るための仕組みがDNSになります。

DNSには
ドメイン名に紐づく形でIPアドレスが管理されています。
DNSに対して「このドメイン名のIPアドレスを教えてください」と言うと教えてくれるような形になっています。

IPアドレスを探す機能はブラウザのSocketライブラリが提供してくれます。

SocketライブラリにはOSに組み込まれているネットワーク機能をアプリケーションから呼び出すための様々な機能が含まれており、その中の「リゾルバ」という機能がDNSからIPアドレスを取得してくれます。

ここでも、DNSへのリクエストメッセージを作成するのはリゾルバですが、実際に送信、受信を行うのはOSになります。

そうして返ってきたIPアドレスを元にサーバにリクエストを送ります。

## まとめ
まだ第１章しか読めてませんが、少しサーバーからデータを取得する流れの概要は掴めたように思います。
次回は、第２章のTCP/IPについてまとめていきます。