ApolloStore
Apollo Kotlin exposes the ApolloStore
API to read and write from the normalized cache programmatically. The ApolloStore
sits on top of NormalizedCache
, exposes a thread safe API as well as methods that make it easier to read and write fragments and operations.
The store is accessible with the ApolloClient.apolloStore
extension:
val apolloClient = ApolloClient.Builder().serverUrl("https://example.com/graphql").normalizedCache(MemoryCacheFactory(maxSizeBytes = 10 * 1024 * 1024)).build()val apolloStore: ApolloStore = apolloClient.apolloStore
Reading operation data
Just like a regular GraphQL query, the main way to use the store is to read and write queries:
Given the following query:
query GetBook($id: String!) {book(id: $id) {titleauthor {name}}}
You can read it like this:
val data = apolloClient.apolloStore.readOperation(GetBookQuery(id = "42"), apolloClient.customScalarAdapters)println("Title=${data.title}")println("Author Name=${data.author.name}")
In the event of cache miss, readOperation
will throw:
try {apolloClient.apolloStore.readOperation(GetBookQuery(id = "42"), apolloClient.customScalarAdapters)} catch(e: CacheMissException) {println("CacheMiss on key: ${e.key}.${e.fieldName}")}
If you declared scalar adapters at runtime, pass your client's customScalarAdapters
to the store's methods, as the store will need them to convert scalar values to and from their Kotlin/Java types.
Writing operation data
Writing operation data is similar to reading:
apolloClient.apolloStore.writeOperation(GetBookQuery(id = "42"), data, apolloClient.customScalarAdapters)
Note how you'll need to pass the data allong the operation.
Reading and Writing fragments
In the GraphQL specification, fragments are always part of a larger operation and cannot be executed standalone.
fragment BookDetails on Book {idtitleauthor {name}}
Apollo Kotlin makes an exception to that rule and allows to read/write individual fragments. This is disabled by default and can be enabled with generateFragmentImplementations
:
apollo {service("service") {generateFragmentImplementations.set(true)}}
Because fragments are not rooted, you need to specify the root cache id of the fragment:
val data = apolloClient.apolloStore.readFragment(BookDetailsImpl(), CacheKey("42"), apolloClient.customScalarAdapters)println("Title=${data.title}")println("Author Name=${data.author.name}")
Fragments can contain variables. Different fragments with different variables can return different data. In that case the fragment Impl
class will require variables as constructor parameters:
fragment BookDetails on Book {idtitle(locale: $locale)}
val data = apolloClient.apolloStore.readFragment(BookDetailsImpl(locale = "en-US"), CacheKey("42"), apolloClient.customScalarAdapters)println("Title=${data.title}")
Clearing the cache
Call apolloClient.apolloStore.clearAll()
to clear the cache of all entries.