仕組み
Cache-Control と ETag は、役割が異なります。
| 要素 | 主な役割 |
|---|---|
Cache-Control |
保存や再利用をどう許可するか |
ETag |
レスポンスの表現が同じかを確認するための識別子 |
最初の取得
公開記事の例です。
HTTP/1.1 200 OK
Cache-Control: public, max-age=60
ETag: "article-123-v7"
Content-Type: application/json
{
"id": 123,
"title": "API設計の基本"
}
通常、キャッシュは鮮度の条件を満たしている間、サーバーに再確認せずレスポンスを再利用できます。
鮮度の期間を過ぎたら、ETagで確認する
GET /articles/123
If-None-Match: "article-123-v7"
内容が変わっていなければ、サーバーは本文を送らずに応答します。
HTTP/1.1 304 Not Modified
Cache-Control: public, max-age=60
ETag: "article-123-v7"
クライアントは、保存していた本文を再利用します。これが条件付きリクエストによる再検証です。HTTPキャッシュ仕様
ETagがあっても、DB負荷が減るとは限らない
次の実装では、304を返せてもDB問い合わせは残ります。
毎回DBから取得
→ JSONを生成
→ ハッシュを計算してETagを作成
→ 変更なしと判断
→ 304を返す
この場合、主に削減できるのは本文の転送量です。
DB負荷も下げるには、たとえば次のような仕組みが必要です。
- ブラウザやCDNで、新鮮なレスポンスをそのまま返す。
- アプリケーション側に、生成済みレスポンスを保持する。
- 内容全体を読み出さず、変更を判定できるようにする。
ETagには、そのレスポンスの内容に関わる変更を反映させます。記事に著者名も含むなら、著者名の変更を無視するETagでは不十分です。
混同しやすいディレクティブ
| 指定 | 意味 |
|---|---|
no-cache |
保存は可能だが、再利用前に検証が必要 |
no-store |
キャッシュに保存させない |
private |
共有キャッシュでの保存を禁止する |
public |
共有キャッシュでの保存を許可する |
private は暗号化を意味しません。ユーザー専用データを共有キャッシュへ保存させないための指示です。Cache-Controlの定義
設計上の要点
通信量・API処理・DB問い合わせのうち、どれを減らしたいのかを区別します。