GraphQL SWR キャッシング (NestJS、コードファースト)
概要
意図によってキャッシュし、メカニズムによってキャッシュしないでください。単一のポリシー形状、単一の監視可能なイベントストリーム、単一のリクエストごとのトレース。デフォルトでサービスレベルにマウントし、測定された場合にのみフィールド/操作/トランスポートにエスカレーションします。
すべての決定を形作る3つの厳然たる事実:
- Apollo Server には組み込みの stale-while-revalidate がありません。 その
responseCachePluginは TTL のみで、操作レベルです。本当の SWR は、独自のレイヤー(async-cache-dedupe、または Mercurius ドライバー上のmercurius-cache)または CDN から得られます。 - スコープのデフォルトは
publicです。 パブリックエントリはすべての呼び出し元でそのまま共有されるため、結果がすべての呼び出し元でバイト単位で同一である場合にのみ正しいです。値が呼び出し元によって異なる場合は、perUserとマークする必要があります。そうしないとリークします。 - Nest インターセプターはサービスメソッドをラップせず、
@nestjs/cache-managerのCacheInterceptorは GraphQL では機能しません。 したがって、必要なサービスレベルのデコレータは、重複排除エンジン上のメソッドラッパーであり、フレームワークのインターセプターではありません。
使用するタイミング
- NestJS GraphQL(コードファースト)で、リゾルバー/サービスがデータベースまたは上流APIに繰り返しヒットする場合。
- TTL 期限切れ時のレイテンシスパイクとスタンピードを除去する必要がある場合(真のSWR)。
- マルチユーザーキャッシュの安全性/リークについて推論する必要がある場合。
- ヒット/スティッシュ/ミスの決定に対する可視性が必要な場合。
- キャッシュを完全にオフにする必要がある場合(開発、CI、またはインシデント)。1つのフラグで(セクション1、
setup-disable-switchを参照)。 - アプリにキャッシュ機能を初めて配線している場合(セクション1を参照)。
使用すべきでない場合:
- パブリックなGET/APQトラフィックに対して応答キャッシュを行うCDNの背後に既にいる場合は、そこから始めてください。
- 書き込み/ミューテーションパス、または再利用性が低く読み取り増幅が少ないユーザー固有データの場合(キャッシュは利益が少なくリスクが増加します)。
コールバック契約
key、@CacheTag、および @InvalidateTags は関数を受け取ります。引数を正しく設定しないと、キャッシュは静かにミスし、タグは静かにパージに失敗します。
| コールバック | シグネチャ | args とは |
|---|---|---|
key | (args, ctx) => unknown[] | Promise<unknown[]> | メソッドの引数リスト(呼び出し順) — args[0]、決して args.id ではない |
@CacheTag | (result, args) => string[] | null | 同じリスト。result はメソッドの戻り値 |
@InvalidateTags | (result, args) => string[] | 同じリスト。result は書き込みの戻り値 |
- 位置指定、名前指定ではありません。
getTitle(id: string)の場合、id はargs[0]です。 - 両方のタグコールバックで
resultが最初に来ます。 生エンジン自身のreferencesは(args, key, result)です。順序が異なり、最初の引数も異なります(driver-async-cache-dedupeを参照)。 ctx(userId、tenantId、locale、およびgen)はリクエストから派生し、buildCacheContextによってアセンブルされます。リクエスト外では空であるため、ジョブは必要なものを引数として渡します。- 型付け: デフォルトは
unknown[]/unknownです。タプル(@Cacheable<[string]>、@CacheTag<[string]>)に注釈を付けないと、コールバック本体がコンパイルされません。 - フィールドレベルは異なります: そこでは
argsはリゾルバーの名前付き引数オブジェクトであり、ctxは GraphQL コンテキストです(driver-mercurius-cache)。
完全な契約、キーバンドル { a, k, u }、およびシリアル化のエッジケースについては、policy-key-derivation を参照してください。ランタイム実装については、setup-decorator-runtime を参照してください。
優先順位別ルールカテゴリ
| 優先度 | カテゴリ | 影響 | プレフィックス |
|---|---|---|---|
| 1 | ワンタイムセットアップ | CRITICAL | setup- |
| 2 | キャッシュポリシー | CRITICAL | policy- |
| 3 | リーク安全性 | CRITICAL | safety- |
| 4 | 無効化 | HIGH | invalidation- |
| 5 | 可観測性 | MEDIUM | observability- |
| 6 | ドライバー | MEDIUM | driver- |
クイックリファレンス
1. ワンタイムセットアップ (CRITICAL)
setup-decorator-runtime- 安定した名前を持つメソッドラッパーとしてデコレータを実装するsetup-disable-switch- サービスレベルキャッシュをバイパスする1つの設定スイッチを提供するsetup-engine-choice- 重複排除エンジンを使用し、TTLを秒単位でカウントするsetup-fail-open- フェイルオープンし、エラーを決してキャッシュしないsetup-file-placement- 誰がインポートするかによって機能を配置するsetup-identity-context- Scope.REQUESTではなくAsyncLocalStorageから呼び出し元を読み取るsetup-module-wiring- キャッシュモジュールをforRootAsyncで一度だけ配線するsetup-storage-and-invalidation- 無効化を有効にし、referencesTTLとGCを設定する
2. キャッシュポリシー (CRITICAL)
policy-five-knobs- 5つのノブを知るpolicy-key-derivation- キーを自動的に導出し、JSON.stringifyを決して使用しないpolicy-mount-at-service- デフォルトでサービスレベルにマウントするpolicy-one-writing-pattern- デコレータが唯一の記述パターンであるpolicy-service-escape-hatch- サービスAPIはエスケープハッチであり、第二のパターンではない
3. リーク安全性 (CRITICAL)
safety-default-public- スコープのデフォルトは public — 呼び出し元によって変化する読み取りを perUser とマークするsafety-key-dimensions- スコープはユーザーのみをカバー — 他のすべての次元はキーに入れるsafety-no-leak-checklist- キャッシュされた読み取りごとにノーリークチェックリストを実行する
4. 無効化 (HIGH)
invalidation-after-success- 成功した書き込みの後にのみ無効化するinvalidation-atomic-purge- アトミックにパージし、タグのカーディナリティを制限するinvalidation-generation-prefix- 巨大または大まかなドメインにはジェネレーションプレフィックスを使用するinvalidation-tags-purge-only- タグはパージ専用であり、検索には使用しない
5. 可観測性 (MEDIUM)
observability-limits-of-events- エンジンが報告できないことを知るobservability-metrics-and-tests- 修正を証明するメトリクスを追跡し、結果でテストするobservability-per-request-trace- リクエストごとのトレースを公開し、GraphQLでは開発時のみにするobservability-structured-events- ログ文字列ではなく構造化キャッシュイベントを出力する
6. ドライバー (MEDIUM)
driver-apollo-response-cache- オプションC — Apollo responseCachePlugin(操作レベル、TTLのみ)driver-apollo-vs-mercurius- ドライバーからフィールドレベルオプションを選択するdriver-async-cache-dedupe- オプションA — async-cache-dedupe(サービスレベル、トランスポート非依存)driver-cdn-transport- オプションE — トランスポート / CDN SWR(公開読み取りのみ)driver-envelop-response-cache- オプションD — Envelop useResponseCache(NestJSネイティブではない)driver-federation-router- フェデレーションのみ — Apollo Router 応答キャッシュdriver-mercurius-cache- オプションB — mercurius-cache(フィールドレベル、真のSWR)driver-version-pinning- バージョンを固定する — この領域は変動しやすい
使用方法
まずワンタイムセットアップセクションから始め、次に目前の判断に関するポリシー、安全性、および無効化のルールを読んでください。ルールファイルは rules/ の下にあります:
rules/setup-module-wiring.md
rules/_sections.md
各ルールファイルには以下が含まれます:
- ルールの内容とそれが防ぐ障害
- 説明付きの誤った例
- 説明付きの正しい例
- 参考文献
完全なコンパイル済みドキュメント
すべてのルールが1つのドキュメントに展開された完全なガイドについては、AGENTS.md を参照してください。