Skip to content

State management with GraphQL + Apollo

Problem to solve

Right now we're managing state with Vuex an it works pretty well. But the issue is Apollo offers its own way to store API calls results (Apollo cache) as well as local application state (apollo-link-state). There was a long discussion about best practices of combining GraphQL+Apollo with Vuex in vue-apollo repository: https://github.com/Akryum/vue-apollo/issues/140 (TL;DR: use apollo-link-state).

As we're going to use GraphQL, we need to discuss the strategy of state management.

Target audience

Frontend Team

Further details

There are 4 main approaches to manage a state in application using GraphQL + Apollo:

  • keep Vuex as a single source of truth storing all data from API to state. In this case we don't need Apollo cache and we can disable it with fetchPolicy: 'no-cache' property in Apollo config. We don't need vue-apollo as well because it's designed to make calls from component level and we're going to make them from Vuex actions. We use Apollo query which returns a Promise.

    Pros:

    • we keep the flow familiar to the team;
    • we can still save local application data to Vuex state;
    • we get rid of one dependency;

    Cons:

    • we lose vue-apollo features;
    • we don't leverage Apollo cache
    • we can't use Apollo polling
  • again, keep Vuex as a single source of truth storing all data from API to state but enable Apollo cache. We don't need vue-apollo as well. This case differs from the first one: we use Apollo watchQuery which returns an Observable instead of Promise

    Pros:

    • we keep the flow familiar to the team;
    • we can still save local application data to Vuex state;
    • we get rid of one dependency;
    • we can do polling simply passing pollInterval to watchQuery

    Cons:

    • we lose vue-apollo features again;
    • we have data stored in both Vuex and Apollo cache.
  • make API calls from components and use Apollo cache to save results while keeping local state in Vuex. This approach has 2 sources of truth and it's the biggest flaw.

  • get rid of Vuex and use Apollo cache for storing API calls results and apollo-link-state for local application state.

    Pros:

    • this is the recommended way of doing things;
    • we get rid of one dependency

    Cons:

    • the way to handle local state requires some boilerplate and is not very intuitive;
    • there is no such thing as getters in Apollo state;

Proposal

I made a little proof of concept to compare both viable options. It contains 3 branches: 2 for Vuex implementations (one using queries as promises, no Apollo cache; second uses Observables with polling) and 1 for apollo-link-state.

Please have a look at implementation and consider what is the most convenient for you and why.

Edited by Natalia Tepluhina