- Published on
HTTP
- Authors
- Name
- あやき
- @ayaki2325
はじめに
この記事では、HTTPの基本概念・HTTPメッセージ・HTTPメソッド・HTTPステータスコード・HTTPヘッダーフィールド・HTTPの状態管理を解説します。
対象読者は、HTTPに自信のないバックエンドエンジニアです。
質の高いWeb APIを設計・開発するのに役立つはずです。
Table of Contents
HTTPとは
HTTP(HyperText Transfer Protocol)とは、WebブラウザとWebサーバー間でデータをやり取りするための通信プロトコルです。
インターネット上でWebページを閲覧したり、Web APIを呼び出したりする際に使われる、Web通信の基盤となる仕組みです。
本来、コンピューター同士が通信するには複雑な手順が必要ですが、HTTPはその手順を標準化し、誰でも同じ方法でWeb上のリソースにアクセスできるようにしています。
HTTPは「リクエスト・レスポンス」という単純な仕組みで動作します。
クライアント(WebブラウザやAPIクライアントなど)がサーバーに「リクエスト」を送信し、サーバーがそれに対して「レスポンス」を返すという流れです。
この仕組みにより、世界中のWebサーバーが統一された方法で情報を提供でき、開発者は一貫したAPIを設計できるのです。
特に現代のWebアプリケーション開発では、HTTPの仕組みを正しく理解することが、堅牢で効率的なシステムを構築するために不可欠です。
それでは、HTTPがどのような構造でデータをやり取りしているのか、具体的な仕組みを見ていきましょう。
HTTPメッセージ
HTTPメッセージとは、クライアントとサーバー間でやり取りされるデータの形式です。
HTTPメッセージは大きく分けると以下3要素から構成されています。
- メッセージヘッダー: サーバーやクライアントが処理すべきリクエストやレスポンスの内容や属性など
- 空行: CR+LF
- メッセージボディ: 転送されるデータそのもの
HTTPメッセージには「HTTPリクエスト」と「HTTPレスポンス」の2種類があります。
HTTPリクエスト
HTTPリクエストは、クライアントがサーバーに送信するメッセージです。
以下の要素で構成されます。
- リクエストライン: リクエストに使用するメソッド、リクエストURI、使用するHTTPバージョンが含まれる。
- ヘッダーフィールド: リクエストの諸条件や属性などを表す。一般ヘッダーフィールド、リクエストヘッダーフィールド、エンティティヘッダーフィールドがある。
- 空行: 同上
- メッセージボディ: 同上
- その他: HTTPのRFCにはないヘッダーフィールド(Cookieなど)が入ることもある
GET /api/users HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0
Accept: application/json
HTTPレスポンス
HTTPレスポンスは、サーバーがクライアントに返すメッセージです。
以下の要素で構成されます。
- ステータスライン: レスポンス結果を表すステータスコード(後述)とその説明と、使用するHTTPバージョンが含まれます
- ヘッダーフィールド: レスポンスの諸条件や属性などを表す。一般ヘッダーフィールド、レスポンスヘッダーフィールド、エンティティヘッダーフィールドがある
- 空行: 同上
- メッセージボディ: 同上
- その他: 同上
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 25
{"id": 1, "name": "田中"}
次に、リクエストの種類を決定するHTTPメソッドについて詳しく見ていきましょう。
HTTPメソッド
HTTPメソッドとは、クライアントがサーバーに対して実行したい操作を指定する仕組みです。
リクエストラインの最初に記述され、そのリクエストの目的を明確に表します。
各メソッドには特定の役割と特性があり、適切なメソッドを選択することで、直感的で一貫性のあるインターフェースを提供できます。
代表的なHTTPメソッドとその特性を詳しく見ていきましょう。
GET
リソースを取得するためのメソッドです。
GET /api/users/123 HTTP/1.1
Host: example.com
Accept: application/json
POST
エンティティボディを転送するためのメソッドです。
POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 28
{"name": "田中", "age": 30}
PUT
ファイルを転送するためのメソッドです。
PUT /api/users/123 HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 28
{"name": "佐藤", "age": 35}
DELETE
ファイルを削除するためのメソッドです。
DELETE /api/users/123 HTTP/1.1
Host: example.com
HEAD
メッセージヘッダーを取得するためのメソッドです。
メッセージボディは返しません。
URIの有効性やリソースの更新時間を確かめる目的などで使われます。
HEAD /api/users/123 HTTP/1.1
Host: example.com
OPTIONS
指定したリソースがサポートしているメソッドを調べるするためのメソッドです。
OPTIONS /api/users HTTP/1.1
Host: example.com
ここまでで、HTTPメソッドの種類を解説しました。
次に、サーバーからの処理結果を表すHTTPステータスコードについて説明します。
HTTPステータスコード
HTTPステータスコードとは、サーバーがクライアントに対してリクエストの処理結果を通知するための3桁の数字です。
レスポンスのステータスラインに含まれ、リクエストが成功したか、失敗したか、追加のアクションが必要かを示します。
ステータスコードは最初の桁によって大きく5つのカテゴリに分類され、それぞれ異なる意味を持ちます。
適切なステータスコードを返すことで、クライアント側での適切なエラーハンドリングや処理分岐を可能にします。
各カテゴリとその代表的なステータスコードを詳しく見ていきましょう。
1xx Informational
リクエストを受信し、処理を継続中であることを示すステータスコードです。
最終的なレスポンスではなく、処理の途中経過を通知するために使用されます。
2xx Success
リクエストが正常に受信・理解・受諾されたことを示すステータスコードです。
成功時の処理結果に応じて適切なコードを選択します。
- 200 OK: リクエストが成功
- 204 No Content: リクエストは成功したが、レスポンスボディに送信するコンテンツがない
- 206 Partial Content: Range リクエストが成功し、一部のコンテンツのみを返す
3xx Redirection
リクエストの完了のために追加のアクションが必要であることを示すステータスコードです。
通常、クライアントは別のURLへのリクエストを行う必要があります。
- 301 Moved Permanently: リクエストされたリソースが恒久的に新しいURLに移動した
- 302 Found: リクエストされたリソースが一時的に別のURLに存在する
- 303 See Other: 302 Found と同様だが、リダイレクト先をGETメソッドで取得するということが明確になっている点が異なる
- 304 Not Modified: 条件付きリクエスト(If-Modified-Since等)において、リソースへのアクセスは許可されたが、条件が満たされていなかったことを示す
- 307 Temporary Redirect: 302 Found と同様だが、リクエストメソッドを保持してリダイレクトすることが保証される
4xx Client Error
クライアント側にエラーがあることを示すステータスコードです。
リクエストの形式が不正であったり、認証が必要であったりする場合に使用されます。
- 400 Bad Request: リクエストが不正であることを示す。構文エラーや必須パラメータの不足など。
- 401 Unauthorized: HTTP認証が必要であることを示す
- 403 Forbidden: リクエストは理解されたが、アクセスが拒否されたことを示す
- 404 Not Found: リクエストされたリソースが見つからないことを示す
5xx Server Error
サーバー側でエラーが発生したことを示すステータスコードです。
リクエスト自体は正常だが、サーバーが処理を完了できない場合に使用されます。
- 500 Internal Server Error: サーバー内部でエラーが発生したことを示す。Webアプリケーションのエラーなど。
- 503 Service Unavailable: サーバーが一時的にリクエストを処理できないことを示す。メンテナンス中や過負荷状態の際に使用される。
ここまでで、HTTPステータスコードの各カテゴリと主要なコードを解説しました。
次に、リクエストやレスポンスの詳細情報を伝えるHTTPヘッダーフィールドについて説明します。
HTTPヘッダーフィールド
HTTPヘッダーフィールドとは、HTTPメッセージに含まれる付加情報を格納するフィールドです。
リクエストとレスポンスの両方に含まれ、通信に必要な様々なメタデータを伝達します。
ヘッダーフィールドは「フィールド名: フィールド値」の形式で記述され、HTTPメッセージの動作を制御したり、コンテンツの詳細を示したりする重要な役割を果たします。
適切なヘッダーフィールドを使用することで、効率的で安全な通信を実現できます。
ヘッダーフィールドは用途に応じて以下の4つに分類されます。
- 一般ヘッダーフィールド
- リクエストヘッダーフィールド
- レスポンスヘッダーフィールド
- エンティティヘッダーフィールド
一般ヘッダーフィールド
リクエスト・レスポンス両方で使用される汎用的な情報を表すヘッダーフィールドです。
- Cache-Control: キャッシュの動作を制御する。
no-cache
(キャッシュしない)、max-age=3600
(3600秒間キャッシュ)など。 - Connection: プロキシに対してそれ以上転送しないヘッダーフィールドの指定。持続的接続の管理。
keep-alive
(接続維持)、close
(接続終了)など。 - Date: メッセージが生成された日時。
Date: Wed, 21 Oct 2015 07:28:00 GMT
- Pragma: HTTP/1.0 との後方互換性のために定義。
no-cache
。 - Trailer: メッセージボディの後に記述されているヘッダーフィールドをあらかじめ伝えることができる。チャンク転送エンコーディングを使用しているときに使う。
- Transfer-Encoding: メッセージボディの転送コーディング形式を指定。
- Upgrade: 現在使用しているプロトコルから別のプロトコルを使用する場合に指定。
HTTP/2.0
など。 - Via: プロキシやゲートウェイによって追加される経路情報。
- Warning: レスポンスに関する追加情報。キャッシュに関する警告など。
リクエストヘッダーフィールド
クライアントからサーバーへのリクエストで使用される情報を表すヘッダーフィールドです。
- Accept: ユーザーエージェントが処理可能なメディアタイプと、それらの優先度。
application/json, text/html
- Accept-Charset: ユーザーエージェントが処理可能な文字セットと、それらの優先度。
utf-8, iso-8859-1
- Accept-Encoding: ユーザーエージェントが処理可能なコンテンツコーディングと、それらの優先度。
gzip, deflate, br
- Accept-Language: ユーザーエージェントが処理可能な自然言語。
ja, en-US;q=0.8
- Authorization: ユーザーエージェントの認証情報を伝える。
Basic dWud...
- Expect: サーバーに特定の振る舞いを要求していることを伝える。
100-continue
- From: ユーザーエージェントを使っているユーザーのメールアドレス。
- Host: リクエストしたリソースのインターネットホストとポート番号。
example.com:8080
- If-Match: 指定されたETagと一致する場合のみリクエストを受け付ける。
- If-Modified-Since: 指定された日時以降に更新されている場合のみリクエストを受け付ける。
- If-None-Match: 指定されたETagと一致しない場合のみリクエストを受け付ける。
- If-Range: 指定されたETagまたは日時と一致する場合のみ Range リクエストを受け付ける。
- If-Unmodified-Since: 指定された日時以降に更新されていない場合のみリクエストを受け付ける。
- Max-Forwards: 転送してもよいサーバー数の最大値。
- Proxy-Authorization: プロキシサーバーへの認証情報を伝える。
- Range: リソースの特定範囲を要求。
bytes=200-1023
- Referer: リクエストが発生した元のリソースのURI。
- TE: レスポンスに受け入れ可能な転送エンコーディングの形式と、それらの優先度。
- User-Agent: ブラウザやユーザーエージェントの名前などの情報。
Mozilla/5.0 (Windows NT 10.0; Win64; x64)
レスポンスヘッダーフィールド
サーバーからクライアントへのレスポンスで使用される情報を表すヘッダーフィールドです。
- Accept-Ranges: サーバーが Range リクエストを受け付け可能かどうかを伝える。
bytes
,none
- Age: オリジンサーバーでレスポンスが生成されてからの経過時間(秒)。
- ETag: リソースを一義的に特定するための文字列。
"abc123def456"
- Location: Request-URI以外のリソースへアクセスを誘導する。
https://example.com/new-location
- Proxy-Authenticate: プロキシサーバーからの認証要求。
- Retry-After: クライアントがどれぐらい後にリクエストを再試行すべきかを伝える。
3600
(秒)またはWed, 21 Oct 2015 07:28:00 GMT
- Server: サーバーに実装されているHTTPサーバーのソフトウェアを伝える。
nginx/1.18.0
- Vary: キャッシュキーとして使用するリクエストヘッダーを指定。
Accept-Encoding, User-Agent
- WWW-Authenticate: クライアントに要求する認証スキームとパラメータを示す challenge を伝える。
Basic realm="api"
エンティティヘッダーフィールド
リクエストやレスポンスのメッセージボディに関する情報を表すヘッダーフィールドです。
- Allow: Request-URIで指定したリソースがサポートしているメソッドの一覧。
GET, POST, PUT, DELETE
- Content-Encoding: サーバーがエンティティボディに施したコンテンツコーディングの形式。
gzip
,deflate
- Content-Language: エンティティボディに使用されている自然言語。
ja
,en-US
- Content-Length: エンティティボディの大きさ(バイト数)。
1024
- Content-Location: メッセージボディに対応するURI。
- Content-MD5: メッセージボディに対してMD5アルゴリズムを実行したバイナリ値に、Base64エンコーディングを施した結果。メッセージボディが変更されずに届いたことを保証するため。
- Content-Range: 範囲を指定して一部分だけリクエストするレンジリクエストに対するレスポンスを行う際に使われる。レスポンスがどの部分に該当するかを伝える。
bytes 200-1023/2048
- Content-Type: エンティティボディのメディアタイプ。
application/json; charset=utf-8
- Expires: リソースの有効期限。
Wed, 21 Oct 2015 07:28:00 GMT
- Last-Modified: リソースが最後に更新された日時。
Wed, 21 Oct 2015 07:28:00 GMT
その他のヘッダーフィールド
- X-Frame-Options: 他のWebサイトのフレームでの表示を制御。クリックジャッキングを防ぐ。
DENY
(拒否)、SAMEORIGIN
(同一オリジンのみフレームに読み込める) - X-XSS-Protection: XSS保護機能の制御。
0
(XSSフィルタを無効)、1
(XSSフィルタを有効s) - DNT: Do Not Track。個人情報の収集を拒否する意思を示す。
0
(トラッキングに同意)、1
(トラッキングを拒否) - P3P: Webサイト上のプライバシーポリシーをP3Pを使うことで、プログラムが読める形で示すことを目的。
ここまでで、HTTPヘッダーフィールドの各カテゴリと主要なフィールドを解説しました。
次に、HTTPの重要な機能である状態管理について説明します。
HTTPの状態管理
HTTPの状態管理とは、ステートレスなHTTPプロトコルでユーザーの状態を維持する仕組みです。
HTTPは本来、リクエストとレスポンスが独立しており、前回の通信内容を覚えていません。
しかし、Webアプリケーションでは「ログイン状態の維持」「ショッピングカートの内容保持」「ユーザー設定の記憶」など、複数のリクエストにわたって状態を保持する必要があります。
この課題を解決するために、HTTPでは主にCookieという仕組みを使用して状態管理を行います。
HTTPの状態管理の仕組みと実装方法を詳しく見ていきましょう。
Cookie
Cookieとは、サーバーがクライアントに送信する小さなデータ片です。
クライアント(ブラウザ)はCookieを保存し、同じサーバーへの以後のリクエストで自動的にCookieを送信します。
Cookieの動作は以下の流れで行われます。
- サーバーからCookieを送信: レスポンスヘッダーの
Set-Cookie
でクライアントにCookieを設定 - クライアントがCookieを保存: ブラウザが受信したCookieを保存
- クライアントがCookieを送信: 以後のリクエストで
Cookie
ヘッダーに含めて自動送信
# 初回リクエスト
GET /reader/ HTTP/1.1
Host: example.com
# レスポンス(サーバーがCookieを設定)
HTTP/1.1 200 OK
Set-Cookie: sessionId=abc123; Path=/; HttpOnly; Secure
# 2回目以降のリクエスト
GET /image/ HTTP/1.1
Host: example.com
Cookie: sessionId=abc123
Set-Cookieヘッダーフィールド
Set-Cookie
レスポンスヘッダーフィールドは、サーバーがクライアントにCookieを送信するために使用されます。
基本的なフォーマットはSet-Cookie: NAME=VALUE; 属性
です。
詳細は以下の通りです。
NAME=VALUE
: Cookie につける名前とその値expires=DATE
: Cookie の有効期限path=PATH
: Cookie の適用対象となるサーバー上のディレクトリdomain=DOMAIN
: Cookie の適用対象となるドメイン名Secure
: HTTPSで通信している場合にのみ Cookie を送信HttpOnly
: Cookie を JavaScriptからアクセスできないように制限。
Cookieヘッダーフィールド
Cookie
リクエストヘッダーフィールドは、クライアントが保存しているCookieをサーバーに送信するために使用されます。
フォーマットはCookie: NAME1=VALUE1; NAME2=VALUE2
です。
ここまでで、HTTPの状態管理の仕組みとCookieの使用方法を解説しました。
まとめ
- HTTPとはWebブラウザとWebサーバー間でデータをやり取りするための通信プロトコル
- HTTPメッセージにはHTTPリクエストとHTTPレスポンスがあり、それぞれ特定の構造を持つ
- HTTPメソッドはクライアントがサーバーに対して実行したい操作を指定する
- HTTPステータスコードはサーバーがクライアントに対してリクエストの処理結果を通知する
- HTTPヘッダーフィールドはHTTPメッセージに含まれる付加情報を格納する
- HTTPの状態管理はCookieによって実現される