apollographql / apollo-ios

📱  A strongly-typed, caching GraphQL client for iOS, written in Swift.
https://www.apollographql.com/docs/ios/
MIT License
3.89k stars 728 forks source link

Cache migrations #3422

Closed remigijusbalc closed 3 months ago

remigijusbalc commented 3 months ago

Question

Hello, Is there any recommended/official way to migrate existing cache entries?

Example: User A has persisted query in cache (SQLiteCache) with X fields. New app version introduces changes to query where some of X fields are removed, some changed and new ones are introduced.

How could previous version be migrated to the latest one so the first access of the cache with changed query fields would not fail and return proper values including migrated ones?

AnthonyMDev commented 3 months ago

Thanks for the question @remigijusbalc.

The cache is not really intended to be a complete data persistence option. It's not an alternative to something like CoreData/SwiftData. It's meant to just be a cache of fetched data, which is usually temporary and expires. When things change, you should probably just be refetching them from your GraphQL service and letting that re-write new data into the cache.

If you really need to mutate the data in the cache for a migration, you can use a local cache mutation as defined here in our docs. But it's going to be a pretty manual process that you're going to have to put a lot of thought and care into getting right. There isn't an easy or automatic way that's built in to apply migrations based on a change set in a GraphQL schema or anything like that.

Also, if new fields are added to a query, data for those fields is just not going to be in the cache yet, so your query is going to get a cache miss and need to be refetched the first time. If you somehow know what the values of those fields should be, you could maybe run a local cache mutation on app startup that could write that data to the cache I suppose.

Alternatively, if you want the existing data to appear from the cache and then have the new data loaded, you could try using a deferred fragment . This is a new feature and is still in its experimental phase, but you can try it out! A deferred fragment is able to be returned later after the non-deferred parts of a query. So if all of the non-deferred parts of the query are in the cache, you would get a cache hit, and the deferred fragments would just not be there yet. Then we would do a network fetch and then update the data as it comes in.

I hope that helps. As I don't believe there is much in the way of an actionable work item for us from this issue, I'm going to close the issue. If you have more specific details of your use case, you can still comment on this issue and we may be able to help point you in the right direction for a solution.

github-actions[bot] commented 3 months ago

Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo iOS usage and allow us to serve you better.