iOS - How to take query's input out of cache key

Hi all,

Let’s say the query is as follow:

query FetchWeather($currentTime: String) {
  weather(currentTime: $currentTime) {
    temperature
  }
}

I was trying to fetch weather multiple times (ofc “currentTime” will be different every time). Every time I did a fetch, I was hoping the cache to completely replace the old weather data with new data, meaning I just wanted the last one I fetched storing in the cache.
But when Apollo tried to cache the the data with normalization, it would internally take the currentTime as part of the cache key, e.g. “weather:{currentTime}”. Since every time the key was different, it resulted in the consequence that all weathers’ data were staying in the cache.
I tried the “custom cache keys” approach from Apollo doc, but it only deduplicated the stored data by establishing a reference from “weather:{currentTime}” to “someUnifiedWeather”. In such way, currentTime was still used so that cache would always miss when reading.
One looks-like solution I found was setting keyArgs as false (Key arguments in Apollo Client - Apollo GraphQL Docs), but it’s a feature in React client :frowning: .
Is there any solution to this problem for iOS?

Hi @Hantp :wave: welcome to the forum! I apologize if I’m misreading something but I’m having trouble understanding the problem you’re trying to solve here. I see three needs so far:

  1. You never want stale data being rendered in the UI
  2. You don’t want unused data in the cache
  3. Cache misses are not desirable

If that’s correct (and again, sorry if I’m missing something), I don’t understand how to reconcile 1 and 3. More info would be helpful :pray:

Hi Jeff, thanks for reading my question and sorry for the confusion.

My only need: I don’t want stale data staying in the cache when I try to write new data into cache. The current problem is, old data would stay when writing because the query’s input is different every time.

Let’s say, what’s in the cache initially

[QUERY_ROOT -> "QUERY_ROOT,weather(currentTime: May-02)"]
[QUERY_ROOT.weather(currentTime: May-02) -> "temperature:95"]

After I fetch and then write in new data, the cache will becomes

[QUERY_ROOT -> "QUERY_ROOT.weather(currentTime: May-02),
QUERY_ROOT.weather(currentTime: May-03)"]
[QUERY_ROOT.weather(currentTime: May-02) -> "temperature:95"]
[QUERY_ROOT.weather(currentTime: May-03) -> "temperature:89"]

However, I want the cache to be as follow, that is, don’t the input as part of cache key completely.

[QUERY_ROOT -> "QUERY_ROOT.weather"]
[QUERY_ROOT.weather -> "temperature:89"]

A potential approach I tried was “Custom Cache Key”, but it only made the cache like below, which didn’t solve the problem because if I try to fetch data for May-04, it would fail to read(In this case, I just want it to read whatever in the cache regardless of the input).

[QUERY_ROOT -> "QUERY_ROOT.weather(currentTime: May-02)":{"$reference":"FetchWeather.weather"},
"QUERY_ROOT,weather(currentTime: May-03)":{"$reference":"FetchWeather.weather"}]
[FetchWeather.weather -> "temperature:89"]

Hope this time I make my question clear :sweat_smile:

This definitely makes the issue clearer to us. Thank you @Hantp!

The normalized cache isn’t really set up for this functionality. We have to assume that if you pass in different input parameters that you need specific data for those given input parameters. Currently, there is no way to configure the cache to ignore certain input parameters. This might be something we could consider doing in the future, but it’s not a feature on our current roadmap.

Any type of workaround for now is going to involve writing a custom NormalizedCache implementation that is hardcoded to handle this specific query.

1 Like

Thanks a lot for your time @AnthonyMDev and @JeffAuriemma