Open kenyee opened 2 years ago
Thanks for writing this! I think this boils down to:
HttpCache
has "CACHE_EXPIRE_TIMEOUT_HEADER" which is client controlled and doesn't read the server value
a. MemoryCache
has "expireAfterMillis" which is client controlled and doesn't read the server value
b. SqlNormalizedCache
has no expirationAll in all, We'll work about 2. I opened https://github.com/apollographql/apollo-kotlin/issues/3566 a few days ago. I don't think we can do much about 1.? If the information is not in the response, there's not much we can do.
A few other comments:
Ideally, the federation server would also send down expiration info for subgraphs and the graphql client would know to request only subgraphs.
I don't think the client should know anything about federation and subgraphs? That's the nice thing with GraphQL is that client developers don't need to know anything about how it's implemented server-side. There's still the question about per-field expiration information (1. above).
apolloClient.query(query).httpFetchPolicy(CacheFirst).acceptStaleDataFor(60.min).execute()
Good point about accepting stale data. I've updated https://github.com/apollographql/apollo-kotlin/issues/3566 with some more information.
I'm keeping this issue open as a global server + client brainstorming issue but for all client APIs and discussion, please go to https://github.com/apollographql/apollo-kotlin/issues/3566 instead
I don't think the client should know anything about federation and subgraphs? That's the nice thing with GraphQL is that client developers don't need to know anything about how it's implemented server-side
That was mainly in case app developers want to implement their own client side caching of a subgraph if they don't want to use Apollo client SDK caching. That expires info can come down as part of the data in a separate field as you mentioned though.
We don't need TTL info to be pulled down with every data query. The TTL information should be as static as the graph itself. eg: a Product Price should be a Price .... if the implementer wants the same graph node with different TTL's then maybe they should rethink what they are doing and implement it as different nodes.
How about a solution where the client (mobile app or SPA) pulls down a separate graph which defines the TTL for each node on the graph?
At least for mobile app, it could only pull down the TTL graph once and then push it to the Apollo client. I envisage a mobile App starts with a cached copy and does an async pull of the "latest" TTL graph and then updates the Apollo client with the "latest" version of the TTL graph.
@mindwalkr gotcha. I've added a "client-side expiration logic" section to https://github.com/apollographql/apollo-kotlin/issues/3566. There's significant work involved. The biggest challenge certainly being able to store the per-field expiration metadata without doubling (or worse) the size of the cache...
Use case In case a graphql graph has mixed expiration timeouts in subgraphs or fields, the Apollo graphql client doesn't have an API to handle these cases. E.g., a simple use case would be a product site like Wayfair or Amazon....price fields are only valid for 10min, but product descriptions might be valid for a much longer time (e.g. 1 day). Apollo federation server does set the query result to min(subgraph[].timeout), so one workaround is to break this into two different queries. Apps can also use the executionContext to get the expiration timeout from the http expires header to know when to do another request to updated data.
Describe the solution you'd like Ideally, the federation server would also send down expiration info for subgraphs and the graphql client would know to request only subgraphs. If the streaming API is used, as long as there are subscribers, there should be a flow of updates for that data. and maybe include a staleness parameter: apolloClient.query(query).httpFetchPolicy(CacheFirst).acceptStaleDataFor(60.min).execute()