Webアプリケーションにおける通信の仕組み(1)

# はじめに
　Webアプリを初めて作成したので、そのまとめとしてWebアプリケーションでどのように通信が行われているのかをアウトプットしようと思い、この記事を投稿しました。

　今回のテーマとしては、Webアプリケーションにおけるクライアントとサーバ間の通信がどのように行われているかをアウトプットしていきたいと思います。間違っている事があるかもしれないので、その場合は指摘していただいて大丈夫です。

# Webアプリケーションってなんだ?
　そもそもWebアプリケーションとは、利用者(ユーザー)がインターネットを通して、ブラウザ(Webサーバーに接続するためのソフトウェア)で操作をするアプリケーションのことです。クライアント側ではアプリケーションのインストールをする事なく利用できたり、処理がサーバ側で行われるので、クライアント側は何もしなくても新しいサービスを受ける事ができるのが利点です。例えば、YoutubeやGmail、クックパッドなどが挙げられます。皆さんも一度は使った事があるのではないでしょうか。以下の図は、大まかにWebアプリケーションの通信をまとめたものです。

![スクリーンショット 2021-09-05 21.35.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1864916/decdb1b1-2057-d0c9-970f-33de250cb7e1.png)


　インターネットを利用する場合、サービスを利用する側とサービスを提供する側に分かれます。この時、サービスを利用するコンピュータをクライアント、提供するコンピュータをサーバと呼びます。このクライアントとサーバ間でHTTPによって通信を行います。
具体的には、クライアントからサーバへHTMLファイルを要求します。(HTTPリクエスト) サーバはリクエストに応じた処理を行い、クライアントに要求されたファイルを返答します。(HTTPレスポンス)

# HTTPリクエストとHTTPレスポンスでは何が行われているのか?
### HTTP通信とは?
　HTTP(HyperText Transfer Protocol)とは、**HTML(Hyper Text Markup Language)で書かれたファイルをやり取りするためのプロトコル(クライアントとサーバ間で通信する際の決まり事)**です。HTMLとは、Webページを記述するための言語です。一つのリクエストに対して一つのレスポンスを得ることで通信が完結します。

　また、HTTPはステートレス(過去の状態を保持しない)特徴を持っています。よって、過去の状態によりサーバの状態やクライアントのWebブラウザの状態などに影響を受けることはありません。

　では、以下の例をもとにHTTPリクエストとHTTPレスポンスでどんな情報が転送されているかを説明していきたいと思います。例として、クライアントがトップページを見たいと思い、localhost:3000にアクセスした場合を考えます。すると通信の順番は以下のようになります。**ここでは1番と3番の処理内容を説明することにします。**
1. リクエストをサーバに送信する。
2. リクエストに応じてサーバが処理する。
3. 処理結果をレスポンスとしてサーバに返送する。

## HTTPリクエストの中身
HTTPリクエストは、**クライアントがサーバに対してHTTPメソッド(GETやPOSTなどサーバにしてほしい操作)によりデータを送信し、要求すること**です。Webサーバにアクセスする際、TCP(通信したデータが相手に届いたかを確認しながら通信するやり方)のプロトコルでコネクションが確立されます。そして、その接続を用いてサーバへリクエストを送信します。リクエストを送信する際にフォーマットがあり、以下のような構造になっています。
![スクリーンショット 2021-09-05 21.42.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1864916/8c8c2137-1122-b8e6-7602-46ced77d6603.png)
ここでHTTPヘッダのHTTPリクエストをcurlコマンドを用いて取得してみます。

```bash
$ curl --http1.1 --get -v localhost:3000
```
以下がlocalhost:3000に対するHTTPヘッダの中身です。またHTTPリクエストの構造を表にまとめてみました。

```bash
 <リクエスト>
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.64.1
> Accept: */*
  (空行)
メッセージ本体
```

|  構造  |
| ---- |
|  リクエスト行  |
|  ヘッダー  |
|  空行  |
|  ボディ  |

　1行目はリクエスト行と呼ばれ、以下の形式で記述されます。メソッド名はGETやPOSTなどクライアントがサーバにして欲しい処理のことです。パス名は、スラッシュで始まるパス名(/homeなど)やURLで指定します。
　　　　　　　　　　メソッド名 パス名 HTTP/バージョン

　2行目以降はHTTPヘッダーフィールドと呼ばれ、クライアントやサーバがHTTPリクエストやレスポンスで追加情報を渡す事が出来ます。今回は、ここで記述されているフィールド名を説明します。他にもありますが、興味がある方は調べてみてください。

- Host:リクエスト先サーバ名、DNS名を利用
- User-Agent:ユーザが利用しているブラウザの種類やOSの情報を表示
- Accept:受け取り希望のデータの種類をサーバに通知

　空行はスキップします。
　空行の次の行からはメッセージ本体(ボディ)を指します。GETメソッドでは何も表示されませんが、POSTメソッドだと表示されます。
　以上がHTTPリクエストの中身です。次は、HTTPレスポンスの中身を見ていきます。

## HTTPレスポンスの中身
HTTPレスポンスは、**クライアントから送信されたデータをサーバが処理をして、クライアントに返信する返答**のことです。
以下がcurlにより取得したレスポンスの内容です。また、HTTPレスポンスの構造を表にまとめました。


```bash
    <レスポンス>
---レスポンス行---
< HTTP/1.1 200 OK

---ヘッダー---
< X-Frame-Options: SAMEORIGIN
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Download-Options: noopen
< X-Permitted-Cross-Domain-Policies: none
< Referrer-Policy: strict-origin-when-cross-origin
< Link: </assets/application.debug-705e2a3e9fc0114537e86eb4d20ae47c29de848ecebf09d9773173807f673ee5.css>; rel=preload; as=style; nopush,</packs/js/application-0e1984c70fd0ed370407.js>; rel=preload; as=script; nopush
< Content-Type: text/html; charset=utf-8
< Vary: Accept
< Cache-Control: no-store, must-revalidate, private, max-age=0
< Set-Cookie: _todo_app_session=nn%2FtuslnP%2FNP%2FDZqCa1J2WtzGow%2BQqm9O1GpCjumVHkslbj3MaPiFq1ZtAHXhDdH4MMqY%2BFP7kRz647QgCKgHyMQf%2FAzz%2FUdANFFQE%2BU%2FQIKtRVZwsNEi%2Bz1y3rfWrDx2DY2PGUsjYpNomF83JvvcvxhFWpaTgT%2FvgTnp7nUle9XYyz1NpmEzZ18Ji%2FCIMAvcfgEWmxcs%2FTUBKjG6nzqNcw3RAtdlWG7ONlpEEV2OsB1vXhVvJi6adLgdC%2FqGxp5yoPqokDkjqpWB1gXP%2F9LMFKszs2UEfeEKQ%3D%3D--bCqhciglRWP5Lhiu--bPj%2FMf5BXl0TnMKniuoGSw%3D%3D; path=/; HttpOnly; SameSite=Lax
< Set-Cookie: __profilin=p%3Dt; path=/; HttpOnly; SameSite=Lax
< X-Request-Id: c9bd0961-b67c-4769-8f49-3eb079a2e31b
< X-Runtime: 0.198644
< X-MiniProfiler-Original-Cache-Control: max-age=0, private, must-revalidate
< X-MiniProfiler-Ids: a2pn01i7y1ns72kmfi94,mi05m1l53ncl594wmw2z,l3cj5g9bz1o9tt437s18,cfqallle4eona8tc1upx,tzyvlhk3he5wmabxohat
< Content-Length: 4642
   (空行)
---ボディ---
<!DOCTYPE html>
```

|  構造  |
| ---- |
|  リクエスト行  |
|  ヘッダー  |
|  空行  |
|  ボディ  |

　リクエスト行では、HTTPリクエストの結果が記述されています。200 OKはリクエストが正常に処理できたことを意味します。
　ヘッダーは、データ本体の前に送られてくる各種状態を示す情報が入っている部分です。一部のフィールド名と内容を紹介します。

- Date:現在の日付
- Content-Type:出力のMIMEタイプ
- Set-cookie:データをクライアント側に保存する。
- Server:webサーバの名前とバージョン情報
- Content-Length:出力のバイト単位の長さ

　ボディには、HTMLや画像、動画などの実際表示するコンテンツ自身が入ってます。以上がHTTPレスポンスの中身です。

# 最後に
　ここまでをまとめると、WebアプリケーションはHTTP通信で行われ、クライアントとサーバによって成立します。クライアントがサーバに対してHTTPリクエストを送信して、受け取ったリクエストをもとにサーバ側で処理を行い、処理結果をHTTPレスポンスとしてクライアントに返信することで、通信が成立します。リクエストとレスポンスの中身は上記で説明した通りです。
　今回は、Webアプリケーションにおいて、クライアントとサーバ間の通信を説明しました。次回は、実際に作成したコードをもとに、サーバ側の処理内容をMVCモデルとともに説明していきたいと思います。

# 参考資料
https://qiita.com/koheiyamaguchi0203/items/5777c4653a01ae4c7b06#初めに

https://www.itmanage.co.jp/column/http-www-request-response-statuscode/#anc002