react-relay-network-modern icon indicating copy to clipboard operation
react-relay-network-modern copied to clipboard

Cache and Fetch

Open ro-savage opened this issue 5 years ago • 10 comments

We would like to return cached data to React, but also fetch new data in the background and update accordingly when the new data arrives.

Our specific circumstances are that our queries can take a long time to respond and the data is used in visualizations. We would like our visualisations to appear immediately using old data, then update to show new data when it arrives.

Ideally, we'd then like to cache in localStorage, so visuals can be seen both offline and instantly when first visiting the site again.

Current cache using RelayQueryResponseCache will always show old data, until the cache expires.

The undocumented dataFrom="STORE_THEN_NETWORK" on the <QueryRenderer> doesn't work if you have multiple stores, and also doesn't support offline/page reload caching.

This feels like something that should/could be implemented at the network layer, but I've had no luck figuring out how to do.

Any suggestions, would be happy to make a PR if it is useful.

ro-savage avatar Feb 12 '19 07:02 ro-savage

For anyone wanting to implement yourself:

Locally I've implemented with Observables, yet another undocumented feature of relay.

You can read about them here: https://artsy.github.io/blog/2018/07/25/Relay-Networking-Deep-Dive/

Here is an example implementation that will return data from a cache, then do a fetch, and when the fetch returns update the data automatically: https://gist.github.com/ro-savage/0855aaadb8a869cdf684693876d757a0

ro-savage avatar Feb 12 '19 10:02 ro-savage

Apollo solves this issue simply. There is a "fetchPolicy" which defaults to "cache-first" (like Relay) but you can also pass in "cache-and-network" which does exactly what you describe (there are other options as well). I have an issue of an important page not updating for anyone other than the person who made the change (since the mutation altered their cache) and even using the force fetch, it won't. It is so averse to network calls that it will show out-of-date data even when you "force fetch". Relay devs will go on long-winded, detailed responses about the internals of it as to why it works that way -- but at the end of the day, a dev should be able to just call a 'force fetch' and get it to make the call to the server no matter what. Relay has some serious design flaws for most use-cases that Apollo solves in really simple ways. SSR is also well thought out with Apollo, which is pretty important for SEO.

nuclearspike avatar Apr 01 '19 07:04 nuclearspike

@ro-savage from what I can see, I could probably just be middleware layer? But I dare say, you'd have to rework middleware composition, to support observable. So things like this could be bubbled all the up to the Relay Network.

From what I can tell, and @nodkz correct me if im wrong - this project looks abandoned a bit. So could it be worth teaming up @ro-savage and go through a bit of a refactor, as I'm also wanting features like this...

maraisr avatar Jul 31 '19 02:07 maraisr

@maraisr I think a small refactor to solve some of the core issues could be warranted and something I could help out with as well. I am currently running into some of the current boundaries that I would need to solve anyways (not just related to this issue).

If @nodkz agrees, maybe we should start sketching on what a possible 5.0.0 version would include?

AnotherHermit avatar Jul 31 '19 06:07 AnotherHermit

I definitely have gone down the path of refactoring how the middlewares work... not simple.

I was able to implement this feature with polling with the cache middleware and a customized fetch function here: https://github.com/relay-tools/react-relay-network-modern/issues/40#issuecomment-487781782

I also saw recently the official Relay docs now highlight STORE_THEN_NETWORK, which might have gotten some updated functionality: https://relay.dev/docs/en/query-renderer#props

joelvh avatar Jul 31 '19 06:07 joelvh

I agree on any changes and improvements for current lib from the community. I'm very sorry but now I have no bandwidth to introduce observables to RRNM, cause current my project use ApolloClient and I cannot spend my working time on this package. BUT with love add some more collaborators to this repo if somebody wants to take care of the current codebase. 😉

nodkz avatar Jul 31 '19 07:07 nodkz

@nodkz I'd be keen on giving it some love, for sure! I reckon first order of business would be to TypeScript migration - coz I mean, who even uses Flow 🤷‍♂

@AnotherHermit I think so yeah, if we maybe spin up a new issue for what v5 might look like, and why. @joelvh care to chip in?

maraisr avatar Jul 31 '19 08:07 maraisr

All hands for TypeScript.

Somewhere from v0.70 Flow became very-very slow. Generics in Flow still very weak. Anyway, when developers write code on the previous version of its code (like it do TypeScript team) they provide a better experience and more comfortable language constructions. But when you write code by request on another language (like it do Flow) we got tons of breaks which may be fixed whenever; also it may be called as blind development; also Flow team concentrated only on Facebook problems. So the winner for static analysis in JS - is TypeScript 🥇

PS. And the main advantages of Flow

  • to migrate the codebase gradually is broken by this talk from AirBnb https://www.youtube.com/watch?v=P-J9Eg7hJwE
  • more strict checks - in practice kill hundreds of my hours of stupid type checks (especially hate array type checking, where it should be readonly for proper checks). I support a quite complex library codebase with complex types (graphql-compose) and the last changes in it was incredibly painful and take a lot of time (cause the flow checks take about 10-30 seconds after file save 🤬).

Kill the Flow! 😈

nodkz avatar Jul 31 '19 09:07 nodkz

Flow is still the top class technology for sound type checking. And doesn't bind you to a custom DSL, you just use standard JavaScript.

If your Flow check takes 30 seconds something with you setup is definitely broken. Flow on my very large projects in my company take no more than a few milliseconds after a file save. The integration with VS Code is seamless

FezVrasta avatar Jul 31 '19 09:07 FezVrasta

Hi everyone, I have achieved, with excellent results, the react-relay-offline library which adds many features to Relay. All the libraries inside the monorepo wora were born from it. In summary, persistence of javascript objects, management of apollo and relay stores (TTL, persistence), offline workflow, network management and introduction of the cache-first policy in relay.

Soon I will integrate the logics implemented in the relay-hooks repository to manage store-or-network and store-only policies.

I recommend you try them, In the repository offline-examples you can find examples of using the offline for apollo (web) and relay (web and react-native)

Now I'm working on a better and complete documentation. For any questions please contact me or open the issues.

Lorenzo

morrys avatar Jul 31 '19 11:07 morrys