mirror of
https://github.com/graphql-hive/console
synced 2026-05-16 13:48:18 +00:00
Improve documentation of @cacheControl (#6161)
This commit is contained in:
parent
5a6e565be4
commit
0565b2aacb
1 changed files with 196 additions and 2 deletions
|
|
@ -64,8 +64,202 @@ The behaviour of this plugin can be configured by passing an object at the gatew
|
|||
The `@cacheControl` directive can be used to give to subgraphs the control over the cache behavior
|
||||
for the fields and types they are defining. You can add this directive during composition.
|
||||
|
||||
- [See here for Federation to learn more about the `@cacheControl` directive](https://www.apollographql.com/docs/federation/performance/caching/#using-cache-hints-with-subgraphs)
|
||||
- [See here for GraphQL Mesh to learn more about the `@cacheControl` in subgraph definitions](/docs/gateway/other-features/performance/response-caching)
|
||||
You can learn more about the behavior of the `@cacheControl` directive in the following section. If
|
||||
you want to use the configuration API on the gateway, you can skip the `@cacheControl` directive
|
||||
section.
|
||||
|
||||
### `@cacheControl` directive's behavior
|
||||
|
||||
This directive allows you to control response caching from the subgraph. But the behavior can be
|
||||
different depending on the subgraph configuration.
|
||||
|
||||
The following 3 section shows the ways of using the `@cacheControl` directive in different ways. The
|
||||
usage examples in the other sections represent the third(last) use case in the following three.
|
||||
|
||||
#### Apollo Server with `Cache-Control` header (This response cache plugin is not required)
|
||||
|
||||
Apollo Server handles `@cacheControl` directives to set HTTP caching headers in the HTTP response to
|
||||
the gateway. Then the gateway can cache the response based on these headers.
|
||||
[Learn more about Apollo Server's cache control behavior](https://www.apollographql.com/docs/apollo-server/performance/caching).
|
||||
In this case, gateway is still response of caching the response. Hive Gateway can handle http
|
||||
caching headers using [HTTP Caching plugin](/docs/gateway/other-features/performance/http-caching).
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["GraphQL Client"] -->|"GraphQL Request"| B(Go shopping)
|
||||
B("Hive Gateway") --> C{Let me think}
|
||||
C -->|"Cache Hit"| D["Get the cached response from Cache Storage"]
|
||||
C -->|"Not Cached"| E["Send HTTP Response Back"]
|
||||
C{"Subgraph Executor"}
|
||||
D ---|"Return the cached response"| C
|
||||
E
|
||||
E ---|"Get 'Cache-Control' header, and store the response for the following requests"| C{"Subgraph Executor gets the query"}
|
||||
```
|
||||
|
||||
##### Example
|
||||
|
||||
Let's say you have a subgraph that defines a `Post` type with a `@cacheControl` directive, your Hive
|
||||
Gateway has [HTTP Caching plugin](/docs/gateway/other-features/performance/http-caching) enabled.
|
||||
|
||||
```graphql
|
||||
type Post @cacheControl(maxAge: 240) {
|
||||
id: Int!
|
||||
title: String
|
||||
}
|
||||
```
|
||||
|
||||
When the gateway receives a query that selects the `Post` type, it will cache the response for 240
|
||||
seconds.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
posts {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In this case, the gateway will cache the response for 240 seconds. If the same query is made within
|
||||
240 seconds, the gateway will return the cached response.
|
||||
|
||||
#### GraphQL Yoga with the response caching plugin (This response cache plugin is not required)
|
||||
|
||||
On the other hand, GraphQL Yoga handles `@cacheControl` directives to configure the response caching
|
||||
behavior rather than `Cache-Control` headers like Apollo Server. It leverages `ETag` headers to
|
||||
cache the response and invalidate it by mutations.
|
||||
[Learn more about GraphQL Yoga's response caching behavior](https://the-guild.dev/graphql/yoga-server/docs/features/response-caching).
|
||||
So even if nothing is configured on the gateway but Yoga on the subgraph uses the response caching
|
||||
plugin on its own. But this won't reduce the HTTP connection traffic in between gateway and
|
||||
subgraph.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["GraphQL Client"]
|
||||
B(Go shopping)
|
||||
B("Hive Gateway")
|
||||
E["Send HTTP Response Back"]
|
||||
E
|
||||
E["Subgraph Yoga Server"]
|
||||
E --- n1["Response Cache Plugin"]
|
||||
n1 ---|"If Cached"| n2["Get the cached response from Cache Storage"]
|
||||
n1 ---|"If Not Cached"| n3["Prepare the result by making database calls etc, and store it for the future calls"]
|
||||
subgraph B["Hive Gateway"]
|
||||
n5
|
||||
n4["Query Planner"]
|
||||
end
|
||||
n4
|
||||
n4 ---|"Generate Subgraph Query"| n5["Execution Engine"]
|
||||
n5
|
||||
E
|
||||
B
|
||||
n5
|
||||
n5
|
||||
n5 ---|"HTTP Request"| E
|
||||
A --- B
|
||||
```
|
||||
|
||||
##### Example
|
||||
|
||||
Let's say you have a subgraph that defines a `Post` type with a `@cacheControl` directive, your Hive
|
||||
Gateway has [HTTP Caching plugin](/docs/gateway/other-features/performance/http-caching) enabled.
|
||||
|
||||
```graphql
|
||||
type Post @cacheControl(maxAge: 240) {
|
||||
id: Int!
|
||||
title: String
|
||||
}
|
||||
```
|
||||
|
||||
When the gateway receives a query that selects the `Post` type, it will forward the request to the
|
||||
subgraph directly.
|
||||
|
||||
```graphql
|
||||
query {
|
||||
posts {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then Yoga Server will generate the response and cache it for 240 seconds. If the same query is made
|
||||
within 240 seconds, Yoga Server will return the cached response. So it will always receive the HTTP
|
||||
request but do the less work to generate the response. The difference between others, this case
|
||||
won't reduce the HTTP connection traffic in between gateway and subgraph, but it will reduce the
|
||||
work that subgraph needs to do to generate the response.
|
||||
|
||||
#### Subgraphs with any server implementation using directives directly (This response cache plugin is required)
|
||||
|
||||
Besides these two, you can let the gateway handle the caching on its own. In this case, you need to
|
||||
define the following in the subgraphs so the supergraph has `@cacheControl` directives. Then, the
|
||||
response caching plugin on the gateway will handle the caching based on these directives.
|
||||
|
||||
```graphql
|
||||
extend schema
|
||||
@link(
|
||||
# Federation spec version should be at least 2.1 to support `@composeDirective`
|
||||
url: "https://specs.apollo.dev/federation/v2.1"
|
||||
import: ["@composeDirective"]
|
||||
)
|
||||
# Import `@cacheControl`
|
||||
@link(url: "https://the-guild.dev/mesh/v1.0", import: ["@cacheControl"])
|
||||
# Use `@composeDirective` to define the directive as exposed
|
||||
@composeDirective(name: "@cacheControl")
|
||||
|
||||
# Then add the actual directive definitions
|
||||
enum CacheControlScope {
|
||||
PUBLIC
|
||||
PRIVATE
|
||||
}
|
||||
|
||||
directive @cacheControl(
|
||||
maxAge: Int
|
||||
scope: CacheControlScope
|
||||
inheritMaxAge: Boolean
|
||||
) on FIELD_DEFINITION | OBJECT | INTERFACE | UNION
|
||||
```
|
||||
|
||||
In this case, the gateway will cache the response based on the `@cacheControl` directives defined in
|
||||
the subgraphs.
|
||||
|
||||
The difference between the two is that the gateway will control the caching behavior based on the
|
||||
`@cacheControl` directives defined in the subgraphs. For any cached responses, the gateway will skip
|
||||
query planning and federation execution phase, and return the response directly.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["GraphQL Client"]
|
||||
B(Go shopping)
|
||||
B("Hive Gateway")
|
||||
E["Send HTTP Response Back"]
|
||||
E
|
||||
E["Subgraph Yoga Server"]
|
||||
E --- n1["Response Cache Plugin"]
|
||||
n1 ---|"If Cached"| n2["Get the cached response from Cache Storage"]
|
||||
n1 ---|"If Not Cached"| n3["Prepare the result by making database calls etc, and store it for the future calls"]
|
||||
subgraph B["Hive Gateway"]
|
||||
n7["Get Stored Response"]
|
||||
n6["Response Caching Plugin"]
|
||||
n5
|
||||
n4["Query Planner"]
|
||||
end
|
||||
n4
|
||||
n4 ---|"Generate Subgraph Query"| n5["Execution Engine"]
|
||||
n5
|
||||
E
|
||||
B
|
||||
n5
|
||||
n5
|
||||
n5 ---|"HTTP Request"| E
|
||||
A
|
||||
B
|
||||
n6 ---|"If Not Cached"| n4
|
||||
n6 ---|"If Cache Hit"| n7
|
||||
n7 ---|"Respond Cached Response back to Client"| A
|
||||
n5 ---|"Store the response for future calls"| n6
|
||||
A ---|"Send GraphQL Request via HTTP "| n6
|
||||
```
|
||||
|
||||
## Session based caching
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue