Migrating to Apollo Client 3.0
This article walks you through migrating your application to Apollo Client 3.0 from previous versions of Apollo Client.
To illustrate the migration process, we've also made this video that uses the example app from our full-stack quickstart as a starting point, updating it from Apollo client 2.6 to 3.0:
What’s new in 3.0
- Apollo Client is now distributed as the
@apollo/client
package (previous versions are distributed asapollo-client
). - The
@apollo/client
package includes both React hooks and GraphQL request handling, which previously required installing separate packages. - Apollo Client’s cache (
InMemoryCache
) is more flexible and performant. It now supports garbage collection, storage of both normalized and non-normalized data, and the customization of cached data with newTypePolicy
andFieldPolicy
APIs. - The update also includes numerous bug fixes and optimizations, as described in the changelog.
Installation
WARNING: Apollo Client 3.0 is a major-version release that includes breaking changes. If you are updating an existing application to use Apollo Client 3.0, please see the changelog for details about these changes.
Install Apollo Client 3.0 with the following command:
npm install @apollo/client
If you’re installing Apollo Client 3.0 in a project that already uses an earlier version, follow the instructions in each section of Updating imports that applies to a library you are currently using.
Updating imports
The @apollo/client
library includes functionality that previously required installing additional packages. As part of migrating to Apollo Client 3.0, follow the instructions below for each library your application currently uses.
To simplify the process of converting your import
declarations from older packages to @apollo/client
, we provide an automated transform based on jscodeshift
. Note that this transform merely moves import
specifiers between import
declarations, without checking for proper usage of the imported values. Since the transform cannot take care of everything, pay close attention to any errors produced by TypeScript or your bundling tools, and be sure to verify all changes made by the transform. A more detailed list of caveats can be found in the README.md
.
@apollo/react-hoc and @apollo/react-components
React Apollo HOC and component functionality is now included in the @apollo/client
package:
import { Query, Mutation, Subscription } from '@apollo/client/react/components';import { graphql } from '@apollo/client/react/hoc';
As part of migrating, we recommend removing all @apollo/react-hoc
and @apollo/react-components
dependencies.
@apollo/react-hooks
All @apollo/react-hooks
functionality is included in the @apollo/client
package. For example:
import { ApolloProvider, useQuery, useApolloClient } from '@apollo/client'
As part of migrating, we recommend removing all @apollo/react-hooks
dependencies.
Breaking Changes:
useQuery
no longer maintains the previously fetched results in itsdata
result when loading new data. Instead, when new data is being loaded (i.e.loading
===true
) thedata
result ofuseQuery
is set toundefined
. Use thepreviousData
result as a bridge to the old v2 behavior.refetch
functionality ofuseQuery
was broken in 3.5.x until it was fixed in 3.5.8. Previous to this version, if theskip: true
option was used,refetch
would always beundefined
.
@apollo/react-ssr
React Apollo’s SSR utilities (like getDataFromTree
, getMarkupFromTree
, and renderToStringWithData
) are included in the @apollo/client
package. Access them via @apollo/client/react/ssr
:
import { renderToStringWithData } from '@apollo/client/react/ssr';
As part of migrating, we recommend removing all @apollo/react-ssr
dependencies.
@apollo/react-testing
React Apollo’s testing utilities (like MockedProvider
) are included in the @apollo/client
package. Access them via @apollo/client/testing
:
import { MockedProvider } from '@apollo/client/testing';
As part of migrating, we recommend removing all @apollo/react-testing
dependencies.
apollo-boost
The Apollo Boost project is now retired, because Apollo Client 3.0 provides a similarly straightforward setup. We recommend removing all apollo-boost
dependencies and modifying your ApolloClient
constructor as needed.
apollo-client
With Apollo Client 3.0, the apollo-client
package is retired in favor of @apollo/client
. As part of migrating, remove all apollo-client
dependencies.
apollo-link and apollo-link-http
All apollo-link
, apollo-link-http
, and apollo-link-http-common
functionality is included in the @apollo/client
package. For example:
import { ApolloLink, HttpLink, from, split, execute } from '@apollo/client';
As part of migrating, we recommend removing all apollo-link
, apollo-link-http
, and apollo-link-http-common
dependencies.
If you want to configure your own link chain, the ApolloClient
constructor still accepts a link option. Otherwise, the ApolloClient
constructor now also supports uri
, headers
, and credentials
options. For example:
const client = new ApolloClient({cache,uri: 'http://localhost:4000/graphql',headers: {authorization: localStorage.getItem('token') || '','client-name': 'Space Explorer [web]','client-version': '1.0.0',},...});
These options are passed into a new HttpLink
instance behind the scenes, which ApolloClient
is then configured to use.
apollo-link-*
The separate apollo-link-*
packages, that were previously maintained in the https://github.com/apollographql/apollo-link repo, have been merged into the Apollo Client project. These links now have their own nested @apollo/client
entry points. Imports should be updated as follows:
apollo-link-batch
is now@apollo/client/link/batch
apollo-link-batch-http
is now@apollo/client/link/batch-http
apollo-link-context
is now@apollo/client/link/context
apollo-link-error
is now@apollo/client/link/error
apollo-link-retry
is now@apollo/client/link/retry
apollo-link-schema
is now@apollo/client/link/schema
apollo-link-ws
is now@apollo/client/link/ws
It is important to note that Apollo Client 3 no longer allows @client
fields to be passed through a Link chain. While Apollo Client 2 made it possible to intercept @client
fields in Link's like apollo-link-state
and apollo-link-schema
, Apollo Client 3 enforces that @client
fields are local only. This helps ensure Apollo Client's local state story is easier to understand, and prevents unwanted fields from accidentally ending up in network requests (PR #5982).
graphql-anywhere
The graphql-anywhere
package’s functionality is no longer included with Apollo Client. You can continue to use the graphql-anywhere
package, but Apollo no longer uses it and will not actively support it moving forward.
graphql-tag
The @apollo/client
package includes graphql-tag
as a dependency and re-exports gql
. To simplify your dependencies, we recommend importing gql from @apollo/client
and removing all graphql-tag
dependencies.
react-apollo
react-apollo
v3 is an umbrella package that re-exports the following packages:
@apollo/react-common
@apollo/react-hooks
@apollo/react-components
@apollo/react-hoc
@apollo/react-ssr
@apollo/react-testing
The react-apollo
package has been deprecated, and the functionality offered by each of the above packages can now be accessed from @apollo/client
directly:
@apollo/react-hooks
-> now available directly from@apollo/client
@apollo/react-components
-> now available from@apollo/client/react/components
@apollo/react-hoc
-> now available from@apollo/client/react/hoc
@apollo/react-ssr
-> now available from@apollo/client/react/ssr
@apollo/react-testing
-> now available from@apollo/client/testing
Using individual components of Apollo Client 3
Apollo Client 3.0 provides multiple entry points for you to import from. If you only use a particular part of Apollo Client’s functionality, you can import that functionality from its corresponding entry point. By doing so, modern bundlers can omit the remainder of the @apollo/client
package from your bundle and reduce its size considerably.
Using Apollo Client without React
Apollo Client 3.0 includes built-in support for React hooks, but it absolutely still supports non-React view layers. To use Apollo Client 3.0 with Vue, Angular, or another view layer of your choosing, import ApolloClient
from the @apollo/client/core
entry point:
import { ApolloClient } from '@apollo/client/core';
Using apollo-utilities without the rest of Apollo Client
The apollo-utilities
package has been removed, but you can access the utilities themselves from the @apollo/client/utilities
entry point:
import { isReference, isInlineFragment } from '@apollo/client/utilities';
Using apollo-cache and/or apollo-cache-inmemory without the rest of Apollo Client
The apollo-cache
and apollo-cache-inmemory
packages have been removed, but if you're interested in using Apollo Client's cache by itself, you can access their contents with the @apollo/client/cache
entry point:
import { ApolloCache, InMemoryCache } from '@apollo/client/cache';
Cache improvements
Apollo Client 3.0 introduces powerful improvements to its caching system. Most of these improvements are backward compatible, so most applications will continue to work without any changes to caching logic. However, we highly recommend learning more about the capabilities of the Apollo Client 3.0 cache.
Breaking cache changes
The following cache changes are not backward compatible. Take them into consideration before you upgrade to Apollo Client 3.0.
By default, the
InMemoryCache
no longer merges the fields of two objects unless those objects have the same unique identifier and that identifier is present in both objects. Additionally, the values of fields with the same name are no longer merged recursively by default. You can define a custommerge
function for a field to handle both of these changes for a particular field. You can read more about these changes in Merging non-normalized objects. (PR #5603).All cache results are now frozen/immutable, as promised in the Apollo Client 2.6 blog post (PR #5153).
FragmentMatcher
,HeuristicFragmentMatcher
, andIntrospectionFragmentMatcher
have all been removed. We recommend using theInMemoryCache
’spossibleTypes
option instead. For more information, see Defining possibleTypes manually (PR #5073).The internal representation of normalized data in the cache has changed. If you’re using
apollo-cache-inmemory
’s public API, then these changes shouldn’t impact you. If you are manipulating cached data directly instead, review PR #5146 for details.client|cache.writeData
have been fully removed.client|cache.writeQuery
,client|cache.writeFragment
, and/orcache.modify
can be used to update the cache. For example:client.writeData({data: {cartItems: []}});can be converted to:
client.writeQuery({query: gql`query GetCartItems {cartItems}`,data: {cartItems: []}});For more details around why
writeData
has been removed, see PR #5923.cache-and-network
fetch policy now initiates a network request whenever there are cache updates that affect the query, and is no longer limited to the first time the query is run. In order to recreate the default behavior from2.x.x
, please configure anextFetchPolicy
(available in versions>=3.1.0
). For example:
const { loading, error, data } = useQuery(GET_ALL_TODOS, {fetchPolicy: "cache-and-network",nextFetchPolicy: "cache-first",});