question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Restore API does not retain ROOT_QUERY, ROOT_MUTATION

See original GitHub issue

Intended outcome:

Calling cache.gc() after the cache is restored using a tool like https://github.com/apollographql/apollo-cache-persist should not remove all entities in the cache and only remove unreachable entities.

Actual outcome:

Calling cache.gc() after the cache is restored using a tool like https://github.com/apollographql/apollo-cache-persist removes all entities in the cache.

Explanation

It looks like this happens because when you call cache.restore(data) as defined here: https://github.com/apollographql/apollo-client/blob/master/src/cache/inmemory/inMemoryCache.ts#L99

and subsequently call EntityStore replace: https://github.com/apollographql/apollo-client/blob/master/src/cache/inmemory/entityStore.ts#L238

it hydrates the cache, but never calls retain on any ID. Normally, the ROOT_QUERY is retained by a write to the store: https://github.com/apollographql/apollo-client/blob/master/src/cache/inmemory/writeToStore.ts#L114:L114

but if nothing has been written to the store yet, and gc is called immediately after a cache.restore using a tool like cache-persist, then there are no rootIds retained and the entire cache will get garbage collected.

I think the solution would be to either:

  1. Default the rootIds to include ROOT_QUERY and ROOT_MUTATION on cache instantiation so that they are not lazily retained on a call to writeToStore but assumed to be desired to be retained by default
  2. Retain ROOT_QUERY and ROOT_MUTATION if a call to cache.restore includes those keys at the time restore is called
  3. Have downstream tools like cache-persist know that after doing a restore, they will need to retain IDs they care about like ROOT_QUERY and ROOT_MUTATION. I think this is a riskier approach, because as a user I would assume that ROOT_QUERY should be retained by default based on the documentation of cache.gc():
Screen Shot 2020-11-13 at 11 26 21 AM

I think rootIds is not a familiar term to most folks in these docs and they’d assume that unreachable would mean that there are things like dangling normalized entities, not potentially the ROOT_QUERY itself.

Let me know what your thoughts are, thanks!

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
loteoocommented, Dec 13, 2020

@benjamn Genius, I was indeed importing getDataFromTree from @apollo/react-ssr. I switched the import to @apollo/client/react/ssr and it’s working properly with newer versions (now 3.3.6)

Thanks so much and sorry for the distraction!

1reaction
benjamncommented, Dec 11, 2020

@loteoo If you’re not calling cache.gc() in that code, this issue (#7323) probably isn’t the cause of your problems, but getting an empty object is definitely strange/worrisome!

A couple more questions:

  1. Are you importing getDataFromTree from @apollo/client/react/ssr?
  2. Are you importing ApolloProvider from @apollo/client (or @apollo/client/react/context)?

The older @apollo/react-* packages should no longer be used.

Read more comments on GitHub >

github_iconTop Results From Across the Web

GraphQL Mutation vs Query – When to use a GraphQL Mutation
If queries are the GraphQL equivalent to GET calls in REST, then mutations represent the state-changing methods in REST (like DELETE , PUT...
Read more >
Required service for type RootQuery not found in ASP.NET ...
This answer is useful. 1. This answer is not useful. Save this answer. Show activity on this post. Add RootQuery to your service...
Read more >
GraphQL: Mutation and Database Access - DEV Community ‍ ‍
This post shows how to use the context argument that every resolver function receives, implement GraphQL mutation, and work with Prisma as ...
Read more >
How to build a GraphQL API backend with Express and ...
GraphQL is a querying language and thus it's optimized to retrieve the specified data, unlike Rest APIs where data retrieved either has ......
Read more >
Getting Started with GraphQL and Spring Boot - Baeldung
Discover GraphQL - a query language for APIs. ... client doesn't request a field, then the GraphQL Server won't do the work to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found