仕組み

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問い合わせのうち、どれを減らしたいのかを区別します。