Skip to content
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

How to prevent arrays inside cached object being overwritten? #6023

Open
isaacmanu opened this issue Jul 2, 2024 · 3 comments
Open

How to prevent arrays inside cached object being overwritten? #6023

isaacmanu opened this issue Jul 2, 2024 · 3 comments

Comments

@isaacmanu
Copy link

isaacmanu commented Jul 2, 2024

Question

Version 4.0.0-beta.4

Hi,

In our schema we have an object like this:

type SimpleUser implements User {

  id: ID!

  books: [Book]

  name: String!

  someObjects: [SomeObject]
}

And we have a CacheKeyGenerator like so:

class ApolloCacheKeyGenerator : CacheKeyGenerator {
    override fun cacheKeyForObject(obj: Map<String, Any?>, context: CacheKeyGeneratorContext): CacheKey? {
        return when (val typename = obj.getOrDefault("__typename", "")) {
            "SimpleUser" -> CacheKey("$typename:${obj["id"]}")
            else -> null
        }
    }
}

We can receive this SimpleUser object from multiple different queries, and each time we receive it, it can contain a different array of Book and SomeObject, which results in the newest received SimpleUser overwriting the previous one. Is there an easy way for me to merge the new and old arrays every time we receive a SimpleUser regardless of which query it comes from?

Thank you!

@BoD
Copy link
Contributor

BoD commented Jul 2, 2024

Hi!

One way is to use the ApolloStore API to manually store a SimpleUser that is a combination of the one existing in the cache, and the one you just received from the network. You'd have to do that at all the places that execute queries that return SimpleUser.

There are also incubating (experimental) APIs that allow to pass the desired merge algorithm, which will be called whenever an object needs to be merged. These exist to help with pagination scenarios but If you are willing to try experimental APIs I believe they could also be used for your use-case.

Both approaches are described in this document. Hope this helps!

@BoD BoD added 🗄️ Normalized cache ⌛ Waiting for info More information is required labels Jul 2, 2024
@isaacmanu
Copy link
Author

Thank you for your reply! And sorry for the slow follow up.

I'm trying to implement the second approach you listed above. However I'm running into this issue

Duplicate class com.apollographql.apollo3.cache.normalized.ApolloStore found in modules apollo-normalized-cache-incubating-jvm-4.0.0-beta.4.jar -> jetified-apollo-normalized-cache-incubating-jvm-4.0.0-beta.4 (com.apollographql.apollo3:apollo-normalized-cache-incubating-jvm:4.0.0-beta.4) and apollo-normalized-cache-jvm-4.0.0-beta.4.jar -> jetified-apollo-normalized-cache-jvm-4.0.0-beta.4 (com.apollographql.apollo3:apollo-normalized-cache-jvm:4.0.0-beta.4)

When attempting to import

implementation("com.apollographql.apollo3:apollo-runtime:4.0.0-beta.4")
implementation("com.apollographql.apollo3:apollo-normalized-cache-incubating:4.0.0-beta.4")

Any suggestions on how I could resolve this? For clarity's sake this is the only place we declare dependencies on Apollo.

@BoD
Copy link
Contributor

BoD commented Jul 18, 2024

Hmm it looks like your project depends on both apollo-normalized-cache and apollo-normalized-cache-incubating. Can you maybe try ./gradlew :app:dependencies to understand why?

By the way, head up that since the RC1 release of Apollo Kotlin 4, we've changed the group ids, and moved the incubating library outside of the main repository (a bit of context about this here) - so your dependencies should now be:

implementation("com.apollographql.apollo:apollo-runtime:4.0.0-rc.1")
implementation("com.apollographql.cache:apollo-normalized-cache-incubating:0.0.2")

Don't hesitate to let us know how that goes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants