Skip to content

Add migration guide #93

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
Feb 11, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Next version (unreleased)

- Add `ApolloStore.ALL_KEYS` to notify all watchers (#87)
- Support partial responses from the cache (#57)

# Version 0.0.5
_2024-12-18_
Expand Down
1 change: 1 addition & 0 deletions Writerside/doc.tree
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<toc-element toc-title="GitHub" href="https://github.com/apollographql/apollo-kotlin-normalized-cache-incubating" />
<toc-element toc-title="Kdoc" href="https://apollographql.github.io/apollo-kotlin-normalized-cache-incubating/kdoc" />
<toc-element topic="welcome.md" />
<toc-element topic="migration-guide.md" />
<toc-element topic="pagination-home.md">
<toc-element topic="pagination-relay-style.md" />
<toc-element topic="pagination-other.md" />
Expand Down
118 changes: 118 additions & 0 deletions Writerside/topics/migration-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Migration guide

> This guide is a work in progress

{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).

## Artifacts and packages

To use this library, update the dependencies to your project:

```kotlin
// build.gradle.kts
dependencies {
// Replace
implementation("com.apollographql.apollo:apollo-normalized-cache") // Memory cache
implementation("com.apollographql.apollo:apollo-normalized-cache-sqlite") // SQLite cache

// With
implementation("com.apollographql.cache:normalized-cache-incubating:%latest_version%") // Memory cache
implementation("com.apollographql.cache:normalized-cache-sqlite-incubating:%latest_version%") // SQLite cache
}
```

Note: the `com.apollographql.apollo:apollo-normalized-cache-api` artifact no longer exists, the code it contained has been merged into `com.apollographql.cache:normalized-cache-incubating`.

Then update your imports:

```kotlin
// Replace
import com.apollographql.apollo.cache.normalized.*

// With
import com.apollographql.cache.normalized.*
```

## Database schema

The SQLite cache now uses a different schema.

- Previously, records were stored as JSON in a text column.
- Now they are stored in an equivalent binary format in a blob column.

When this library opens an existing database and finds the old schema, it will **automatically delete** any existing data and create the new schema.

> This is a destructive operation.

{style="warning"}

If your application relies on the data stored in the cache, you can manually transfer all the records from the an old database to a new one.
See an example on how to do that [here](https://github.com/apollographql/apollo-kotlin-normalized-cache-incubating/blob/main/tests/migration/src/commonTest/kotlin/MigrationTest.kt#L157).

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
`readOperation()` now returns an `ApolloResponse<D>` (it previously returned a `<D>`). This allows for returning partial data from the cache, whereas
previously no data and a `CacheMissException` would be returned if any field was not found.

Now data with null fields (when possible) is returned with `Error`s in `ApolloResponse.errors` for any missing field

`ApolloResponse.cacheInfo.isCacheHit` will be false when any field is missing.

> The built-in `CacheFirst` and `CacheOnly` fetch policies treat any missing field as a full cache miss (same behavior as previous versions).
>
> You can implement your own fetch policy interceptor to handle partial cache reads, as shown in [this example](https://github.com/apollographql/apollo-kotlin-normalized-cache-incubating/blob/main/tests/partial-results/src/commonTest/kotlin/test/CachePartialResultTest.kt#L809).


### Publishing changes to watchers

Previously, write methods had 2 flavors:
- a `suspend` one that accepts a `publish` parameter to control whether changes should be published to watchers
- a non-suspend one (e.g. `writeOperationSync`) that doesn't publish changes

Now only the non-suspend ones exist and don't publish. Manually call `publish()` to notify watchers of changes.

```kotlin
// Replace
store.writeOperation(operation, data)
// With
store.writeOperation(operation, data).also { store.publish(it) }
```

### Other changes

- `readFragment()` now returns a `ReadResult<D>` (it previously returned a `<D>`). This allows for surfacing metadata associated to the returned data, e.g. staleness.


## 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
interface CacheResolver {
fun resolveField(
field: CompiledField,
variables: Executable.Variables,
parent: Map<String, @JvmSuppressWildcards Any?>,
parentId: String,
): Any?
}

// After
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).