Conversation
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
The structure and conceptual coverage are solid (when-to-use, cache-key composition, invalidation, operational pitfalls). The blocker is the configuration examples: they use a YAML schema that does not match the current Router and will not validate.
Specific accuracy issues:
-
Top-level key. The doc uses
preview_entity_cache. The current feature is configured underresponse_cache(see the siblingdocs/response-caching-guide.mdin this same repo, and the Apollo docs at graphos/routing/performance/caching/response-caching). Using a stale/preview key will mislead readers and fail config validation. -
Per-tenant / per-locale block is invented.
invalidation: { private: true }andcache_key_modifierswithcontext:/header:entries are not real Router config. Private/user-specific caching is configured withprivate_id(a context field pointing at e.g. the JWTsubclaim), and custom cache keys are set at runtime via theapollo::response_cache::keycontext entry (Rhai or coprocessor), not declarative YAML modifiers. As written, this section would steer SAs to a config that does not exist; given the section is specifically about preventing cross-user data leaks, the inaccuracy is high-risk. -
Debug logging target is unverified.
RUST_LOG="apollo_router::services::entity_cache=debug"references a module path that should be confirmed against the actual crate before publishing; recommend pointing at the cache debugger in Sandbox (as the sibling guide does) plus a verified log target. -
"See also" links point at
apollographql.com/docs/router/configuration/entity-caching/and a#cachecontrol-directiveanchor. The feature now lives undergraphos/routing/performance/caching/response-caching; verify all four links resolve before publishing.
The self-flagged Wayfair gap is acknowledged and acceptable for a first draft. The above are correctness issues that must be fixed before this is usable as SA/SE reference material, let alone upstreamed for Summit GA. Recommend reconciling every config snippet against the current response_cache reference and the sibling guide in this repo.
CI: only "Secrets in Source" runs and it passed; no automated link or schema checks exist here, so accuracy is on review.
|
|
||
| ## Configuration shape | ||
|
|
||
| ```yaml title="router.yaml — entity caching at the subgraph level" |
There was a problem hiding this comment.
preview_entity_cache is not the current config key. This feature is configured under response_cache (matching the sibling docs/response-caching-guide.md and the current Apollo docs). Update the key and reconcile the block against the response_cache reference; as written it will not validate.
There was a problem hiding this comment.
Verified at b8bf3d7: the stale preview_entity_cache key is gone. The configuration shape block now uses response_cache with subgraph.all (enabled, ttl, redis) and per-subgraph overrides under subgraph.subgraphs, matching the sibling docs/response-caching-guide.md and the current Apollo response-caching reference. This thread can be resolved.
| products: | ||
| invalidation: | ||
| private: true | ||
| # The cache key is composed of the JWT 'tenant' claim and an |
There was a problem hiding this comment.
invalidation: { private: true } and cache_key_modifiers are not real Router config. Use private_id (context field, e.g. JWT sub) for per-user caching, and set custom cache keys at runtime via the apollo::response_cache::key context entry (Rhai/coprocessor). This section is about preventing cross-user leaks, so the wrong syntax here is high-risk.
There was a problem hiding this comment.
Verified at b8bf3d7: the invented invalidation: { private: true } and cache_key_modifiers syntax is gone. Per-user caching now uses private_id pointing at a context field, and per-tenant/per-locale dimensions are set at runtime via the apollo::response_cache::key context entry from Rhai, which are the correct mechanisms. This thread can be resolved. One residual concern about the exact shape of that runtime cache-key value is raised separately in the review body so it stays tracked.
…hema (AS-240)
Address docs-reviewer feedback. The PR used `preview_entity_cache`, an
out-of-date top-level key; current Router (v2.6+) configures this under
`response_cache` (matching the sibling response-caching-guide and the
current Apollo docs). Also:
- Redis settings live under `subgraph.all.redis`, not at the top level.
- TTL placement: required under `subgraph.all.ttl`.
- Redis timeout bumped from 5ms (unrealistic — most lookups would time
out) to 200ms.
- Per-user/tenant caching uses the documented `private_id` field
pointing at a context entry (e.g. JWT `sub`), not the fictitious
`invalidation: { private: true }`.
- Custom multi-dimensional cache keys use the `apollo::response_cache::key`
context entry from Rhai/coprocessor, replacing the fictitious
`cache_key_modifiers` block.
- Repoint legacy /docs/router/... See-also links.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Re-reviewed at b8bf3d7. The two original blockers are fixed. The configuration block now uses the response_cache schema with subgraph.all and per-subgraph overrides, matching the sibling response-caching-guide.md and the current Apollo reference; and the per-tenant section now uses private_id plus the apollo::response_cache::key runtime context entry instead of the invented invalidation/cache_key_modifiers YAML. Both bot threads are addressed.
The rewrite introduces one new accuracy issue in the same cross-user-leak section, plus two smaller items, so this is not yet ready to approve.
-
Runtime cache-key shape (high-risk, inline). The Rhai snippet assigns a bare string to apollo::response_cache::key. Per the Apollo customization reference, that context entry takes a JSON object keyed by scope (all, subgraphs., or operation name); for example request.context[Router.APOLLO_RESPONSE_CACHE_KEY]["all"] = ... As written the flat string does not match the documented structure and would not segment the cache as intended, which is the exact failure mode this section is meant to prevent.
-
Rhai accessor shape (verify). The documented examples use supergraph_service with request.headers; this snippet uses subgraph_service with request.subgraph.headers and a nested request.context["apollo::authentication::jwt_claims"]?.tenant access. Confirm these accessors are valid in the current Rhai API before publishing.
-
private_id value (verify). The docs point private_id at a flat context key that you populate from the JWT sub claim via Rhai, not directly at a nested apollo::authentication::jwt_claims.sub path. Confirm the nested-path form resolves, or switch to the documented intermediate-key pattern.
Non-blocking: the two See also links use /caching/entity; the canonical feature now lives under /caching/response-caching, so verify those resolve. The self-flagged Wayfair gap remains acceptable for a first draft. Test plan checkboxes are still unchecked.
| service.map_request(|request| { | ||
| let tenant = request.context["apollo::authentication::jwt_claims"]?.tenant ?? "anon"; | ||
| let locale = request.subgraph.headers["accept-language"] ?? "*"; | ||
| request.context["apollo::response_cache::key"] = `tenant=${tenant};lang=${locale}`; |
There was a problem hiding this comment.
apollo::response_cache::key takes a JSON object keyed by scope (all, subgraphs., or operation name), not a flat string. Per the Apollo customization reference the pattern is request.context[Router.APOLLO_RESPONSE_CACHE_KEY]["all"] = . Assigning a bare tenant=...;lang=... string at the top level does not match the documented structure and would not segment cache entries as intended, which is the leak this section is meant to prevent. Set the value under all (or the relevant subgraph/operation field) instead.
- apollo::response_cache::key must be a JSON object keyed by scope (e.g. {"all": "..."}) not a bare string
- private_id: use an intermediate flat context key populated from JWT claims via Rhai, not a nested dotted path which is unreliably resolved
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
Adds
docs/entity-caching-best-practices.md. First-draft synthesis of public Apollo guidance covering: when entity caching pays off (and when it doesn't), TTL configuration shape, cache-key composition pitfalls (per-tenant / per-viewer caching — the most common source of cross-user data leaks), invalidation patterns, operational pitfalls (memory, thundering herd, in-process vs distributed cache), and verification via debug logs.Important
The original AS-240 ticket cites the Wayfair engagement as the primary source. This PR is a first-draft synthesis of public Apollo guidance and general patterns; a reviewer with access to the Wayfair notes should fold in customer-specific learnings before this is migrated to the public docs site at Summit GA.
Tracks AS-240.
Note
Placement: apollographql/docs archived; apollographql/platform-docs requires SAML grant.
Test plan
🤖 Generated with Claude Code