:wave: I stumbled upon an interesting behavior I'm...
# apollo-kotlin
m
👋 I stumbled upon an interesting behavior I'm not sure is a bug or if I'm making wrong assumption on how the cache works. let's assume the client has a list of IDs we should later fetch, but due to reasons the associated object gets removed on the server (in our case it was never there because some caches got outdated), so when the client attempts to fetch them an incomplete list of object gets returned (with extra information returned via
errors
array) With such setup, I see the request that makes network call returns the partial data, but I'm unable to access cached data via a
fetchPolicy(FetchPolicy.CacheOnly)
request. Couple of highlights of the setup: •
storePartialResponses
is enabled •
emitCacheMisses
is enabled • custom
CacheKeyResolver
is provided that computes list of IDs using
listOfCacheKeysForField
, similar to the one mentioned in the documentation example schema:
Copy code
type Viewer {
  id: String!,
  books(ids: [String!]!): [Book!]!
}

type Book {
  id: String!
  name: String!
}
Full repro with failing test can be found here. The only workaround I was able to come up with is not to compute
listOfCacheKeysForField
, but that disables the neat feature introduced in (I think?) 3.x we rely on to access individual element details without making extra network calls. So in the end I wonder if I can expect the partial data to be accessible after it was fetched, or due to the fact apollo knows it's partial it is not considered "valid"?
m
I think what you’re looking for is partial cache results?
As of today, the cache stops at the first cache miss and returns
data == null
for the whole response
We could return partial cache results but that’d probably mean we need the cache to be closer to a full fledge GraphQL server
m
I think what you’re looking for is partial cache results?
I wouldn't say that, I think. I don't necessarily need any partial result, I'd say I only want to read the latest data saved in the cache.
the cache stops at the first cache miss and returns
data == null
This is the behavior I observe when I use
listOfCacheKeysForField
, returning
null
there, allows me to read the partial/incomplete data that has just been written to the cache. So apollo has already the capability to return the data I need It feels like • using
listOfCacheKeysForField
- always computes the required response and fails due to cache miss, ignoring saved cache keys • not using
listOfCacheKeysForField
- checks if the root key exists in cache and returns associated data so what I'd say what I'm missing is a mechanism that tries to recover from a "computed" cache miss by checking if a "stored" key is present in the cache (which I hope is much simpler than fully fledged partial cache results 😅_)_
👀 1
m
Just for me to understand, the reproducer doesn’t seem to have the
book-id-invalid
stored in cache:
Copy code
"book-id-1" : {
    "id" : book-id-1
    "name" : book-name-1
  }

  "viewerId" : {
    "id" : viewerId
    "books({"ids":["book-id-1","book-id-invalid"]})" : [
      CacheKey(book-id-1)
    ]
  }

  "QUERY_ROOT" : {
    "viewer" : CacheKey(viewerId)
  }
But in other scenarios, you would have it, right?
Oh, I think I just got it, you don’t have it because it’s an error
m
Not sure if I got what other scenarios are 👀 I confirm I do not have the invalid id stored in the cache, and I expected I'll be able to read the data that are currently available in the cache
m
I see
Using
listOfCacheKeysForField
tries to read
book-id-invalid
and throw a cache miss there
yes black 1
There might be a way to fallback to what’s stored in that case
Let me check
m
Thanks 🙏
I understand this is not a typical scenario where the BE responds with an invalid data, but I was told it cannot be fixed on BE side for technical reasons and now I'm looking into fixing it on the client side
If there is a cached list already it is used. If not, it constructs one from the
ids
argument
Note that the opposite would be significantly more complicated (i.e. try using the
ids
arguments first and then fallback to the existing list if there a cache miss)
m
Neat 🧠
I think that order works for me, I don't see any obvious issues caused by checking for the existing keys first 👍
👍 1
Nice, thank you very much 🙏