mirror of
https://github.com/graphql-hive/console
synced 2026-05-24 09:38:26 +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
|
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.
|
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)
|
You can learn more about the behavior of the `@cacheControl` directive in the following section. If
|
||||||
- [See here for GraphQL Mesh to learn more about the `@cacheControl` in subgraph definitions](/docs/gateway/other-features/performance/response-caching)
|
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
|
## Session based caching
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue