Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change default fetchPolicy to "cache-and-network" #2061

Closed
pcorey opened this issue Aug 22, 2017 · 25 comments
Closed

Change default fetchPolicy to "cache-and-network" #2061

pcorey opened this issue Aug 22, 2017 · 25 comments

Comments

@pcorey
Copy link

pcorey commented Aug 22, 2017

Hello,

I thought I'd open up this issue for discussion. The current fetchPolicy on GraphQL queries is "cache-first". This default assumes that all mutations are either made by, or can be predicted by the client. I would argue that this isn't true for most web applications.

Defaulting fetchPolicy to "cache-first" opens up the possibility of stale cache reads throughout an app if any queried data has been updated on the server (or by another client) without the client's knowledge. The only way to fix this is to go though your app and mark every query with a more appropriate fetchPolicy (like "cache-and-network").

I think a more sane default for fetchPolicy would be "cache-and-network". In my mind, this gives developers a more predictable experience. If a query result lives in cache, it will be returned while a network round trip takes place. If a developer knows that a query can only be affected by client-initiated changes (which I believe is a more rare use case), they can change their fetchPolicy to "cache-first" for performance gains.

Short of changing the fetchPolicy default value from "cache-first" to "cache-and-network", it might be worth considering making this default value configurable when initializing the Apollo client instance.

Any thoughts? Thanks!

  • apollo-client@1.9.1
@sepehr500
Copy link

I think a default policy of network-only makes more sense. You don't want your application to be storing sensitive information without you specifically setting it to do so.

@vieiralucas
Copy link
Contributor

+1 for allowing the default value to be configurable.

@pcorey
Copy link
Author

pcorey commented Aug 31, 2017

This hasn't been discussed, and consensus hasn't been reached, but I thought I'd throw our a PR for posterity and discussion.

@jbaxleyiii
Copy link
Contributor

@pcorey what do you think about a way to set defaults for all of the watchQueryOptions? Vue apollo does this and it could be useful for other integrations for it to be part of the core!

@pcorey
Copy link
Author

pcorey commented Sep 2, 2017

@jbaxleyiii Something to consider, for sure.

I haven't dug deep enough to figure out the difference between ModifiableWatchQueryOptions vs the extended WatchQueryOptions, but does it make sense to want to have a global default for things like variables, query, and others?

@stale
Copy link

stale bot commented Sep 23, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions to Apollo Client!

@stale
Copy link

stale bot commented Oct 7, 2017

This issue has been automatically closed because it has not had recent activity after being marked as stale. If you belive this issue is still a problem or should be reopened, please reopen it! Thank you for your contributions to Apollo Client!

@stale stale bot closed this as completed Oct 7, 2017
@ceferrari
Copy link

+1

@7ynk3r
Copy link

7ynk3r commented Jan 2, 2018

any updates on this?

@josepjaume
Copy link

It'd be nice to have the default be configurable indeed!

@7ynk3r
Copy link

7ynk3r commented Jan 12, 2018

hello everyone, i found that it's possible to set it by default:

    const defaultOptions = {
      watchQuery: {
        fetchPolicy: 'cache-and-network',
        errorPolicy: 'all',
      },
      query: {
        fetchPolicy: 'cache-and-network',
        errorPolicy: 'all',
      },
      mutate: {
        errorPolicy: 'all',
      },
    };

    const client = new ApolloClient({
      link,
      cache,
      defaultOptions,
    });

for more: https://www.apollographql.com/docs/react/basics/setup.html#ApolloClient

@sajsanghvi
Copy link

I'm getting an error that says "cache-and-network" can only be used with WatchQuery .. anyone have any ideas for this?

@JPeer264
Copy link

@sajsanghvi for me I just get this error, when I call the query directly with the client, e.g.: this.props.client.query({ query: MyQuery }); (on React).

@mbrowne
Copy link

mbrowne commented Mar 6, 2018

I agree that cache-first isn't a good default cache policy, but I also have concerns about making cache-and-network the default. This could cause a lot of unnecessary fetching without the user necessarily being aware of it (at least at first)...and it seems to me that the biggest performance gains that can be obtained from caching are from avoiding unnecessary network requests -- not just avoiding unnecessary client-side cache updates. Maybe some sort of time-based caching policy would be a better default. Then in the simplest case, the only configuration tweaking you'd need to do is adjust the amount of time until you consider the cache to be stale and need to re-fetch from the server to check for updates.

I'm assuming that cache-and-network re-fetches the entire query every time and that there aren't any server-side optimizations to avoid re-sending the data when unnecessary. Is that correct?

@Evanion
Copy link

Evanion commented Mar 13, 2018

Too be honest .. Too many network requests is usually a rather positive problem to have... It means that your app have traffic, and you have the resource (time) to look in to increase the caching of static data.A too high cache level would cause more issues with out-of-sync clients, than an over burdened Gateway server.

Most project tends to look in to optimising server performance before caching the client requests since the RoI potential is (generally) greater.

@wzup
Copy link

wzup commented Sep 4, 2018

@7ynk3r
You're wrong.
cache-and-network doesn't work with client.query. Only with watchQuery

Error: cache-and-network fetchPolicy can only be used with watchQuery

@lukepighetti
Copy link

Docs have changed and there is no mention of fetchPolicy as a default anymore. Can someone confirm a method of setting a default fetchPolicy? I want cache-and-network as a default.

@bsara
Copy link

bsara commented Dec 20, 2018

@lukepighetti It doesn't look like defaultOptions works anymore:

image

@bsara
Copy link

bsara commented Dec 20, 2018

This is the best way I can think of doing this for the time being:

On my project, I happen to have a LoadingQuery React component that takes care of displaying a spinner for me while a query is running. Because of Query being wrapped in a different component, I have done the following:

function LoadingQuery({ ...props }) {
  return (
    <Query fetchPolicy="network-only" {...props}>
      ...
    </Query>
  );
}

This allows me to default to network-only but also allows for overriding my default because ...props comes AFTER the fetchPolicy prop.

@rstrand
Copy link

rstrand commented Jan 16, 2019

@bsara You need to use apollo-client directly instead of apollo-boost in order to be able to set defaultOptions. There are migration instructions here: https://www.apollographql.com/docs/react/advanced/boost-migration.html

The <Query /> component uses watchQuery so to use network-only by default you should be setting the defaultOptions like this:

const defaultOptions = {
  watchQuery: { fetchPolicy: 'network-only' },
};

const client = new ApolloClient({
  link,
  cache,
  defaultOptions,
})

@diazemiliano-zz
Copy link

Now are here. https://www.apollographql.com/docs/react/api/apollo-client/#example-defaultoptions-object

@bradley
Copy link

bradley commented Feb 6, 2020

I know this is a little unrelated to this thread, but the way links to apollo docs constantly expire is really frustrating. The above link doesnt work. This is common in many issue threads.

@noobling
Copy link

noobling commented Jan 9, 2021

Does anyone have any reference to why they have chosen the default to be cache-first. This clearly will be the source of many issues for people just getting started with apollo. This doesn't make sense you obviously want to make it easy for beginners and give flexibility for more advanced users.

EDIT: After using apollo fulltime for 3 months I still believe the default should be network-only. Then adding cache-first to requests where we can live with the fact that the data may be slightly outdated

@markymc
Copy link

markymc commented Sep 28, 2021

After having used Apollo for well over a year now on multiple products (I run an agency), I agree with @noobling on this one.

@mbrowne
Copy link

mbrowne commented Sep 28, 2021

Let's not forget about cache-and-network - that makes apps snappier/more responsive but still updates if the cached data is stale. I still think it would be really good to add a time-based caching feature, and maybe even make that the default.

At least we have defaultOptions to set your own default.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 1, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests