Spektor?.dev

Upgrading From Apollo Boost to Apollo Client 3

August 28, 2020

apollo logo

I’ve been using Apollo Client/Server for a while and although these are great projects I did experience inconsistencies and issues with the client cache/local state. So much so that I was thinking of migrating to another local state solution. However Apollo Client 3 came out recently which significantly revamped local state functionality and claims to have fixed the earlier issues. So I decided to upgrade to it from using the older Apollo Boost.

The new client provides all of the functionality that Apollo Boost used to provide so the Boost project is now retired. The Apollo team posted a really nice guide on how to upgrade to the new client which is really helpful. Below are some of the steps I had to take in order to complete the migration in addition to the ones described in the guide:

  1. We were using next-will-apollo with Apollo Boost. It’s a nice library which calls getDataFromTree Apollo function which determines which queries need to be run for render and fetches them. However, using this library with Apollo Client 3 resulted in this error: Module not found: Can't resolve 'apollo-client' in 'node_modules/@apollo/react-hooks/lib'. Upgrading next-will-apollo to the latest version solved the issue. However, in the latest version of next-will-apollo you need to explicitly pass getDataFromTree like so:
import withApollo from 'next-with-apollo';
import { getDataFromTree } from '@apollo/react-ssr';

export default withApollo({ ctx, headers, initialState }) {
  return new ApolloClient({
    // ... options
  })
}, { getDataFromTree });
  1. For me personally, by far the most work involved in the upgrade was caused by the fact that the cache results are immutable. For example, performing a sort on such results will cause a run-time error because native Javascript sort method sorts in-place thus mutating the original array.
  2. Apollo Client 3 introduced a really nice feature called reactive variables. From now on, you don’t need to write custom client resolvers in order to read/write local state values, just use reactive variables to create them as simply as:
import { makeVar } from "@apollo/client"
const isLoggedIn = makeVar(false)

You can then use the isLoggedIn function anywhere in code in order to either get the value: const isLoggedIn = isLoggedIn() or to set the value isLoggedIn(true)

It’s important to reset reactive variables to their initial values if you reset the client store because their values are not reset automatically:

import withApollo from 'next-with-apollo';
import { getDataFromTree } from '@apollo/react-ssr';

export default withApollo({ ctx, headers, initialState }) {
  const client = new ApolloClient({
    // ... options
  })
  client.onResetStore(() => {
    // reset reactive variables here...
  });
  return client
}, { getDataFromTree });

Lastly, make sure to pay attention to the breaking changes involved in the upgrade.