Skip to content

Update migration guide changelog and welcome page #158

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Next version (unreleased)

- The computation of cache keys when multiple key fields are used has changed to avoid potential collisions. Note: this can lead to cache misses after upgrading to this version. (#80)
- Make SQL cache more robust. (#152)
- Support simple list cases in `FieldPolicyCacheResolver`. (#142)
- Fragments selecting the key fields are now automatically added for union members and interface possible types by the compiler plugin. (#141)
- Introduce `CacheKey.Scope`. (#102)

# Version 1.0.0-alpha.1

Expand Down
93 changes: 75 additions & 18 deletions Writerside/topics/migration-guide.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
# Migration guide

> This guide is a work in progress
The Apollo Kotlin Normalized Cache used to be part of the [Apollo Kotlin main repository](https://github.com/apollographql/apollo-kotlin).
It is now hosted in this dedicated repository and published at its own cadence and versioning scheme.

{style="warning"}

This guide highlights the main differences between this library and the version hosted on the
[main Apollo Kotlin repository](https://github.com/apollographql/apollo-kotlin).
This guide highlights the main differences between this library and the "classic" version, and how to migrate to it.

## Artifacts and packages

Expand Down Expand Up @@ -42,6 +40,23 @@ import com.apollographql.cache.normalized.memory.MemoryCacheFactory

In most cases, this will be enough to migrate your project, but there were a few renames and API breaking changes. Read on for more details.

## Compiler plugin

Configure the compiler plugin in your `build.gradle.kts` file:

```kotlin
apollo {
service("service") {
packageName.set("com.example")

// Add this
plugin("com.apollographql.cache:normalized-cache-apollo-compiler-plugin:%latest_version%") {
argument("packageName", packageName.get())
}
}
}
```

## Database schema

The SQLite cache now uses a different schema.
Expand All @@ -60,10 +75,6 @@ See an example on how to do that [here](https://github.com/apollographql/apollo-

Make sure you thoroughly test migration scenarios before deploying to production.

> Expect more changes to the schema as the library evolves and stabilizes.

{style="warning"}

## `ApolloStore`

### Partial cache reads
Expand Down Expand Up @@ -108,14 +119,14 @@ Previously, if you configured custom scalar adapters on your client, you had to
Now, `ApolloStore` has a reference to the client's `CustomScalarAdapters` so individual methods no longer need an adapters argument.

```kotlin
// Before
// Replace
client.apolloStore.writeOperation(
operation = operation,
data = data,
customScalarAdapters = client.customScalarAdapters
)

// After
// With
client.apolloStore.writeOperation(
operation = operation,
data = data
Expand All @@ -128,7 +139,7 @@ The `ApolloStore` interface has been renamed to `CacheManager`. If you provide y
Correspondingly, the `ApolloClient.Builder.store()` extension has been renamed to `ApolloClient.Builder.cacheManager()`.

```kotlin
// Before
// Replace
val MyStore = object : ApolloStore {
// ...
}
Expand All @@ -137,7 +148,7 @@ val apolloClient = ApolloClient.Builder()
.store(MyStore)
.build()

// After
// With
val MyStore = object : CacheManager {
// ...
}
Expand All @@ -152,13 +163,13 @@ val apolloClient = ApolloClient.Builder()
- `readFragment()` now returns a `ReadResult<D>` (it previously returned a `<D>`). This allows for surfacing metadata associated to the returned data, e.g. staleness.
- Records are now rooted per operation type (`QUERY_ROOT`, `MUTATION_ROOT`, `SUBSCRIPTION_ROOT`), when previously these were all at the same level, which could cause conflicts.

## CacheResolver, CacheKeyResolver
## `CacheResolver`, `CacheKeyResolver`

The APIs of `CacheResolver` and `CacheKeyResolver` have been tweaked to be more future-proof. The main change is that the methods now takes a `ResolverContext` instead of
individual parameters.

```kotlin
// Before
// Replace
interface CacheResolver {
fun resolveField(
field: CompiledField,
Expand All @@ -168,23 +179,69 @@ interface CacheResolver {
): Any?
}

// After
// With
interface CacheResolver {
fun resolveField(context: ResolverContext): Any?
}
```

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

### CacheKey
### `TypePolicyCacheKeyGenerator`

You can now pass the type policies to the `TypePolicyCacheKeyGenerator` constructor, and it is recommended to do so.
The type policies are generated by the compiler plugin in `yourpackage.cache.Cache.typePolicies`.

If your entities ids are unique across the service, you can pass `CacheKey.Scope.SERVICE` to the `TypePolicyCacheKeyGenerator` constructor
to save space in the cache and improve hit rates in certain cases.

```kotlin
// Replace
val apolloClient = ApolloClient.Builder()
// ...
.normalizedCache(cacheFactory)
.build()

// With
val apolloClient = ApolloClient.Builder()
// ...
.normalizedCache(
cacheFactory,
cacheKeyGenerator = TypePolicyCacheKeyGenerator(
typePolicies = Cache.typePolicies,
keyScope = CacheKey.Scope.SERVICE // defaults to TYPE
)
)
.build()
```

### `FieldPolicyCacheResolver`

- `FieldPolicyCacheResolver` now supports simple list cases. If your field takes a flat list of ids, you no longer need to implement a custom `CacheResolver` for it and can use `@fieldPolicy`.
- As for `TypePolicyCacheKeyGenerator`, you can pass `CacheKey.Scope.SERVICE` to the constructor if your ids are unique across the service:

```kotlin
val apolloClient = ApolloClient.Builder()
// ...
.normalizedCache(
cacheFactory,
cacheKeyGenerator = /*...*/,
cacheResolver = FieldPolicyCacheResolver(
keyScope = CacheKey.Scope.SERVICE // defaults to TYPE
)
)
.build()
```

## CacheKey

For consistency, the `CacheKey` type is now used instead of `String` in more APIs, e.g.:

- `ApolloStore.remove()`
- `Record.key`
- `NormalizedCache.loadRecord()`

### Removed APIs
## Removed APIs

- `ApolloCacheHeaders.EVICT_AFTER_READ` is removed. Manually call `ApolloStore.remove()` when needed instead.
- `NormalizedCache.remove(pattern: String)` is removed. Please open an issue if you need this feature back.
17 changes: 9 additions & 8 deletions Writerside/topics/welcome.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# Welcome

This repository hosts [Apollo Kotlin](https://github.com/apollographql/apollo-kotlin)'s new normalized cache, aiming to replace the main repository version.
This is [Apollo Kotlin](https://github.com/apollographql/apollo-kotlin)'s Normalized Cache.

For an introduction please read the Normalized Cache [documentation](https://www.apollographql.com/docs/kotlin/caching/normalized-cache).

Note: the Normalized Cache used to be part of the [Apollo Kotlin main repository](https://github.com/apollographql/apollo-kotlin).
It is now hosted in a dedicated repository and published at its own cadence and versioning scheme.

## Use in your project

> This version is not yet stable and is subject to change. It is recommended to experiment with it in
> non-critical projects/modules, or behind a feature flag.
>
> In particular,
> - there are no guarantees about the format of the cached data, so you should assume that it may be lost when upgrading
> - performance and size may not be optimal
> During the alpha phase, the API is still subject to change, although we will try to make changes in non-breaking ways.
> For now it is recommended to experiment with this library in non-critical projects/modules, or behind a feature flag.

{style="warning"}

Expand All @@ -26,4 +27,4 @@ dependencies {
}
```

If you were using the stable Normalized Cache before, you can update your imports to the new package, `com.apollographql.cache.normalized.*`.
If you were using the classic Normalized Cache before, please consult the [migration guide](migration-guide.md).