HTTPのまとめ 〜備忘録〜

# はじめに

未経験からWebエンジニアとして転職することが決まったため、WebとHTTPの基礎についてまとめます。
業務でこのあたりの知識の理解で困ったら振り返られるようにという目的で作成しています。

# HTTPの基本的な仕組み

まず、HTTP とは、HyperText Transfer Protcolの略称で、WebブラウザやWebサーバ間でデータを転送するためのプロトコルです。

HTTPによって、Webページの表示や、ファイルのダウンロードが可能になっています。  
それでは HTTP の基本的な仕組みについて説明します。

###  1. HTTPリクエスト と HTTPレスポンス

HTTPは、クライアントとサーバー間で「リクエスト」と「レスポンス」のやりとりを行います。

:::note info
クライアントはWebページを表示するために、Webサーバーに「リクエスト」を送信します。
:::

HTTPリクエストとしては「リクエスト行」「メッセージヘッダー」「メッセージボディ」の3つで構成されます。

<dl>
  <dt>リクエスト行</dt>
  <dd>Webサーバに対してどのような処理をして欲しいかというリクエストの要求内容を記述しています。
情報を取得したい/情報を送信したいといった情報をWebサーバへ伝えます。</dd>
  <dt>メッセージヘッダー</dt>
  <dd>Webブラウザの種類やバージョン、対応するデータ形式など付加的な情報を記述しています。</dd>
  <dt>メッセージボディ</dt>
  <dd>Webページ内のフォーム欄などに入力したテキストデータなどをWebサーバに送る目的で使用されます。</dd>
</dl>

:::note info
Webサーバーは、クライアントから送られたリクエストに対して、必要なデータを含んだ「レスポンス」を返します。
:::


HTTPレスポンスとしては「ステータス行」「メッセージヘッダー」「メッセージボディ」の3つで構成されます。


<dl>
  <dt>ステータス行</dt>
  <dd>Webブラウザから受け取ったHTTPリクエストに対して、Webサーバないでの処理の結果を伝える役割。</dd>
  <dt>メッセージヘッダー</dt>
  <dd>Webサーバの種類や、送信するデータの形式などの付加的な情報が記述されている。</dd>
  <dt>メッセージボディ</dt>
  <dd>WebブラウザからリクエストされたHTMLなどのデータが格納されます</dd>
</dl>

これらのHTTPリクエストとHTTPレスポンスのやりとりを繰り返し行うことで、わたしたちはWebサイトを閲覧できています。

###  2. HTTPメソッド

**HTTPメソッド**は、リクエストが何を行いたいのかをサーバーに伝えるものです。

よく利用するメソッドとしては以下のようなものがあります。

| メソッド | 意味 |
| ------ | ------- |
| GET | データを取得するためのメソッド |
| POST | 新しいデータを送信するためのメソッド |
| PUT | 既存のデータを更新するためのメソッド |
| PATCH | 既存のデータの一部を更新するためのメソッド |
| DELETE | データを削除するためのメソッド |

Webアプリケーションの開発においては前提知識になるので、メソッドごとの違いを抑えておく必要があります。

<details><summary>Q. GETでもデータを新規登録ができるが、POSTメソッドを使うべき理由は?</summary>


```markdown
GETメソッドを用いても、確かにデータの新規登録はできます。
しかし、本来の使用目的はデータを取得することです。

GETメソッドではURLのクエリパラメータにデータを含めて送信します。
クエリパラメータにデータが含まれると、URLがブラウザの履歴やキャッシュに保存される可能性があります。
ブラウザのURLバーにデータが表示されるため、セキュリティ上の問題が発生する場合があります。

一方、POSTメソッドはリクエストボディにデータを含めて送信します。
リクエストボディにデータが含まれると、URLにはデータが表示されず、ブラウザの履歴やキャッシュにも保存されません。

これらの違いから、新規登録時にはPOSTメソッドを使うことが一般的です。
POSTメソッドを使用することで、リクエストボディにデータが含まれるため、よりセキュアな通信が実現できます。
```
</details>

<details><summary>Q. POSTとPUTメソッドの違いは？</summary>

```markdown
POSTメソッドは、リソースを新規作成するために使用されます。

POSTメソッドでは、リクエストされたデータが新しいリソースであることを示す必要があり、
リクエストボディに含まれるデータをリソースとしてサーバーに送信することによって新しいリソースを作成します。

POSTメソッドは、サーバー側で新しいリソースを作成し、そのリソースのURIをクライアントに返す。

一方、PUTメソッドは、既存のリソースを更新するために使用されます。

PUTメソッドでは、リクエストされたデータが更新するリソースであることを示す必要があり、
リクエストボディに含まれるデータを既存のリソースとしてサーバーに送信することによって既存のリソースを更新します。

PUTメソッドは、クライアントが指定したURIに対して、リクエストボディに含まれるデータを使用して既存のリソースを更新する。

POSTとPUTは使用目的が異なるため、実際の処理内容にあわせて、選択する必要があります。
```
</details>

<details><summary>Q. PUTとPATCHメソッドの違いは？</summary>


```markdown
PUTメソッドは、完全なリソースを更新するために使用され、リソース全体を置き換えることができます。

PUTメソッドは、リクエストされたデータが更新するリソース全体であることを示す必要があり、
リクエストボディに含まれるデータでリソース全体を置き換えます。

リクエストされたリソース全体をサーバーに送信し、既存のリソースを完全に置き換えます。

PATCHメソッドは、リソースの一部分だけを更新するために使用され、リソースの特定の部分だけを変更することができます。

PATCHメソッドは、リクエストされたデータが更新するリソースの一部分であることを示す必要があり、リクエストボディに含まれるデータでリソースの特定の部分だけを変更します。

リクエストされたデータに基づいて、リソースの一部分だけを更新します。
```
</details>

:::note warn
HTTPメソッドの使い方は正しく理解することが重要です。
メソッド間の違いに悩んだ時はMDNなどで確認しましょう。
:::

###  3. HTTPステータスコード

HTTPステータスコードは、Webサーバーが処理した結果を表す3桁の数字で、以下のような種類があります。

| ステータスコード | 意味 |
| ------ | ------- |
| 1xx | 情報レスポンス |
| 2xx | 成功レスポンス |
| 3xx | リダイレクト |
| 4xx | クライアントエラー |
| 5xx | サーバーエラー |

HTTPステータスコードは、Webページの表示においても重要な役割を担っています。
ステータスコードの内容を糸口にトラブルシューティングを行うこともあります。

なお、1xx台のステータスコードはWeb開発の現場で利用されることはあまりないため、
2xx台以降のステータスコードでよく利用するものを説明します。

<details><summary>2xx Success</summary>

- 200 OK 
リクエストが成功したことを示します。通常は、リクエストされた情報が正常に返されたことを示します。例えば、ウェブサイト上のページが正常に表示された場合などに使用されます。

- 204 No Content
リクエストが成功したことを示しますが、レスポンスには本文が含まれていないことを示します。通常は、情報の更新が成功した場合などに使用されます。

</details>


<details><summary>3xx Redirection</summary>

- 301 Moved Permanently
リクエストされたリソースが恒久的に移動したことを示します。通常は、リダイレクト先のURLがレスポンスに含まれます。
例えば、ウェブサイトのURLが変更された場合などに使用されます。

- 302 Found
リクエストされたリソースが一時的に移動したことを示します。通常は、リダイレクト先のURLがレスポンスに含まれます。
例えば、ウェブサイトの一時的なメンテナンス中に、代替のページにリダイレクトする場合などに使用されます。

</details>


<details><summary>4xx Client Error</summary>

- 400 Bad Request
リクエストが無効であることを示します。通常は、リクエストに誤りがある場合などに使用されます。
例えば、リクエストされたパラメータが不足している場合などに使用されます。

- 404 Not Found
リクエストされたリソースが存在しないことを示します。
通常は、リクエストされたURLが無効である場合などに使用されます。
</details>


<details><summary>5xx Server Error</summary>

- 500 Internal Server Error
サーバー側でエラーが発生したことを示します。
通常は、サーバー側で予期しない問題が発生した場合に使用されます。

- 503 Service Unavailable
リクエストされたリソースが一時的に利用できないことを示します。
通常は、サーバーの過負荷やメンテナンス中に使用されます。
</details>

:::note info
HTTPステータスコードは、Webアプリケーション開発において非常に重要な役割を担っています。
Webアプリケーションを開発する際には、各ステータスコードについて十分に理解しておきましょう。
:::

###  4. HTTPヘッダー

HTTPリクエストとレスポンスには、「HTTPヘッダー」と呼ばれるメタデータが含まれます。
HTTPヘッダーは、リクエストやレスポンスのメタデータを指定するために使用されるものです。

代表的なHTTPヘッダーと役割は以下へ記載します。

| HTTPヘッダー | 役割 |
| ------ | ------- |
| Accept | リクエストがどの種類のレスポンスを受け入れることができるかを指定します。 |
| Content-Type | リクエストまたはレスポンスの本文のMIMEタイプを定義します。 |
| User-Agent | リクエストを送信するクライアントの情報を識別するために使用されます。 |
| Cookie | サーバーに保存されているクライアントの状態を追跡するために使用されます。 |
| Set-Cookie | クライアントに保存されるCookieを定義するために使用されます。 |

たとえば、Content-Typeヘッダーは、レスポンスに含まれるコンテンツの種類を指定するために使用され、
Webアプリケーションの開発においてよく利用します。

Content-typeは、HTTPヘッダーの1つで、ウェブサイトで送信されるデータの種類を示します。

具体的には、ウェブページで使用されるファイルの種類を指定するために使用されます。

例えば、HTMLファイルのContent-typeは「text/html」、画像のContent-typeは「image/jpeg」または「image/png」です。
なお、JSONをクライアントとサーバー間で通信する場合には、Content-typeとして「application/json」を使用します。これは、送信されるデータがJSON形式であることを示します。

:::note info
JSONは、現代のWeb開発において非常に一般的なフォーマットであり、APIの開発やデータの交換などに広く使用されています。
:::

Content-typeが適切に設定されていない場合、ブラウザはデータを正しく処理できず、正しく表示されないことがあります。ウェブ開発者はContent-typeを正確に設定することが重要です。

### 5. HTTPキャッシュ

HTTPのキャッシュを利用すると、クライアントや中間キャッシュ（プロキシサーバーなど）がリソース（画像、HTML、JavaScriptなど）を保持することで、
同じリソースに対するリクエストがあった場合にサーバーにアクセスする必要を減らし、通信量を削減することができます。

HTTPのキャッシュには、次のような仕組みがあります。

<dl>
  <dt>キャッシュ制御用のヘッダー</dt>
  <dd>HTTPリクエストやレスポンスのヘッダーにCache-Control、Expires、Pragmaなどのヘッダーを含めることで、キャッシュの動作を制御できます。たとえば、Cache-Control: max-age=3600というヘッダーを含めることで、リソースが1時間キャッシュされるように指定できます。</dd>
  <dt>ETag</dt>
  <dd>サーバーがリソースを生成した際に付与するハッシュ値で、クライアントがリソースをキャッシュする際に、サーバーに問い合わせてキャッシュが最新かどうかを確認するために利用されます。</dd>
  <dt>Last-Modified</dt>
  <dd>リソースが最後に変更された日時を表すヘッダーで、クライアントがリソースをキャッシュする際に、サーバーに問い合わせてキャッシュが最新かどうかを確認するために利用されます。</dd>
  <dt>ブラウザキャッシュ</dt>
  <dd>ブラウザによるキャッシュ。たとえば、一度アクセスしたページや画像は、ブラウザのキャッシュに保存され、次回アクセスしたときにキャッシュから読み込まれます。ただし、キャッシュを無効化する設定もできます。</dd>
</dl>

HTTPキャッシュは、通信量の削減や応答速度の向上など、Webアプリケーションのパフォーマンス向上に役立ちます。

:::note warn
キャッシュの利用によって古い情報が表示されたり、更新が反映されなかったりすることがあるため、キャッシュの制御には注意が必要になります。
:::

###  6. HTTPS

HTTPSは、HTTPのセキュアなバージョンです。

データの暗号化やデータの改ざん防止に使用され、Webサイトの訪問者の個人情報や機密情報が保護されます。

以下のような仕組みで実現しています。
今回はそれぞれの詳細までは記載しませんが、仕組みの概要を抑えておくと良いでしょう。

<dl>
  <dt>SSL/TLSによる暗号化通信</dt>
  <dd>HTTPSでは、SSL（Secure Sockets Layer）またはTLS（Transport Layer Security）と呼ばれるプロトコルを使用して、通信内容を暗号化します。
この暗号化により、通信経路を傍受された場合でも通信内容が盗聴されることを防止することができます。</dd>
  <dt>証明書によるサーバー認証</dt>
  <dd>HTTPSでは、Webサーバーが信頼できるものであることを確認するため、証明書を使用してサーバー認証を行います。
証明書は、Webサーバーが第三者機関から発行を受けたもので、Webサーバーの識別情報や公開鍵などが含まれています。クライアントは、Webサーバーが信頼できる証明書を持っていることを確認することで、サーバーが偽装されていないことを確認できます。</dd>
</dl>

これらの仕組みにより、HTTPSでは通信内容が暗号化され、サーバーが偽装されていないことが確認できるため、よりセキュアな通信を実現することができます。

###  7. Cookie と セッション と キャッシュ

**Cookie**は、Webサイトの訪問者のデバイスに保存される小さなテキストファイルで、Webサイトをよりパーソナライズするために使用されます。Webサイトが訪問者のデバイスにCookieを保存すると、次回訪問したときに、Webサイトは訪問者の情報を自動的に読み取り、以前の訪問からの設定や状態を復元することができます。

なお、Cookieは、サーバーから送信された小さなデータの塊で、ブラウザに保存されます。その際にはユーザーのIDや設定、閲覧履歴などの情報が含まれることがあります。

**セッション**は、Webサイトの訪問者の情報を保持するために使用される仕組みです。サーバー側で管理されるユーザーの状態を保存することができます。

セッションは、Cookieを使用して設定される一時的な識別子で、訪問者がWebサイトにアクセスしている間、セッションが維持されます。ブラウザがサーバーにリクエストを送信するたびに、サーバーが一時的にデータ（ユーザーのIDや設定、状態などの情報が含まれる）を保存します。

:::note warn
セッションはブラウザが閉じられるか、一定期間アクセスがない場合に自動的に破棄されます。
:::

Cookieやセッションはウェブアプリケーションにおけるユーザー認証や状態管理に使用されます。
使い方や目的が異なるので正しく理解しておくことが必要です。

**キャッシュ**は、Webサイトのパフォーマンスを向上させるために使用されます。Webサイトは、ユーザーがアクセスしたページの情報をキャッシュに保存し、次回以降のアクセス時に再利用することができます。これにより、サイトの読み込み速度が向上し、ユーザーエクスペリエンスが向上します。

:::note alert
Cookieとセッションとキャッシュは似ているようで全く違います
:::

### 8. ステートフル と ステートレス  

ステートフルとステートレスは、コンピューターシステムにおいて、どのように状態を管理するかを示す用語です。

**ステートフル(stateful)** なシステムは、前回の「状態」を覚えています。
クライアントとの通信の際に必要な情報を保持し、クライアントの状態に応じた動作を行います。

**ステートレス(stateless)** なシステムは、前回の「状態」を保持せず、各リクエストが独立して処理されます。
ステートレスなシステムでは、各リクエストが独立しているため、冪等性(べきとうせい)を持たせることで、システムの信頼性を高めることができます。

HTTPはステートレスなプロトコルであり、サーバーはクライアントの過去のリクエストについて何も知らないため、
各リクエストは独立しています。

これにより、Webアプリケーションがスケーラブルになり、より多くのリクエストを処理できるようになります。

一方、ステートフルなアプリケーションでは、サーバーはクライアントの過去の状態を保持し、クライアントがアプリケーション内で移動している場合でも、同じ状態を保持します。

これにより、より複雑なアプリケーションを実装できますが、スケーラビリティに制限があります。
なぜなら、各リクエストが前の状態に依存するため、サーバーは各クライアントの状態を保持する必要があるためです。

このようなアプリケーションでは、ロードバランサーやセッションマネージャーなどの追加のインフラストラクチャが必要になる場合があります。

なお、ここ最近では、クライアント側で状態(ステート)を管理することができるようになりました。
これを可能にした技術としては、ReactやVue.jsなどのフロントエンドフレームワークがあります。

これらのフレームワークでは、コンポーネントの状態を管理することができ、ユーザーのアクションに応じて動的に変更することができます。

クライアント側で状態を管理することにより、ステートレスなアプリケーションでも、より複雑な機能を実現することができます。

### 9. URLとURI

URLとURIは似ていますが、厳密には異なる概念です。

**URL（Uniform Resource Locator）** は、Web上のリソース（Webページ、画像、ファイルなど）を識別するための一種のURIです。
URLは、通常、プロトコル（http、https、ftpなど）、ドメイン名、ポート番号、パス、クエリストリング、フラグメント識別子などから構成されます。

たとえば、次のURLは、GoogleのWebページを識別します。

```
https://www.google.com/
```

**URI（Uniform Resource Identifier）** は、インターネット上のあらゆるリソースを識別するための識別子です。URIは、URLとURNの2つのサブタイプに分かれます。

**URN（Uniform Resource Name）** は、URIのもう一つのサブタイプであり、特定のリソースの名前を表す識別子です。URNは、特定のドメイン名やパスを含める必要はありません。
しかし、URNは必ずしも全てのリソースへ定義されているものではないことに注意しておきましょう。

URNの代表例は 書籍を特定するための、ISBNコードです。

Google.comはWebサイトであるため、URLで識別されます。
したがって、Google.comのURIは、そのWebサイトを表すために使用されるURLによって表されることになります。

したがって、URLはWeb上のリソースを識別するための一種のURIですが、URNはリソースの名前を表す識別子であり、そのリソースの場所を表すために別のメカニズムが必要になります。

HTTPとURLの関係性は現時点で以下の理解をしておけば、今のところは充分です。

```
http://www.test.example.com/test.html

# http: → HTTPを使ってアクセスする
# www.test.example.com: → www.test.example.com というWebサーバにアクセス
# test.html という名前のコンテンツを要求する
```

### 10.  RESTful API

RESTfulとは「RESTの原則」を守っていることを示す言葉です。

そもそも、**REST（Representational State Transfer）** は、Webサービスを設計するためのアーキテクチャスタイルの1つで、HTTPプロトコルを使用してリソースを操作するAPIを作成することを目的としています。

RESTful APIは、このRESTアーキテクチャスタイルに従って設計されたAPIのことを指します。
言い換えると、RESTful APIの場合はRESTの原則を守って設計されたAPIです。

RESTful APIの設計原則は以下へ記載します。

**1. 統一インターフェース**
これは、APIのリソースに対する操作方法やリソースの表現方法、またエラー処理などについて統一した規約を定めることを指します。
これにより、APIの利用者は複数のAPIを扱う場合でも統一的な操作方法を使用できるため、開発効率が向上し、APIの理解が容易になります。WebであればHTTPでやり取りが行われます。

**2. アドレス可能性**
これは、APIのリソースに一意なURLを割り当て、リソースを識別可能にすることを指します。
この原則により、APIの利用者はリソースを特定するために必要なURLを把握できるため、APIの使い方が簡単になります。

**3. 接続性**
これは、APIでやり取りする情報にリンクを含められることを指します。1つのリンクから別の情報のリンク(接続）することができ、RESTfulなシステム同士なら円滑に情報連携を行えます。

**4. ステートレス性**
APIのリクエストとレスポンスが状態を持たず、個々のリクエストとレスポンスが互いに独立していることを指します。この原則により、APIの利用者は複数のAPIを使用する場合でも、各APIに対する状態管理を行う必要がなくなります。

:::note info
開発したAPIが本当にRESTに沿っているのかは意識しておく必要があります。
:::

# まとめ

完全に個人として振り返りようですが、適宜図解や具体例を追加する予定です。

現段階ではHTTP周りのみに絞って作成しましたが、Webや関連するネットワークの仕組みなども一緒に追加してしまおうと思います。