Skip to content

Commit be7d858

Browse files
martinbonninBoD
andauthored
Add documentation for cache-control options. (#212)
* Move cache-control up * favor present * Add documentation for cache options * Update Writerside/topics/options.md Co-authored-by: Benoit 'BoD' Lubek <[email protected]> * Update Writerside/topics/options.md Co-authored-by: Benoit 'BoD' Lubek <[email protected]> * Rename allowCachedErrors -> serverErrorsAsCacheMisses and allowCachePartialResults -> throwOnCacheMiss * Rename cache control -> expiration --------- Co-authored-by: Benoit 'BoD' Lubek <[email protected]>
1 parent 572163a commit be7d858

File tree

11 files changed

+77
-40
lines changed

11 files changed

+77
-40
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ _2024-12-18_
108108
# Version 0.0.4
109109
_2024-11-07_
110110

111-
- Cache control support (see [the documentation](https://apollographql.github.io/apollo-kotlin-normalized-cache-incubating/cache-control.html) for details)
111+
- Expiration support (see [the documentation](https://apollographql.github.io/apollo-kotlin-normalized-cache-incubating/expiration.html) for details)
112112
- Compatibility with the IntelliJ plugin cache viewer (#42)
113113
- For consistency, `MemoryCacheFactory` and `MemoryCache` are now in the `com.apollographql.cache.normalized.memory` package
114114
- Remove deprecated symbols

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ This repository hosts [Apollo Kotlin](https://github.com/apollographql/apollo-ko
1919
Compared to the previous version, this new normalized cache brings:
2020

2121
- [Pagination support](https://apollographql.github.io/apollo-kotlin-normalized-cache/pagination-home.html)
22-
- [Cache control](https://apollographql.github.io/apollo-kotlin-normalized-cache/cache-control.html) (a.k.a. Time to live or expiration)
22+
- [Expiration](https://apollographql.github.io/apollo-kotlin-normalized-cache/expiration.html) (a.k.a. Time to live)
2323
- [Garbage collection](https://apollographql.github.io/apollo-kotlin-normalized-cache/garbage-collection.html), and [trimming](https://apollographql.github.io/apollo-kotlin-normalized-cache/trimming.html)
2424
- Partial results from the cache
2525
- API simplifications

Writerside/doc.tree

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@
1111
<toc-element toc-title="Kdoc" href="https://apollographql.github.io/apollo-kotlin-normalized-cache/kdoc" />
1212
<toc-element topic="welcome.md" />
1313
<toc-element topic="migration-guide.md" />
14+
<toc-element topic="expiration.md" />
15+
<toc-element topic="options.md" />
1416
<toc-element topic="pagination-home.md">
1517
<toc-element topic="pagination-relay-style.md" />
1618
<toc-element topic="pagination-other.md" />
1719
<toc-element topic="pagination-manual.md" />
1820
</toc-element>
19-
<toc-element topic="cache-control.md" />
2021
<toc-element topic="garbage-collection.md" />
2122
<toc-element topic="trimming.md" />
2223
<toc-element topic="partial-cache-reads.md" />

Writerside/topics/compiler-plugin.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ apollo {
3030
}
3131
</code-block>
3232

33-
This plugin generates some code to support the Normalized Cache features, such as declarative cache IDs, pagination and cache control.
33+
This plugin generates some code to support the Normalized Cache features, such as declarative cache IDs, pagination and expiration.
3434

3535
## Declarative cache IDs (`@typePolicy`)
3636

Writerside/topics/cache-control.md renamed to Writerside/topics/expiration.md

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
# Cache control
1+
# Expiration
22

3-
The cache control feature takes the freshness of fields into consideration when accessing the cache. This is also sometimes referred to as TTL (Time To Live) or expiration.
3+
The cache can be configured to store expiration information using a max-age. This is also sometimes referred to as TTL (Time To Live) or freshness.
44

5-
Freshness can be configured by the server, by the client, or both.
5+
Max-age can be configured by the server, by the client, or both.
66

7-
## Server-controlled
7+
## Server-controlled max-age
88

9-
When receiving a response from the server, the [`Cache-Control` HTTP header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) can be used to determine the **expiration date** of the fields in the response.
9+
When receiving a response from the server, the [`Cache-Control` HTTP header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) can be used to determine the **max age** of the fields in the response.
1010

1111
> Apollo Server can be configured to include the `Cache-Control` header in responses. See the [caching documentation](https://www.apollographql.com/docs/apollo-server/performance/caching/) for more information.
1212
13+
> The [`Expires` HTTP header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Expires) is not supported. Only `Cache-Control` is.
14+
{style="note"}
15+
1316
The cache can be configured to store the **expiration date** of the received fields in the corresponding records. To do so, call [`.storeExpirationDate(true)`](https://apollographql.github.io/apollo-kotlin-normalized-cache/kdoc/normalized-cache/com.apollographql.cache.normalized/store-expiration-date.html?query=fun%20%3CT%3E%20MutableExecutionOptions%3CT%3E.storeExpirationDate(storeExpirationDate:%20Boolean):%20T), and set your client's cache resolver to [
1417
`CacheControlCacheResolver`](https://apollographql.github.io/apollo-kotlin-normalized-cache/kdoc/normalized-cache/com.apollographql.cache.normalized.api/-cache-control-cache-resolver/index.html):
1518

@@ -24,11 +27,11 @@ val apolloClient = ApolloClient.builder()
2427
.build()
2528
```
2629

27-
**Expiration dates** will be stored and when a field is resolved, the cache resolver will check if the field is stale. If so, it will throw a `CacheMissException`.
30+
**Expiration dates** are stored and when a field is resolved, the cache resolver will check if the field is stale. If so, it will return an error..
2831

29-
## Client-controlled
32+
## Client-controlled max-age
3033

31-
When storing fields, the cache can also store their **received date**. This date can then be compared to the current date when resolving a field to determine if its age is above its **maximum age**.
34+
When storing fields, the cache can also store their **received date**. This date can then be compared to the current date when resolving a field to determine if its age is above its **max age**.
3235

3336
To store the **received date** of fields, call [`.storeReceivedDate(true)`](https://apollographql.github.io/apollo-kotlin-normalized-cache/kdoc/normalized-cache/com.apollographql.cache.normalized/store-receive-date.html?query=fun%20%3CT%3E%20MutableExecutionOptions%3CT%3E.storeReceivedDate(storeReceivedDate:%20Boolean):%20T), and set your client's cache resolver to [
3437
`CacheControlCacheResolver`](https://apollographql.github.io/apollo-kotlin-normalized-cache/kdoc/normalized-cache/com.apollographql.cache.normalized.api/-cache-control-cache-resolver/index.html):
@@ -46,7 +49,7 @@ val apolloClient = ApolloClient.builder()
4649

4750
> Expiration dates and received dates can be both stored to combine server-controlled and client-controlled expiration strategies.
4851
49-
The **maximum age** of fields can be configured either programmatically, or declaratively in the schema. This is done by passing a [`MaxAgeProvider`](https://apollographql.github.io/apollo-kotlin-normalized-cache/kdoc/normalized-cache/com.apollographql.cache.normalized.api/-max-age-provider/index.html?query=interface%20MaxAgeProvider) to the `CacheControlCacheResolver`.
52+
The **max age** of fields can be configured either programmatically, or declaratively in the schema. This is done by passing a [`MaxAgeProvider`](https://apollographql.github.io/apollo-kotlin-normalized-cache/kdoc/normalized-cache/com.apollographql.cache.normalized.api/-max-age-provider/index.html?query=interface%20MaxAgeProvider) to the `CacheControlCacheResolver`.
5053

5154
### Global max age
5255

@@ -102,7 +105,7 @@ extend type Book @cacheControlField(name: "cachedTitle", maxAge: 30)
102105
extend type Reader @cacheControlField(name: "book", inheritMaxAge: true)
103106
```
104107

105-
This will generate a map in `yourpackage.cache.Cache.maxAges`, that you can pass to the `SchemaCoordinatesMaxAgeProvider`:
108+
This generates a map in `yourpackage.cache.Cache.maxAges`, that you can pass to the `SchemaCoordinatesMaxAgeProvider`:
106109

107110
```kotlin
108111
cacheResolver = CacheControlCacheResolver(
@@ -112,24 +115,3 @@ cacheResolver = CacheControlCacheResolver(
112115
)
113116
),
114117
```
115-
116-
## Maximum staleness
117-
118-
If stale fields are acceptable up to a certain value, you can set a maximum staleness duration. This duration is the maximum time that a stale field will be resolved without resulting in a cache miss. To set this duration, call [`.maxStale(Duration)`](https://apollographql.github.io/apollo-kotlin-normalized-cache/kdoc/normalized-cache/com.apollographql.cache.normalized/max-stale.html?query=fun%20%3CT%3E%20MutableExecutionOptions%3CT%3E.maxStale(maxStale:%20Duration):%20T) either globally on your client, or per operation:
119-
120-
```kotlin
121-
val response = client.query(MyQuery())
122-
.fetchPolicy(FetchPolicy.CacheOnly)
123-
.maxStale(1.hours)
124-
.execute()
125-
```
126-
127-
### `isStale`
128-
129-
With `maxStale`, it is possible to get data from the cache even if it is stale. To know if the response contains stale fields, you can check [`CacheInfo.isStale`](https://apollographql.github.io/apollo-kotlin-normalized-cache/kdoc/normalized-cache/com.apollographql.cache.normalized/-cache-info/is-stale.html):
130-
131-
```kotlin
132-
if (response.cacheInfo?.isStale == true) {
133-
// The response contains at least one stale field
134-
}
135-
```

Writerside/topics/garbage-collection.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ The garbage collection feature allows to remove unused data from the cache to re
77
A field is considered stale if its **received date** is older than its (client controlled) max age, or if its (server controlled)
88
**expiration date** has passed.
99

10-
See [](cache-control.md) for more information about staleness.
10+
See [](expiration.md) for more information about staleness.
1111

1212
Stale fields can be removed from the cache by calling the [`ApolloStore.removeStaleFields()`](https://apollographql.github.io/apollo-kotlin-normalized-cache/kdoc/normalized-cache/com.apollographql.cache.normalized/remove-stale-fields.html) function.
1313

Writerside/topics/migration-guide.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ interface CacheResolver {
196196

197197
`resolveField` can also now return a `ResolvedValue` when metadata should be returned with the resolved value (e.g. staleness).
198198

199-
If you wish to use the [Cache Control](cache-control.md) feature, a [`CacheControlCacheResolver`](https://apollographql.github.io/apollo-kotlin-normalized-cache/kdoc/normalized-cache/com.apollographql.cache.normalized.api/-cache-control-cache-resolver/index.html) should be used.
199+
If you wish to use the [Expiration](expiration.md) feature, a [`CacheControlCacheResolver`](https://apollographql.github.io/apollo-kotlin-normalized-cache/kdoc/normalized-cache/com.apollographql.cache.normalized.api/-cache-control-cache-resolver/index.html) should be used.
200200
You can call the generated `cache()` extension on `ApolloClient.Builder` which will use it by default if max ages are configured in the schema.
201201

202202
### `TypePolicyCacheKeyGenerator`

Writerside/topics/options.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Query options
2+
3+
When you execute a query, options control how the query is executed. `ApolloClient` returns an `ApolloResponse` that satisfies the options or an exceptional response otherwise (`response.exception` is not null).
4+
5+
## `fetchPolicy`
6+
7+
Fetch policy controls how and if the cache is used. The default is `CacheFirst`.
8+
9+
### `CacheFirst`
10+
11+
A response is fetched from the cache first. If no valid response cannot be found, the network is queried.
12+
13+
### `CacheOnly`
14+
15+
The response is fetched from the cache. If no valid response cannot be found, `response.exception` is set.
16+
17+
### `NetworkOnly`
18+
19+
The response is fetched from the network. If no valid response cannot be found, `response.exception` is set.
20+
21+
### `NetworkFirst`
22+
23+
A response is fetched from the network first. If no valid response cannot be found, the cache is queried.
24+
25+
## `serverErrorsAsCacheMisses`
26+
27+
Sets whether GraphQL errors in the cache should be treated as cache misses. When true (the default), if any field is an Error in the cache, the returned response will have a null data and a non-null exception of type `ApolloGraphQLException`.
28+
29+
## `throwOnCacheMiss`
30+
31+
Sets whether missing fields from the cache should result in an exception. When true (the default), if any field is missing in the cache, the returned response will have a null data and a non-null exception of type `CacheMissException`.
32+
33+
Set this to false to allow partial responses from the cache, where _some_ or _all_ of the fields may be missing.
34+
35+
## `maxStale`
36+
37+
If stale fields are acceptable up to a certain value, you can set a maximum staleness duration. This duration is the maximum time that a stale field will be resolved without resulting in a cache miss. To set this duration, call [`.maxStale(Duration)`](https://apollographql.github.io/apollo-kotlin-normalized-cache/kdoc/normalized-cache/com.apollographql.cache.normalized/max-stale.html?query=fun%20%3CT%3E%20MutableExecutionOptions%3CT%3E.maxStale(maxStale:%20Duration):%20T) either globally on your client, or per operation:
38+
39+
```kotlin
40+
val response = client.query(MyQuery())
41+
.fetchPolicy(FetchPolicy.CacheOnly)
42+
.maxStale(1.hours)
43+
.execute()
44+
```
45+
46+
### `isStale`
47+
48+
With `maxStale`, it is possible to get data from the cache even if it is stale. To know if the response contains stale fields, you can check [`CacheInfo.isStale`](https://apollographql.github.io/apollo-kotlin-normalized-cache/kdoc/normalized-cache/com.apollographql.cache.normalized/-cache-info/is-stale.html):
49+
50+
```kotlin
51+
if (response.cacheInfo?.isStale == true) {
52+
// The response contains at least one stale field
53+
}
54+
```

Writerside/topics/partial-cache-reads.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Partial cache reads
22

33
The cache supports partial cache reads, in a similar way to how GraphQL supports partial responses.
4-
This means that if some fields are missing from the cache, the cache will return the available data along with any errors for the missing fields.
4+
This means that if some fields are missing from the cache, the cache returns the available data along with any errors for the missing fields.
55

66
## With `ApolloStore`
77

Writerside/topics/trimming.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Trimming the cache
22

3-
By default, if you don't use [cache control](cache-control.md) and [garbage collection](garbage-collection.md),
3+
By default, if you don't use [expiration](expiration.md) and [garbage collection](garbage-collection.md),
44
the cache will grow indefinitely as more data is written to it.
55

66
To prevent this, a few APIs are available:

0 commit comments

Comments
 (0)