ゆるテックノート

メソッドとキャッシュの関係

「このレスポンス、キャッシュされる?」を素早く判断するためのメモです。HTTPの意味を定めるRFC 9110とキャッシュを定めるRFC 9111に沿って、GET/HEAD/POSTの扱いをまとめました。

キャッシュの基本

保存できるかはメソッド・ステータス・ヘッダーで決まります。保存できても、実際に保存するかはブラウザーやCDNの実装・設定次第です。

メソッド別の前提

メソッド キャッシュ扱い ポイント
GET 対象 ステータスや認証、Cache-Controlなどの条件を満たす場合に保存可能。
HEAD 対象 GETと同じ扱い。ボディなし。
POST 原則非対象 明示的な鮮度情報と、対象URIと同じ値のContent-Locationが必要。詳細は下記。
PUT/DELETE 対象外 これらのメソッドのレスポンスはキャッシュ不可。
PATCH 条件付きで可能 RFC 5789では明示的な鮮度情報と対象URIに一致するContent-Locationが必要。後続のGET/HEADだけに再利用できる。

主なキャッシュ制御ヘッダー

レスポンスヘッダーがキャッシュの寿命や共有可否を決めます。

ヘッダーまとめ

  • Cache-Control: max-age, s-maxage, no-cache, no-store, private, must-revalidate などで寿命と再検証ルールを指定。
  • ETag/Last-Modified: 再検証に使うタグや日時。条件付きリクエストとセットで運用。
  • Vary: Accept-Languageなど、表現の選択に使ったリクエストヘッダーを指定。アクセス制御やprivateの代わりにはなりません。
  • Expires: 鮮度期限を日時で指定。max-ageがあればそちらが優先され、共有キャッシュではs-maxageが優先されます。

POSTレスポンスをキャッシュするとき

仕様上は可能ですが、条件が多いので意図しないキャッシュを避ける設定も重要です。

成立条件

  • max-ageやExpiresによる明示的な鮮度情報と、POSTの対象URIと同じ値のContent-Locationが必要です。
  • publicだけでは鮮度情報になりません。ステータスやno-storeなど、一般の保存条件も満たす必要があります。
  • 保存した応答は後続のGET/HEADに再利用できます。後続のPOSTをキャッシュで処理してはいけません。
  • ボディがユーザー固有ならprivateを付けてshared cacheに載らないようにする。

避けたい場合

  • Cache-Control: no-store を明示。機密データやトークン発行系では必須。
  • Authorization付きの要求への応答は、原則として共有キャッシュで後続の要求に再利用できません。public・s-maxage・must-revalidateには例外を許す意味があります(RFC 9111 §3.5)。個人向け応答へ安易に付けないでください。

再検証と無効化

GET/HEADは条件付きリクエストを活用し、変更時だけ再取得するのが効率的です。

再検証のコツ

  • ETagを返し、If-None-Matchで304を返せるようにする。
  • 保存させない指定はno-storeです。no-cacheは保存を許し、再利用の前に検証を要求します。max-age=0も保存禁止ではありません。
  • ETagの更新やサーバー側のヘッダー変更だけでは、既に新鮮な応答を持つキャッシュへ変更を通知できません。許容できる鮮度期間をあらかじめ設計し、CDNでは必要に応じてパージ機能を利用します。

まとめ

保存の可否と、保存後の再利用条件を分けて考えましょう。更新確認の流れは条件付きリクエストとETag、メソッドの性質はHTTPメソッドの解説を参照してください。

仕様・関連資料

RFC 9110 §9.3.3: POST / RFC 9111: HTTP Caching / RFC 5789 §2: PATCH