メソッドとキャッシュの関係
「このレスポンス、キャッシュされる?」を素早く判断するためのメモです。RFC 9110のキャッシュ仕様に合わせて、GET/HEAD/POSTの扱いをまとめました。
キャッシュの基本
HTTPキャッシュはメソッドとヘッダーの組み合わせで決まります。特にGET/HEADは明示がなければキャッシュ対象になり得ます。
メソッド別の前提
| メソッド | キャッシュ扱い | ポイント |
|---|---|---|
| GET | 対象 | レスポンスがshared cacheに載る前提。Cache-Controlで寿命を決める。 |
| HEAD | 対象 | GETと同じ扱い。ボディなし。 |
| POST | 原則非対象 | Cache-ControlやExpiresが明示され、かつステータスがキャッシュ可能な場合にのみ格納可(実務ではまれ)。 |
| PUT/PATCH/DELETE | 対象外 | ステート変更用のため格納されない(仕様ではキャッシュ無効)。 |
主なキャッシュ制御ヘッダー
レスポンスヘッダーがキャッシュの寿命や共有可否を決めます。
ヘッダーまとめ
- Cache-Control: max-age, s-maxage, no-cache, no-store, private, must-revalidate などで寿命と再検証ルールを指定。
- ETag/Last-Modified: 再検証に使うタグや日時。条件付きリクエストとセットで運用。
- Vary: Accept-Language, Authorization など、レスポンスが依存するリクエストヘッダーを列挙。CDNキャッシュでも必須。
- Expires: 旧式の期限指定。Cache-Controlが優先されるが併記されることが多い。
POSTレスポンスをキャッシュするとき
仕様上は可能ですが、条件が多いので意図しないキャッシュを避ける設定も重要です。
成立条件
- ステータスがキャッシュ可能(例: 200, 203, 204, 206, 300, 301, 404, 410など)であること。
- Cache-Controlに明示的に保存を許可する指示があること(public, max-age など)。
- Varyで適切に分岐を示すこと。示さないと別ユーザーの応答が混ざる恐れ。
- ボディがユーザー固有ならprivateを付けてshared cacheに載らないようにする。
避けたい場合
- Cache-Control: no-store を明示。機密データやトークン発行系では必須。
- Authorization付きリクエストはshared cacheではキャッシュ禁止がデフォルト(RFC 9110 13.5.2)。必要ならpublicを付けるが慎重に。
再検証と無効化
GET/HEADは条件付きリクエストを活用し、変更時だけ再取得するのが効率的です。
再検証のコツ
- ETagを返し、If-None-Matchで304を返せるようにする。
- キャッシュを必ず避けたいエンドポイントではCache-Control: no-storeまたはCache-Control: no-cache, max-age=0を付ける。
- Invalidate時は適切なバージョンアップ(ETag更新)か、Cache-Control: no-cacheで再検証を強制する。
まとめ
「GET/HEADはキャッシュ前提」「POSTは明示しない限りキャッシュされない」が基本線。Cache-ControlとETagを正しく返し、必要に応じてno-storeで締めておくと安心です。