From 6866315e49dfd5a8e02bebc124fb154eaf423870 Mon Sep 17 00:00:00 2001 From: Mandi Wise Date: Thu, 22 Jul 2021 16:09:28 -0600 Subject: [PATCH 1/2] Update caching docs to include federation support. --- docs/source/performance/caching.md | 42 ++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/docs/source/performance/caching.md b/docs/source/performance/caching.md index 16a17e5e411..9311b45d878 100644 --- a/docs/source/performance/caching.md +++ b/docs/source/performance/caching.md @@ -6,8 +6,6 @@ description: Configure caching behavior on a per-field basis > **New in Apollo Server 3**: You must manually define the `@cacheControl` directive in your schema to use static cache hints. [See below.](#in-your-schema-static) -> Note: Apollo Federation doesn't currently support @cacheControl out-of-the-box. There is [an issue](https://github.com/apollographql/federation/issues/356) on the Federation repo which discusses this and proposes possible workarounds. - Apollo Server enables you to define cache control settings (`maxAge` and `scope`) for each field in your schema: ```graphql{5,7} @@ -292,6 +290,46 @@ query GetReaderBookTitle { } ``` +## Using with federation + +When using [Apollo Federation](https://www.apollographql.com/docs/federation), the `@cacheControl` directive and `CacheControlScope` enum may be defined in a subgraph's schema. An Apollo Server-based subgraph will calculate and set the cache hint for the response that it sends to the gateway as it would for a non-federated Apollo Server sending a response to a client. The gateway will then calculate the cache hint for the overall response based on the most restrictive settings among all of the responses received from the subgraphs involved in query plan execution. + +### Setting entity cache hints + +Subgraph schemas contain an `_entities` root field on the `Query` type, so all query plans that require entity resolution will have a [`maxAge` of `0` set by default](#default-maxage). To override this default behavior, you can add a `@cacheControl` directive to an entity's definition: + +```graphql +type Book @key(fields: "isbn") @cacheControl(maxAge: 30) { + isbn: String! + title: String +} +``` + +When the `_entities` field is resolved it will check the applicable concrete type for a cache hint (which would be the `Book` type in the example above) and apply that hint instead. + +To set cache hints dynamically, the [`cacheControl` object and its methods](#in-your-resolvers-dynamic) are also available in the `info` parameter of the `__resolveReference` resolver. + +### Overriding subgraph cache hints in the gateway + +If a subgraph does not specify a `max-age`, the gateway will assume its response (and +in turn, the overall response) cannot be cached. To override this behavior, you can set the `Cache-Control` header in the `didReceiveResponse` method of a `RemoteGraphQLDataSource`. + +Additionally, if the gateway should ignore `Cache-Control` response headers from subgraphs that will affect the operation's cache policy, then you can set the `honorSubgraphCacheControlHeader` property of a `RemoteGraphQLDataSource` to `false` (this value is `true` by default): + +```javascript +const gateway = new ApolloGateway({ + // ... + buildService({ url }) { + return new RemoteGraphQLDataSource({ + url, + honorSubgraphCacheControlHeader: false; + }); + } +}); +``` + +The effect of setting `honorSubgraphCacheControlHeader` to `false` is to have no impact on the cacheability of the response in either direction. In other words, this property won’t determine whether the response can be cached, but it does exclude a subgraph's `Cache-Control` header from consideration in the gateway's calculation. If all subgraphs are excluded from consideration when calculating the overall `Cache-Control` header, the response sent to the client will not be cached. + ## Caching with a CDN Whenever Apollo Server sends an operation response that has a non-zero `maxAge`, it includes a `Cache-Control` HTTP header that describes the response's cache policy. From b73569f5097fc5e314738f5ae58f427900104aeb Mon Sep 17 00:00:00 2001 From: David Glasser Date: Tue, 3 Aug 2021 10:59:37 -0700 Subject: [PATCH 2/2] Add minimum version requirements --- docs/source/performance/caching.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/performance/caching.md b/docs/source/performance/caching.md index 9311b45d878..9367981986b 100644 --- a/docs/source/performance/caching.md +++ b/docs/source/performance/caching.md @@ -292,6 +292,8 @@ query GetReaderBookTitle { ## Using with federation +> Using cache control with Apollo Federation requires v0.28 of `@apollo/federation` in your subgraph, v0.36 of `@apollo/gateway` in your router, and v3.0.2 of Apollo Server in both servers. + When using [Apollo Federation](https://www.apollographql.com/docs/federation), the `@cacheControl` directive and `CacheControlScope` enum may be defined in a subgraph's schema. An Apollo Server-based subgraph will calculate and set the cache hint for the response that it sends to the gateway as it would for a non-federated Apollo Server sending a response to a client. The gateway will then calculate the cache hint for the overall response based on the most restrictive settings among all of the responses received from the subgraphs involved in query plan execution. ### Setting entity cache hints