1. HTTPリクエストメソッド
HTTP (Hypertext Transfer Protocol) は、クライアントとサーバー間の通信に使用されるアプリケーション層プロトコルです。
| HTTP方式 | CRUDに対応 | 機能 | 冪等性 |
|---|---|---|---|
| GET | READ | リソースを取得する | はい |
| POST | CREATE | リソースを作成するか、処理のためにデータを送信します | いいえ (デフォルト) |
| PUT | UPDATE | ターゲットリソースを作成または完全に置き換えます | はい |
| PATCH | UPDATE | 部分的に変更されたリソース | 保証なし |
| DELETE | DELETE | リソースの削除 | はい |
| HEAD | READ | 応答ヘッダーのみを取得し、応答本文は返さない | はい |
| OPTIONS | — | サーバーがサポートする通信オプションを問い合わせます | はい |
べき等性 (Idempotency)
同じリクエストが 1 回実行される場合も複数回実行される場合も、サーバーに対する期待される効果は同じであり、これを冪等といいます。
たとえば:
GET /users/1: 読み取りを繰り返しても、サーバー リソースのステータスは変更されません。PUT /users/1: 同じコンテンツが繰り返し送信され、リソースの最終ステータスは同じです。DELETE /users/1: 重複して削除すると、リソースは最終的に存在しない状態になります。POST /orders: 繰り返し送信すると複数の注文が作成される可能性があるため、デフォルトは冪等ではありません。
注: 冪等とは、すべての応答がまったく同じであることを意味するわけではありません。たとえば、リソースを繰り返し削除すると、最初は 204 が返され、2 回目は 404 が返されることがあります。
HTTP は安全なメソッド (Safe Methods) も区別します。 GET、HEAD、および OPTIONS はすべて安全なメソッドです。つまり、クライアントはサーバー リソースの状態の変更を要求しません。
2. HTTP ステートレス
HTTP はステートレス プロトコル (Stateless Protocol) です。
これは、サーバーが個々の HTTP リクエストを処理するとき、HTTP プロトコルが以前のリクエストのコンテキストを自動的に記憶していることを前提としない、という意味です。
たとえば:
Client → GET /products
Server → Products
Client → GET /profile
Server → Profile
各リクエストには、サーバーがリクエストを処理するために必要な情報が必要です。
ただし、ステートレスだからといって、サーバーがユーザー情報を保存できないわけではありません。
実際の応用例:
- Cookie: ブラウザは Cookie を保存し、後続のリクエストで送信します。
- Session: サーバーはセッション状態を保存でき、クライアントは Session ID を通じてセッションを識別します。
- JWT: クライアントは Token を保持でき、サーバーは検証後にユーザーを識別します。
HTTP 自体はステートレスですが、Web アプリケーションは、Cookie、Session、Token およびその他のメカニズムを通じてステートフル ユーザー セッションを実装できます。
さらに、HTTP Keep-Alive は TCP 接続を再利用できますが、接続の再利用とアプリケーション層のセッション状態は 2 つの異なる概念です。
3. URL構造
一般的な URL 構造:
scheme://host:port/path?query#fragment
たとえば:
https://api.example.com:443/api/v1/users?page=2#details
| 構成 | 説明 |
|---|---|
| scheme | HTTP、HTTPSなどのプロトコル |
| host | ドメイン名またはIPアドレス |
| port | サーバーポート |
| path | リソースパス |
| query | クエリパラメータ |
| fragment | ページフラグメント識別子 |
補足:
- HTTP デフォルトのポートは 80 です。
- HTTPS デフォルトのポートは 443 です。
- Query パラメータは、検索、フィルタリング、ページング、並べ替えによく使用されます。
- Fragment は通常、ブラウザによってクライアント側で処理され、通常の HTTP リクエスト ターゲットの一部としてサーバーに送信されません。
URI はリソース識別子で、URL は URI のタイプで、リソースを見つけるために使用されます。
4. RESTful APIの設計仕様
REST (Representational State Transfer) は建築様式の 1 つです。
RESTful API は通常、リソース中心であり、HTTP メソッドによる操作を表します。
URL デザイン
名詞と複数形を使用することをお勧めします。
/api/v1/users
/api/v1/users/{user_id}
/api/v1/users/{user_id}/orders
/api/v1/users/{user_id}/orders/{order_id}
通常、URL で動詞を再利用することは推奨されません。
GET /getUsers
POST /createUser
DELETE /deleteUser/1
さらにお勧めします:
GET /users
POST /users
GET /users/1
PUT /users/1
PATCH /users/1
DELETE /users/1
ただし、CRUD に自然にマッピングできないビジネス操作の場合は、次のようなアクション エンドポイントも使用できます。
POST /orders/123/cancel
POST /payments/123/refund
このような設計は一般的なエンジニアリング手法であり、REST によって禁止されたり要求されたりするものではありません。
URL 設計原則
- リソースを説明するには名詞を使用します (通常は複数形)。
- 操作を区別するには、HTTP メソッドを使用します。
- Query パラメータを使用して、検索、フィルタリング、並べ替え、およびページングを実装します。
- URL 階層を単純にして、深いネストを避けてください。
- API バージョンは、
/api/v1/など、URL に配置できますが、これがバージョンを管理する唯一の方法ではありません。
5. Query Parameters
Query パラメータは通常、GET リクエストで使用されます。
GET /api/v1/pois?city=1&limit=20&offset=40
| パラメータ | 目的 |
|---|---|
city=1 | フィルター |
limit=20 | 毎回 20 個のアイテムが返されます |
offset=40 | 最初の 40 項目をスキップ |
ordering=-score | スコアの降順 |
search=Tokyo | 検索キーワード |
複雑な検索の場合、POST を使用して JSON リクエスト本文を運ぶこともできますが、このインターフェイスのクエリ セマンティクスは明確に定義する必要があります。
6. HTTP Request / Response
Request構造
POST /api/v1/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer <token>
{
"name": "Alice",
"age": 25
}
主に以下が含まれます:
- Request Method: リクエストメソッド。
- URL: リソースを要求しています。
- Headers: メタデータを要求します。
- Body: コンテンツが存在する場合はリクエストします。
Response構造
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/v1/users/123
{
"id": 123,
"name": "Alice",
"age": 25
}
主に以下が含まれます:
- Status Code: 応答ステータスコード。
- Headers: 応答メタデータ。
- Body: 応答の内容 (存在する場合)。
7.共通HTTP Header
| Header | 機能 |
|---|---|
| Content-Type | リクエストボディまたはレスポンスボディのデータ型 |
| Accept | クライアントが受信を希望するデータの種類 |
| Authorization | 認証資格情報の持ち込み |
| Cookie | ブラウザは Cookie をサーバーに送信します |
| Set-Cookie | サーバーにはブラウザ設定 Cookie が必要です |
| Cache-Control | キャッシュポリシーの制御 |
| Accept-Encoding | クライアントがサポートする圧縮アルゴリズム |
| Content-Encoding | 応答コンテンツに使用される圧縮アルゴリズム |
| Origin | CORSで共通に使用するリクエスト元のソース情報 |
| Access-Control-Allow-Origin | クロスオリジンアクセスを許可するオリジンを指定する |
| ETag | キャッシュ検証に使用されるリソースのバージョン識別子 |
Content-Type および Accept
Content-Type: application/json
Accept: application/json
違い:
Content-Type: 現在の送信コンテンツのフォーマットは何ですか。Accept: クライアントがサーバーに返す形式を要求します。
Accept-Encoding および Content-Encoding
Accept-Encoding: br, gzip
Content-Encoding: br
ブラウザは Brotli と gzip をサポートし、サーバーは Brotli 圧縮応答を選択します。
8. HTTP ステータスコード
HTTP ステータス コードは、次の 5 つのカテゴリに分類されます。
| 範囲 | カテゴリ | 意味 |
|---|---|---|
| 1xx | Informational | 有益な回答 |
| 2xx | Success | リクエストは成功しました |
| 3xx | Redirection | リダイレクトまたはキャッシュの検証 |
| 4xx | Client Error | クライアントリクエストエラー |
| 5xx | Server Error | サーバーエラー |
2xx 成功
| ステータスコード | 名前 | 意味 |
|---|---|---|
| 200 | OK | リクエストは成功し、通常はデータが返されます |
| 201 | Created | リソースが正常に作成されました |
| 202 | Accepted | リクエストは受け入れられましたが、処理はまだ完了していません |
| 204 | No Content | リクエストは成功しましたが、レスポンスボディはありません |
一般的な使用法:
- GET 成功: 200
- POST が正常に作成されました: 201
- PUT/PATCH は正常に変更されました: 200 または 204
- DELETE 成功: 204
- 非同期タスクが受け入れられました: 202
202 非同期タスクが最終的に正常に実行されるという保証はありません。
3xx リダイレクト
| ステータスコード | 名前 | 意味 |
|---|---|---|
| 301 | Moved Permanently | 永続的なリダイレクト |
| 302 | Found | 一時的なリダイレクト |
| 304 | Not Modified | リソースは変更されていないため、キャッシュは再利用できます。 |
| 307 | Temporary Redirect | 一時リダイレクト、保持リクエストメソッド |
| 308 | Permanent Redirect | 永続的なリダイレクト、保持リクエストメソッド |
注: 304 は通常、条件付きリクエストに使用され、通常のページ ジャンプとは異なります。
4xx クライアント エラー
| ステータスコード | 名前 | 意味 |
|---|---|---|
| 400 | Bad Request | リクエストの形式が間違っているか、パラメータが不正です |
| 401 | Unauthorized | 有効な認証資格情報がありません |
| 403 | Forbidden | サーバーはリクエストの実行を拒否しました |
| 404 | Not Found | リソースが存在しないか、公開されていません |
| 405 | Method Not Allowed | HTTPメソッドはサポートされていません |
| 406 | Not Acceptable | Acceptの要件を満たす応答を提供できません |
| 409 | Conflict | 現在のリソースのステータスと競合します |
| 410 | Gone | リソースは永久に利用できません |
| 413 | Content Too Large | リクエストされたコンテンツがサーバーの制限を超えています |
| 415 | Unsupported Media Type | リクエストボディのデータ形式がサポートされていません |
| 422 | Unprocessable Content | リクエスト形式は認識されますが、コンテンツを処理できません |
| 429 | Too Many Requests | リクエストが多すぎるため、電流制限が発生します |
401と403の違い
- 401: クライアントに有効な認証資格情報がないため、通常はログインまたは再認証が必要です。
- 403: サーバーはリクエストを理解しましたが、その実行を拒否し、クライアントが認証されている場合でも 403 を返す場合があります。
400と422の違い
- 400: 通常、リクエストの形式またはパラメータのエラーを示します。また、リクエストの検証の失敗をカバーすることもできます。
- 422: リクエストの構文は正しく、コンテンツ タイプは識別可能ですが、サーバーは命令またはセマンティクスを処理できません。
フレームワークが異なれば、検証エラーに対して異なるステータス コードが選択される場合があります。
たとえば、Django REST Framework の Serializer 検証エラーは通常 400 を返しますが、FastAPI のリクエスト データ検証エラーは通常 422 を返します。
5xx サーバーエラー
| ステータスコード | 名前 | 意味 |
|---|---|---|
| 500 | Internal Server Error | サーバー内部エラー |
| 502 | Bad Gateway | ゲートウェイが無効なアップストリーム応答を受信しました |
| 503 | Service Unavailable | サービスが一時的に利用できなくなりました |
| 504 | Gateway Timeout | ゲートウェイがアップストリームの応答を待機中にタイムアウトしました |
Nginx + Django アーキテクチャの場合:
- 500: Django は内部例外が原因である可能性があります。
- 502: Nginx は有効な Django アップストリーム応答を取得できませんでした。
- 503: サーバーは一時的にサービスを提供できません。
- 504: Nginx は Django アップストリーム応答を待機中にタイムアウトしました。
9. HTTP キャッシュ
HTTP キャッシュにより、変更されていないリソースの繰り返しダウンロードが回避されます。
一般的な応答ヘッダー:
Cache-Control: public, max-age=31536000, immutable
通常、コンテンツ ハッシュを持つ JS、CSS 静的リソースに使用されます。
一般的な Cache-Control 命令:
| 指示 | 意味 |
|---|---|
| public | 共有キャッシュストレージを許可する |
| private | 応答はプライベート キャッシュにのみ保存できます |
| no-cache | キャッシュを再利用する前に検証する必要がある |
| no-store | 保存された応答のキャッシュを許可しない |
| max-age=3600 | キャッシュの鮮度期間は 3600 秒です |
| immutable | フレッシュ期間中にリソースは変更されません |
ETag キャッシュの検証
ブラウザの最初のリクエスト:
GET /api/v1/data
サーバーは次を返します:
HTTP/1.1 200 OK
ETag: "abc123"
再度リクエストしてください:
GET /api/v1/data
If-None-Match: "abc123"
リソースが変更されていない場合、サーバーは以下を返すことができます。
HTTP/1.1 304 Not Modified
ブラウザはキャッシュのコンテンツを引き続き使用します。
10. CORSとCSRF
CORS(Cross-Origin Resource Sharing)
ブラウザは、同一オリジン ポリシーを通じて、応答のクロスオリジン読み取りを制限します。 CORS を使用すると、サーバーはブラウザーがどのクロスオリジン リクエストにアクセスできるかを宣言できます。
たとえば:
Access-Control-Allow-Origin: https://example.com
クロスオリジンリクエストは、場合によっては最初に OPTIONS プリフライトリクエスト (Preflight Request) を送信します。
CORS は主にブラウザのセキュリティ メカニズムであり、バックエンド API の ID 認証メカニズムではありません。
CSRF(Cross-Site Request Forgery)
CSRF は、ブラウザを使用して Cookie などの認証資格情報を自動的に伝達し、ログインした Web サイトでユーザーが予期しない操作を実行するように誘導する攻撃です。
一般的な防御方法:
- CSRF Token。
- Cookie の SameSite 属性。
- Origin/Refererをご確認ください。
- GET を使用してサーバーのステータスを変更する操作を実装しないでください。
CORS と CSRF は異なるセキュリティ メカニズムであり、相互に置き換えることはできません。
11. HTTP/1.1、HTTP/2、HTTP/3
| 特長 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| 基礎となるトランスポート | TCP | TCP | QUIC (UDP ベース) |
| 多重化 | HTTP/2 スタイルの多重化なし | サポート | サポート |
| Header圧縮 | 専用の Header 圧縮メカニズムはありません | HPACK | QPACK |
| トランスポート層の行頭ブロック | 存在する | 存在する | TCP スタイルのクロスフロー行頭ブロックを回避する |
主な違い:
- HTTP/1.1: 幅広い互換性があり、多くの場合、同時実行性を向上させるために複数の TCP 接続を使用します。
- HTTP/2: 1 つの接続で複数のリクエストを多重化し、伝送効率を向上させます。
- HTTP/3: QUIC に基づいて、パケット損失時のマルチストリーム伝送パフォーマンスが向上します。
HTTP/2 と HTTP/3 は、GET や POST などのメソッドの基本的なセマンティクスを変更しません。
概要
HTTP および RESTful API に関するコア知識:
| モジュール | フォーカス |
|---|---|
| HTTP Method | GET、POST、PUT、PATCH、DELETE |
| HTTPの特徴 | ステートレス、安全、冪等 |
| URL | Scheme、Host、Port、Path、Query |
| RESTful | リソース指向、HTTP メソッド、ステータス コード |
| Request/Response | Header、Body、Status Code |
| HTTP ステータスコード | 2xx、3xx、4xx、5xx |
| キャッシュ | Cache-Control、ETag、304 |
| 安全な | HTTPS、Authentication、CORS、CSRF |
| HTTPバージョン | HTTP/1.1、HTTP/2、HTTP/3 |
バックエンド API 開発の場合、最も習得する必要があるのは、HTTP メソッドのセマンティクス、ステータス コードの正しい使用、冪等性、認証と認可、キャッシュ ポリシー、およびクロスドメイン セキュリティです。
参考資料: