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

Add example for direct writing to the cache #1440

Closed
michael-mckenna opened this issue Oct 6, 2020 · 11 comments
Closed

Add example for direct writing to the cache #1440

michael-mckenna opened this issue Oct 6, 2020 · 11 comments
Labels
caching docs Focuses on documentation changes

Comments

@michael-mckenna
Copy link

Feature request

Add examples for writing directly to the cache, hopefully for all variants of the "write" function:

transaction.write(object:withKey:)
transaction.write(data:forQuery:)
transaction.write(object:withKey:variables:)

Looks like only read and update are in the docs at the moment.
https://github.com/apollographql/apollo-ios/blob/main/docs/source/caching.mdx#direct-cache-access

Motivation

I'm new to GraphQL and using it for a side project has a learning experience. I don't want to get the whole server and datasource set up yet - would like to just do the iOS portion and have some sort of proof of concept going before pursuing it further. Because of this, I'm using the direct cache access exclusively for now. The extra examples in the readme will help me and future devs a lot. I come from using Realm and Core Data so this is quite a bit different for me.

Outstanding Questions

Is there a sample app that utilizes direct cache access? If so, it'd be great to add a reference to that.

@designatednerd
Copy link
Contributor

Hi, I can certainly add one, but I will say that the idea is that you avoid manually reading from or writing to the cache unless you absolutely have to, and let the store handle most of the nonsense around dealing with cache keys and things like that.

If it's your first time messing around with it and you just want to get an idea of how it works, I'd recommend checking out the app from the Tutorial, which uses a server that's already set up. You can then more easily inspect how things go into the in-memory cache or, if you want to, you can switch to using the SQLite cache and examine the SQLite database.

That will also allow you to have a base to mess around from if you are interested in seeing how the writing works if you need it.

@designatednerd designatednerd added caching docs Focuses on documentation changes labels Oct 6, 2020
@Nickersoft
Copy link
Contributor

@designatednerd Just to clarify, it is still the expectation though that you should use manual cache updating after mutations / incoming subscriptions, correct? Recently I started to receive JSON missingValue errors in my cache updates and I'm not sure if it has anything to do with the major architectural changes that have been going on.

@designatednerd
Copy link
Contributor

Subscriptions don't hit the cache at all at the moment - I wasn't part of that decision but it makes sense from a standpoint of "This is constantly changing information, we don't necessarily want to cache all of it", and also from a performance standpoint. So yes, that you'd need to do manually.

Mutation results can update the cache, though if you're not using a cacheKeyForObject function that says the cache key should be based on a unique identifier, you will need to update any related queries manually.

@morgz
Copy link
Contributor

morgz commented Mar 8, 2021

Mutation results can update the cache, though if you're not using a cacheKeyForObject function that says the cache key should be based on a unique identifier, you will need to update any related queries manually.

Thanks for asking this question as it touches on what I'm just implementing.

This is my current flow:

  • Mutation adds a favourite item to a users favourites.
  • After a successful mutation I add this object to Query which lists the favourites.

What I'm finding rather fiddly is the translation of the Mutation Result to the Query result to append to the List array. I couldn't find good documentation on this, so I'm not sure if I'm doing it right, or haven't found the documentation.

I have to transform object A:

CreateUserExerciseFavouriteMutation.Data.CreateUserExerciseFavourite.UserExerciseFavourite

object into object B

UserExerciseFavouriteListQuery.Data.UserExerciseFavourite.Entry

and to do this I'm using this:

UserExerciseFavouriteListQuery.Data.UserExerciseFavourite.Entry(unsafeResultMap: objectA.resultMap)

Maybe it was naive but I was expecting just to be able to append the UserExerciseFavourite from the mutation directly into the List Query.

Anyway, any glaring problems? Is your recommendation to manipulate the cache like this, or refetch the query?

@designatednerd
Copy link
Contributor

What I'm finding rather fiddly

This absolutely is fiddly. We are definitely planning on work to make it easier to work with cached list.

I was expecting just to be able to append the UserExerciseFavourite from the mutation directly into the List Query

The issue is that, particularly if you're not using a cacheKeyForObject function, the key in the database for this object is not necessarily going to match across these two places. Even if you are using cacheKeyForObject, you may be able to update a particular object but you may not necessarily be able to update the list in the way you expect to without doing some highly manual work.

On the web it's a lot easier to have the expectation that when you make a mutation, you can just re-fetch the related list easily after that mutation succeeds. That's not necessarily going to be the case on mobile, so there's significant added complexity in how that works with the cache. Honestly for right now the thing that is going to give you the most data consistency is to refetch your list, but I know that's not ideal for bandwidth etc. reasons. Which is why we plan to work on this :)

@morgz
Copy link
Contributor

morgz commented Mar 8, 2021

That all sounds sensible. Mostly I just wanted to check I wasn't missing some inbuilt methods etc.

I can see how it could be tricky to ensure consistency between different queries caches with possibly different data / fragments etc. Good luck!

Are there any examples you could point me to that demonstrate updating an object with a cache key?

Even if you are using cacheKeyForObject, you may be able to update a particular object

@designatednerd
Copy link
Contributor

These are the docs on updating, at the moment we don't have a ton of other examples beyond what's in there and in the tests.

@morgz
Copy link
Contributor

morgz commented Mar 11, 2021

Not sure if it's useful but I made a PR to the cache documentation to include some explanation I'd have found useful:

44b81e7

@designatednerd
Copy link
Contributor

@morgz I see the diff but i'm not seeing a PR - did you open one?

@morgz
Copy link
Contributor

morgz commented Mar 11, 2021

@morgz I see the diff but i'm not seeing a PR - did you open one?

Sorry, my bad. Have done now. #1710

@calvincestari
Copy link
Member

Before a public 1.0 release we will be rewriting the documentation and this will be a part of that. Closing for repo cleanliness.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
caching docs Focuses on documentation changes
Projects
None yet
Development

No branches or pull requests

5 participants