0
0

HTTP 基本と特徴

Last updated at Posted at 2024-08-14

はじめに

こんにちは。

今回はWEBエンジニアにとって欠かせない、HTTPについて記事を作成しようと思います。
HTTPについては、その内容が多いため、シリーズになりそうです。

では、自分が勉強したことをこれから皆さんに共有したいと思います。

HTTPとは

まずは、HTTPについて簡単に説明します。

HTTP(hyperText transfer protocol)HTMLで書かれた文書などの情報をやりとりする時に使われる通信手順(プロトコル)を意味します。

現在は、HTMLはもちろんTEXTIMAGEAUDIOVIDEOFILE、からJSONXMLなどのAPIまで、すべてのタイプのデータで通信ができます。

HTTPの歴史

✅ HTTP/ 0.9 (1991)
✅ HTTP/ 1.0 (1996)
✅ HTTP/ 1.1 (1997)
✅ HTTP/ 2 (2015)
✅ HTTP/ 3 (2015~)

HTTPは1991年に登場した通信プロトコルです。

初期にはバージョンとして管理されていなかったのですが、以降のバージョンと区分するためにHTTP/ 0.9と呼ばれたようです。この時代のHTTPはGETメソッドのみサポートされ、ヘッダーは定義されていない簡単な構造でした。

1996年になって色んなメソッドとヘッダーが追加されました。

現在、一番多く使われているHTTP/ 1.1は1997年に登場されました。通信に関するほとんどのSPECはHTTP/ 1.1バージョンに含まれているため、HTTPの記事で最も重要なバージョンです。

HTTP/ 2HTTP/ 3は実際に使われてはいますが、HTTP/ 2HTTP/ 3は性能を改善に目的があるため、HTTP/ 1.1が標準プロトコルで使われています。

また、HTTP/ 1.1HTTP/ 2TCPの上で通信を行っていて、HTTP/ 3UDPを採用しています。

私たちが常に利用しているウェブブラウザからも下記のようにプロトコルの情報を確認することができます。

image.png

qiitaではHTTP/ 1.1HTTP/ 2プロトコルを使って通信していることが分かります。
ここで、h2HTTP/ 2を意味します。

image.png
また、Googleではh3つまりHTTP/ 3を使っていることが確認できます。

HTTPの特徴

次はHTTPの特徴について調べていきます。

  • Client - Server 構造
  • Stateless and Connectionless
  • HTTP Message
  • Simplicity and Extensibilty

client - server 構造

HTTPは基本的にClient - Server構造になっています。

image.png

クライアントはサーバーにHTTPでリクエストを送り、サーバーはクライアント側から送られたリクエストに対しての結果をレスポンスを送ります。

ここで、クライアントはサーバーからレスポンスが届くまで待機します。

このようにクライアントとサーバーで分けているのはHTTPの最も大事な特徴ですが、その理由はメンテナンスと、拡張性にあります。

クライアントとサーバーを分離すれば、ビジネスロジックやデータはサーバー側で管理し、クライアント側はUIやUXのようなユーザーに関する機能に集中できるようになります。

こうすることで、独立的に性能などを向上することができます。クライアントはデータに関する作業を行う必要がなくなり、サーバーもアーキテクチャや技術的なところに集中できます。

Stateful, stateless

次のHTTPの特徴はサーバーがクライアントの状態を保持しない点です。これをstatelessといいます。
逆に、サーバーがクライアントの状態を保持すればstatefulといいます。

stateful

まずstatefulについて簡単な例を見てみましょう。

・御客さん:この「PC」はいくらですか?
・店員:10万円です。 
    (PCの状態を保持)

・御客さん:「2つ」購入します。
・店員:20万円です。お支払いは「クレジット」と「現金」中どっちにしますか?
    (PC, 2つの状態を保持)

・御客さん:「クレジット」でお願いします。
・店員:20万円、支払い完了しました。
    (PC, 2つの状態を保持)

買い物をする際の、日常的な会話です。
お客さんは会話ごとに、自分の要求を伝えて、店員はお客さんの会話を覚えながら対応してます。

お客さんをクライアント、店員をサーバーと考えてみましょう。
サーバーは前の会話を覚えながら、それぞれの要求に対して対応をしています。そのため、クライアントは前の会話を繰り返すことなく、その場で必要な要求だけ伝えて済みます。

この会話でサーバーが保持しているデータはPC2つクレジットカードになるはずです。また、この状態を保持することで、自然な会話ができると思います。

しかし、Statefulな設計にも次のようなデメリットがあります。

・御客さん:この「PC」はいくらですか?
・店員1:10万円です。 

・御客さん:「2つ」購入します。
・店員2:?何を2つ購入しますか?

・御客さん:「クレジット」でお願いします。
・店員3:?何をいくつ、クレジットで購入しますか?

上記の会話はStatefulな環境で、会話ごとに店員が変わる場合の例です。

各店員は前の会話を分からないため、お客さんの最終的な要求事項について理解していない状況です。
お客さんの要求(PC2つクレジットカード)について店員ごと知っているのが違うからです。

つまり、Statefulな設計のデメリット一つのクライアントが複数のサーバーと通信する場合、リクエストに対して、各サーバーで保持している状態が異なるため、クライアントの要求に正確なレスポンスを返すことはできなくなります。

stateless

では、状態を保持しないStatelessはどうでしょうか?

次はStatelessな状態での会話の例です。

・御客さん:この「PC」はいくらですか?
・店員1:10万円です。 

・御客さん:「PC」を「2つ」購入します。
・店員2:PC、2つは20万円です。お支払いは「クレジット」と「現金」中どっちにしますか?

・御客さん:「PC」を「2つ」購入します。「クレジット」でお願いします。
・店員3:20万円、支払い完了しました。

Statelessはサーバーがクライアントの状態を保持していません。そのため、クライアントは会話ごとに自分が必要な要求事項を伝える必要があります。

不自然だと思われるかもしれませんが、こうすることで、途中でサーバーが変わってもクライアントの要求事項にあった対応ができます。

また、お客さんが増えても店員を増やせることで、対応ができるようになります。
これは、クライアントの通信量が増えてもサーバーの増設が可能となります。

statelessのメリット

image.png

statefulな状態でクライアントとサーバー間の通信中、エラーが発生すると、今まで保持していた情報をすべて失われるようになります。

そうなると、クライアントは同じリクエストをほかのサーバーと通信しないといけません。

image.png
一方、Statelessな状態ではサーバーでクライアントの状態を保持していなくて、クライアント側で必要な情報をすべてサーバー側に送っているため、他のサーバーが対応することができます。

こういう設計は、スケールアウト(Scale Out)にもいい設計になります。

statelessの限界

もちろん、すべてのサービスをStatelessな状態で設計することは難しいです。

例えば、ログインが要らない単なるサービスの紹介画面がいれば、ユーザーのログイン情報が必要な画面もいるはずです。

ログインが必要な画面については、ユーザーのログイン情報をサーバー側で保持する必要があります。
このように、サーバーでクライアントの状態を保持する必要がある場合は、ブラウザのクッキーとセッションを利用し、状態を保持することもできます。

しかし、サーバーでエラーが発生すると、セッションなどの情報が失われる可能性もあります。

2つ目で、クライアントが送るデータの量が多くなる問題もあります。

前の例でもわかる通り、サーバーが状態を保持していないため、クライアントは自分の要求事項に必要な情報をすべて伝えることで、データを量が多くなりかねません。

このような限界があるにも関わらず、statelessには色んなメリットがあるため、
statelessな設計が推奨されています。

やむを得ずサーバーで状態を保持する必要がある場合は、サーバーは最小限の状態を保持するように設計した方がいいです。

Connectionless

次の特徴はコネクションレス型(Connectionless)です。

コネクションレス型とは、データ通信時に、データをやりとりする端末間でお互いにコネクション(接続関係)を設定しない接続形態のことを言います。

では、コネクション型モデルとコネクションレス型モデルを次の画像を見て、説明します。

コネクション型モデル

まず、コネクション型モデルです。
image.png

上記の画像のようにクライアントとサーバー間のコネクションを維持する例としては、TCP/IPがあります。

画像を見るとクライアントは3台があります。各クライアントはサーバーと通信した後も、コネクションを維持していることが分かります。
こうなると、サーバーは通信もしていないクライアントとのコネクションを維持するため、**リソースを使い続けている*はずです。

コネクションレス型モデル

すると、コネクションレス型モデルはどのような仕組みなのでしょうか?

image.png

上記の画像のように、サーバーはクライアントとリクエストがある場合だけ、クライアントとコネクションを行い、通信が終わればコネクションを切ります。
こうすることで、最小限のリソースでHTTP通信を行うことができます。

まとめると、HTTPは基本的にコネクションレス型のモデルであることです。それによってクライアントはHTTP通信を行い場合だけ、サーバーとのコネクションを維持し、サーバーが最小限のリソースで通信ができるようになります。

HTTP メッセージ

最後に、HTTPのメッセージの構造について調べていきます。

この記事では、詳細については説明しません。

まず、HTTPのメッセージの全体的な構造を次の画像で確認してみましょう。

image.png

HTTPメッセージはstart-lineheaderempty linemessage body4つで分かれています。
この中で、empty lineは空白ラインで必須となります。

HTTPの全体的な構造は同一ですが、リクエストレスポンスごと、
構造する要素は異なります。

image.png

start-line

まず、リクエストstart-lineを説明します。

start-line = rquest-line / status-line

Request-line = HTTP Method + SP(空白) + Request-Target + SP + HTTP-version + CRLF

リクエストのstart-lineはRequest-lineと呼ばれます。

Request-lineHTTP Methodとリクエストの対象のRequest-Target、そして、HTTP-versionで構成されています。
SPは空白を意味し、最後のCRLFは改行を意味します。

GET /search?q=hello&hl=jo HTTP/1.1

上記の例ではHTTP MethodGETのことで、
Request-Targetは(/search?q=hello&hl=jp)、最後に、HTTP/1.1HTTP-versionになります。

次は、レスポンスリクエストstart-lineを説明します。

start-line = rquest-line / status-line

Status-line = HTTP-version + SP + Status-Code + SP + Reason-Phrase + CRLF

レスポンスのstart-lineはStatus-lineと呼ばれます。

Status-lineはHTTP-versionが最初に定義され、Status-CodeReason-Phraseの順で構成されています。
もちろんSPCRLFも同じように構成されています。

Status-codeとは、HTTPレスポンスに含まれるWebサーバーの処理結果を表現する3桁の数字のことを指します。

  • 200:成功
  • 400:クライアントエラー
  • 500:サーバーエラー

Reason-Phraseは人が理解できるStatus-codeの説明文となります。

HTTP/1.1 200 OK

上記の例では、それぞれHTTP/1.1HTTP-version200Status-CodeOKReason-Phraseを指すことが分かります。

HTTP header

headerにはHTTP通信に必要な情報が含まれています。

Bodyに関する情報から、Bodyサイズ、圧縮、認証、リクエスト側のブラウザ情報、サーバーアプリケーションの情報、キャッシュ管理情報など、その要素はいろいろあります。
また、必要に応じては、任意の要素を追加することもできます。

基本的なheaderの構造は次のようです。

header = field-name + : + OWS + field-value + OWS

ヘッダーに入れたいfield-nameを定義し、その次に:を定義します。その後、field-valueを定義します。
一般的なkey-valueタイプを作成する方法と一緒です。

OWSは空白のことを言います。

次は、実際のヘッダーの構造です。

リクエストのヘッダー
HOST: www.google.com
レスポンスのヘッダー
Content-Type: text/html;charset=UTF-8
Content-Length: 3423

この記事では、基本的なheaderの構造と、通信に必要な色んなメタデータが含まれることを知っておけばいいです。

詳細については後の記事で説明します。

HTTP Body

http bodyには実際に伝えるデータが含まれます。

含まれるデータとしては、html以外もimage, video, jsonなど、byteで表現できるすべてのデータが対象になります。

<html>
    <body>...<body>
<html>

上記の例では、リクエストの場合、Bodyは省略されていて、レスポンスのBodyだけHTMLデータが含まれていることを確認できます。

これは、クライアントがGETメソッドを利用したので、それに対するレスポンスをすることだと考えられます。

おわりに

最後まで、ご覧いただけありがとうございます。

この記事では、HTTPの概念、特徴を調べてきました。

HTTPはWEBエンジニアにとって欠かせない、基本知識の一つだと思い、
ゼロから勉強をし直しています。

まだ、勉強することがたくさん残っているので、毎日勉強しながら、セクションごと記事を書こうと思います。

参考サイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0