A fully-featured caching GraphQL client.
Last release 6 days ago
21 Aug 2026
Ships on a steady schedule
a new release about every 2 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
27 versions withdrawn
withdrawn after publishing
7 years old
723 releases · first in 2019
Release timeline
723 releases since 2019Releases
- 3.5.523 Nov 2021
- 3.5.419 Nov 2021
Release notes
Open source →Apollo Client 3.5.5 (2021-11-23)
Bug Fixes
- Remove
printer: Printerpositional parameter from publicly-exportedselectHttpOptionsAndBodyfunction, whose addition in #8699 was a breaking change (starting in Apollo Client 3.5.0) for direct consumers ofselectHttpOptionsAndBody. @benjamn in #9103
Apollo Client 3.5.4 (2021-11-19)
Notices
-
[Relevant if you use Apollo Client with React Native] Since Apollo Client v3.5.0, CommonJS bundles provided by
@apollo/clientuse a.cjsfile extension rather than.cjs.js, so Node.js won't interpret them as ECMAScript modules. While this change should be an implementation detail, it may cause problems for the Metro bundler used by React Native, whoseresolver.sourceExtsconfiguration does not include thecjsextension by default.As a workaround until this issue is resolved, you can configure Metro to understand the
.cjsfile extension by creating ametro.config.jsfile in the root of your React Native project:const { getDefaultConfig } = require("metro-config"); const { resolver: defaultResolver } = getDefaultConfig.getDefaultValues(); exports.resolver = { ...defaultResolver, sourceExts: [ ...defaultResolver.sourceExts, "cjs", ], };
Improvements
-
Restore the ability to pass
onError()andonCompleted()to the mutation execution function. @brainkim in #9076 -
Work around webpack 5 errors of the form
The request 'ts-invariant/process' failed to resolve only because it was resolved as fully specifiedby ensuring
import ... from 'ts-invariant/process'is internally written toimport ... from 'ts-invariant/process/index.js'. @benjamn in #9083
Apollo Client 3.5.3 (2021-11-17)
-
Avoid rewriting non-relative imported module specifiers in
config/rewriteModuleIds.tsscript, thereby allowing bundlers to resolve those imports as they see fit. @benjamn in #9073 -
Ensure only current file is matched when running VSCode debugger. @eps1lon in #9050
Apollo Client 3.5.2 (2021-11-10)
- Fix useMutation execute function returning non-identical execution functions when passing similar options. @brainkim in #9093
Apollo Client 3.5.1 (2021-11-09)
Apollo Client 3.5.0 (2021-11-08)
Improvements
-
Add
updateQueryandupdateFragmentmethods toApolloCache, simplifying commonreadQuery/writeQuerycache update patterns. @wassim-k in #8382 -
Field directives and their arguments can now be included along with field argument names when using field policy
keyArgs: [...]notation. For example, if you have aQuery.feedfield that takes an argument calledtypeand uses a@connection(key:...)directive to keepfeeddata from different queries separate within the cache, you might configure both using the followingInMemoryCachefield policy:new InMemoryCache({ typePolicies: { Query: { fields: { feed: { keyArgs: ["type", "@connection", ["key"]], }, }, }, }, }) -
Report single
MissingFieldErrorinstead of a potentially very largeMissingFieldError[]array for incomplete cache reads, improving performance and memory usage. @benjamn in #8734 -
When writing results into
InMemoryCache, each written object is now identified usingpolicies.identifyafter traversing the fields of the object (rather than before), simplifying identification and reducing duplicate work. If you have customkeyFieldsfunctions, they still receive the raw result object as their first parameter, but theKeyFieldsContextparameter now providescontext.storeObject(theStoreObjectjust processed byprocessSelectionSet) andcontext.readField(a helper function for reading fields fromcontext.storeObjectand anyReferences it might contain, similar toreadFieldforread,merge, andcache.modifyfunctions). @benjamn in #8996 -
Ensure
cache.identifynever throws when primary key fields are missing, and include the source object in the error message whenkeyFieldsprocessing fails. @benjamn in #8679 -
The
HttpLinkconstructor now accepts an optionalprintfunction that can be used to customize how GraphQLDocumentNodeobjects are transformed back into strings before they are sent over the network. @sarahgp in #8699 -
Make
@apollo/client/testinga fully-fledged, independent entry point, instead of re-exporting@apollo/client/utilities/testing(which was never an entry point and no longer exists). @benjamn in #8769 -
A new nested entry point called
@apollo/client/testing/corehas been created. Importing from this entry point instead of@apollo/client/testingexcludes any React-related dependencies. @wassim-k in #8687 -
Make
cache.batchreturn the result of calling theoptions.updatefunction. @benjamn in #8696 -
The
NetworkErrorandErrorResponsetypes have been changed to align more closely. @korywka in #8424 -
Update
zen-observable-tsto eliminate transitive dependency on@types/zen-observable. @benjamn in #8695
React Refactoring
Improvements (due to @brainkim in #8875):
- The
useLazyQueryfunction now returns a promise with the result. - The
useMutationresult now exposes a method which can be reset.
Bug Fixes (due to @brainkim in #8596):
- The
useQueryanduseLazyQueryhooks will now haveObservableQuerymethods defined consistently. - Calling
useLazyQuerymethods likestartPollingwill start the query. - Calling the
useLazyQueryexecution function will now behave more likerefetch.previousDatawill be preserved. standbyfetchPolicies will now act likeskip: truemore consistently.- Calling
refetchon a skipped query will have no effect (issue #8270). - Prevent
onErrorandonCompletedfunctions from firing continuously, and improving their polling behavior.
Additional notes2 sources agree
Open source →Notices
⚠️ The following advice about
metro.config.jsshould no longer be necessary, as of Apollo Client v3.6.4.-
[Relevant if you use Apollo Client with React Native] Since Apollo Client v3.5.0, CommonJS bundles provided by
@apollo/clientuse a.cjsfile extension rather than.cjs.js, so Node.js won't interpret them as ECMAScript modules. While this change should be an implementation detail, it may cause problems for the Metro bundler used by React Native, whoseresolver.sourceExtsconfiguration does not include thecjsextension by default.As a workaround until this issue is resolved, you can configure Metro to understand the
.cjsfile extension by creating ametro.config.jsfile in the root of your React Native project:// NOTE: No longer necessary in @apollo/[email protected]! const { getDefaultConfig } = require("metro-config"); const { resolver: defaultResolver } = getDefaultConfig.getDefaultValues(); exports.resolver = { ...defaultResolver, sourceExts: [...defaultResolver.sourceExts, "cjs"], };
Improvements
-
Restore the ability to pass
onError()andonCompleted()to the mutation execution function. <br/> @brainkim in #9076 -
Work around webpack 5 errors of the form
The request 'ts-invariant/process' failed to resolve only because it was resolved as fully specifiedby ensuring
import ... from 'ts-invariant/process'is internally written toimport ... from 'ts-invariant/process/index.js'. <br/> @benjamn in #9083
- Remove
- 3.5.317 Nov 2021
- 3.5.210 Nov 2021
- 3.5.19 Nov 2021
Release notes2 sources agree
Open source → - 3.5.08 Nov 2021
Release notes2 sources agree
Open source →Improvements
-
Add
updateQueryandupdateFragmentmethods toApolloCache, simplifying commonreadQuery/writeQuerycache update patterns. <br/> @wassim-k in #8382 -
Field directives and their arguments can now be included along with field argument names when using field policy
keyArgs: [...]notation. For example, if you have aQuery.feedfield that takes an argument calledtypeand uses a@connection(key:...)directive to keepfeeddata from different queries separate within the cache, you might configure both using the followingInMemoryCachefield policy:new InMemoryCache({ typePolicies: { Query: { fields: { feed: { keyArgs: ["type", "@connection", ["key"]], }, }, }, }, }); -
Report single
MissingFieldErrorinstead of a potentially very largeMissingFieldError[]array for incomplete cache reads, improving performance and memory usage. <br/> @benjamn in #8734 -
When writing results into
InMemoryCache, each written object is now identified usingpolicies.identifyafter traversing the fields of the object (rather than before), simplifying identification and reducing duplicate work. If you have customkeyFieldsfunctions, they still receive the raw result object as their first parameter, but theKeyFieldsContextparameter now providescontext.storeObject(theStoreObjectjust processed byprocessSelectionSet) andcontext.readField(a helper function for reading fields fromcontext.storeObjectand anyReferences it might contain, similar toreadFieldforread,merge, andcache.modifyfunctions). <br/> @benjamn in #8996 -
Ensure
cache.identifynever throws when primary key fields are missing, and include the source object in the error message whenkeyFieldsprocessing fails. <br/> @benjamn in #8679 -
The
HttpLinkconstructor now accepts an optionalprintfunction that can be used to customize how GraphQLDocumentNodeobjects are transformed back into strings before they are sent over the network. <br/> @sarahgp in #8699 -
Make
@apollo/client/testinga fully-fledged, independent entry point, instead of re-exporting@apollo/client/utilities/testing(which was never an entry point and no longer exists). <br/> @benjamn in #8769 -
A new nested entry point called
@apollo/client/testing/corehas been created. Importing from this entry point instead of@apollo/client/testingexcludes any React-related dependencies. <br/> @wassim-k in #8687 -
Make
cache.batchreturn the result of calling theoptions.updatefunction. <br/> @benjamn in #8696 -
The
NetworkErrorandErrorResponsetypes have been changed to align more closely. <br/> @korywka in #8424 -
Update
zen-observable-tsto eliminate transitive dependency on@types/zen-observable. <br/> @benjamn in #8695
React Refactoring
Improvements (due to @brainkim in #8875):
- The
useLazyQueryfunction now returns a promise with the result. - The
useMutationresult now exposes a method which can be reset.
Bug Fixes (due to @brainkim in #8596):
- The
useQueryanduseLazyQueryhooks will now haveObservableQuerymethods defined consistently. - Calling
useLazyQuerymethods likestartPollingwill start the query. - Calling the
useLazyQueryexecution function will now behave more likerefetch.previousDatawill be preserved. standbyfetchPolicies will now act likeskip: truemore consistently.- Calling
refetchon a skipped query will have no effect (issue #8270). - Prevent
onErrorandonCompletedfunctions from firing continuously, and improving their polling behavior.
-
- 3.5.0-rc.33 Nov 2021pre-release
Nothing published for this version
- 3.5.0-rc.222 Oct 2021pre-release
Nothing published for this version
- 3.5.0-rc.14 Oct 2021pre-release
Nothing published for this version
- 3.5.0-rc.04 Oct 2021pre-release
Nothing published for this version
- 3.5.0-beta.181 Oct 2021pre-release
Nothing published for this version
- 3.5.0-beta.1727 Sept 2021pre-release
Nothing published for this version
- 3.5.0-beta.1620 Sept 2021pre-release
Nothing published for this version
- 3.5.0-beta.1517 Sept 2021pre-release
Nothing published for this version
- 3.5.0-beta.1417 Sept 2021pre-release
Nothing published for this version
- 3.5.0-beta.1313 Sept 2021pre-release
Nothing published for this version
- 3.5.0-beta.1210 Sept 2021pre-release
Nothing published for this version
- 3.5.0-beta.1130 Aug 2021pre-release
Nothing published for this version
- 3.5.0-beta.1030 Aug 2021pre-release
Nothing published for this version
- 3.5.0-beta.926 Aug 2021pre-release
Nothing published for this version
- 3.5.0-beta.824 Aug 2021pre-release
Nothing published for this version
- 3.5.0-beta.723 Aug 2021pre-release
Nothing published for this version
- 3.5.0-beta.618 Aug 2021pre-release
Nothing published for this version
- 3.5.0-beta.59 Aug 2021pre-release
Nothing published for this version
- 3.5.0-beta.44 Aug 2021pre-release
Nothing published for this version
- 3.5.0-beta.33 Aug 2021pre-release
Nothing published for this version
- 3.5.0-beta.22 Aug 2021pre-release
Nothing published for this version
- 3.5.0-beta.129 Jul 2021pre-release
Nothing published for this version
- 3.5.0-beta.028 Jul 2021pre-release
Nothing published for this version
- 3.4.178 Nov 2021
Release notes2 sources agree
Open source →Improvements
- Allow
TOptions extends FieldFunctionOptionsto be passed as final (optional) type parameter ofFieldPolicytype. <br/> @VictorGaiva in #9000
- Allow
- 3.4.164 Oct 2021
Release notes2 sources agree
Open source →Improvements
-
Prevent webpack from misresolving the
graphqlpackage as the local@apollo/client/utilities/globals/graphql.jsmodule whenmodule.exports.resolve.preferRelativeis enabled inwebpack.config.js.Note: if you encounter strange module resolution errors like
export 'isType' (imported as 'isType') was not found in 'graphql' (possible exports: removeTemporaryGlobals)please try removingpreferRelative: truefrom yourwebpack.config.jsfile, or find a way to disable that resolution behavior for packages withinnode_modules. -
Avoid importing
isTypefrom thegraphqlpackage internally, to prevent bundlers from including as much as 3.4kB of unnecessary code. <br/> @benjamn in #8891 -
Make
client.resetStoreandclient.clearStorepass appropriatediscardWatchesoption tocache.reset. <br/> @benjamn in #8873
-
- 3.4.1527 Sept 2021
- 3.4.1427 Sept 2021
Release notes2 sources agree
Open source →Bug Fixes
-
Disable
InMemoryCacheresult object canonization by default, to prevent unexpected memory growth and/or reuse of object references, with multiple ways to reenable it (per-cache, per-query, or a mixture of both). <br/> @benjamn in #8822 -
Clear
InMemoryCachewatchesset whencache.reset()called. <br/> @benjamn in #8826 -
Stop excluding observerless queries from
refetchQueries: [...]selection. <br/> @benjamn in #8825 -
Prevent optimistic cache evictions from evicting non-optimistic data. <br/> @benjamn in #8829
-
Ensure
cache.broadcastWatchpasses all relevantWatchOptionstocache.diffasDiffOptions. <br/> @benjamn in #8832
-
- 3.4.1320 Sept 2021
Release notes2 sources agree
Open source →Bug Fixes
-
Fix
componentDidUpatetypo inwithSubscriptionhigher-order component. <br/> @YarBez in #7506 -
Fix internal
canUseSymbolimport within@apollo/client/utilitiesto avoid breaking bundlers/builds. <br/> @benjamn in #8817 -
Tolerate unfreezable objects like
Uint8ArrayandBufferinmaybeDeepFreeze. <br/> @geekuillaume and @benjamn in #8813
-
- 3.4.1217 Sept 2021
Release notes2 sources agree
Open source →Bug Fixes
-
Improve handling of falsy
existingand/orincomingparameters inrelayStylePaginationfield policy helper function. <br/> @bubba and @benjamn in #8733 -
Associate Apollo context with
React.createContext(instead of using a localWeakMap) again, so multiple copies of@apollo/client(uncommon) can share the same context. <br/> @benjamn in #8798
-
- 3.4.1110 Sept 2021
Release notes2 sources agree
Open source →Bug Fixes
- Fix Vite tree-shaking by calling the
checkDEV()function (at least once) in the module that exports it,@apollo/client/utilities/globals/index.ts. <br/> @benjamn in #8767
Improvements
- Export
PersistedQueryLinknamespace from@apollo/client/link/persisted-queries. <br/> @vedrani in #8761
Documentation
- Upgrade docs theme for new Algolia-powered search experience. <br/> @trevorblades in #8768
- Fix Vite tree-shaking by calling the
- 3.4.1027 Aug 2021
Release notes2 sources agree
Open source →Improvements
- Warn when calling
refetch({ variables })instead ofrefetch(variables), except for queries that declare a variable named$variables(uncommon). <br/> @benjamn in #8702
Bug Fixes
-
Fix
ObservableQuery.getCurrentResult()returning cacheddatawith certain fetch policies. <br/> @brainkim in #8718 -
Prevent
ssrMode/ssrForceFetchDelayfrom causing queries to hang. <br/> @brainkim in #8709 -
Import
@apollo/client/utilities/globalsinternally wherever__DEV__is used, not just in@apollo/client/**/index.jsentry points. <br/> @benjamn in #8720
- Warn when calling
- 3.4.924 Aug 2021
Release notes2 sources agree
Open source →Bug Fixes
-
Fix unhandled
Promiserejection warnings/errors whose message isObservable cancelled prematurely. <br/> @benjamn in #8676 -
Enforce that
__DEV__is polyfilled by every@apollo/client/*entry point that uses it. This build step considers not only explicit__DEV__usage but also__DEV__references injected nearinvariant(...)andnew InvariantError(...)expressions. <br/> @benjamn in #8689
-
- 3.4.816 Aug 2021
Release notes2 sources agree
Open source →Bug Fixes
-
Fix error thrown by nested
keyFields: ["a", ["b", "c"], "d"]type policies when writing results into the cache where any of the key fields (.a,.a.b,.a.c, or.d) have been renamed by query field alias syntax. <br/> @benjamn in #8643 -
Fix regression from PR #8422 (first released in
@apollo/[email protected]) that causedresult.datato be set to undefined in some cases afterObservableQuery#getCurrentResultreads an incomplete result from the cache. <br/> @benjamn in #8642
-
- 3.4.79 Aug 2021
- 3.4.69 Aug 2021
Release notes2 sources agree
Open source →Improvements
-
Reevaluate
window.fetcheach timeHttpLinkuses it, if not configured usingoptions.fetch. This change enables a variety of strategies for instrumentingwindow.fetch, without requiring those strategies to run before@apollo/client/link/httpis first imported. <br/> @benjamn in #8603 -
Clarify mutation
fetchPolicyoptions ("network-only"or"no-cache") usingMutationFetchPolicyunion type. <br/> @benjamn in #8602
Bug Fixes
-
Restore full
@apollo/client/apollo-client.cjs.jsCommonJS bundle for older bundlers.Note that Node.js and CommonJS bundlers typically use the bundles specified by
"main"fields in our generatedpackage.jsonfiles, which are all independent and non-overlapping CommonJS modules. However,apollo-client.cjs.jsis just one big bundle, so mixing imports ofapollo-client.cjs.jswith the other CommonJS bundles is discouraged, as it could trigger the dual package hazard. In other words, please don't start usingapollo-client.cjs.jsif you're not already. <br/> -
Log
MissingFieldErrors inObservableQuery#getCurrentResultusinginvariant.debug, rather than reporting them viaresult.error. <br/> @benjamn in #8604
-
- 3.4.54 Aug 2021
Release notes2 sources agree
Open source →Bug Fixes
-
Fix double registration bug for mutation
refetchQueriesspecified using legacy one-timerefetchQueries: [{ query, variables }]style. Though the bug is fixed, we recommend usingrefetchQueries: [query]instead (when possible) to refetch an existing query using itsDocumentNode, rather than creating, executing, and then deleting a new query, as the legacy{ query, variables }style unfortunately does. <br/> @benjamn in #8586 -
Fix
useQuery/useLazyQuerystalling when clients or queries change. <br/> @brainkim in #8589
-
- 3.4.43 Aug 2021
- 3.4.32 Aug 2021
Release notes2 sources agree
Open source → - 3.4.22 Aug 2021
- 3.4.129 Jul 2021
- 3.4.028 Jul 2021
Release notes
Open source →Apollo Client 3.4.0
New documentation
- Refetching queries with
client.refetchQueries. @StephenBarlow and @benjamn in #8265
Improvements
-
InMemoryCachenow guarantees that any two result objects returned by the cache (fromreadQuery,readFragment, etc.) will be referentially equal (===) if they are deeply equal. Previously,===equality was often achievable for results for the same query, on a best-effort basis. Now, equivalent result objects will be automatically shared among the result trees of completely different queries. This guarantee is important for taking full advantage of optimistic updates that correctly guess the final data, and for "pure" UI components that can skip re-rendering when their input data are unchanged. @benjamn in #7439 -
Mutations now accept an optional callback function called
onQueryUpdated, which will be passed theObservableQueryandCache.DiffResultobjects for any queries invalidated by cache writes performed by the mutation's finalupdatefunction. UsingonQueryUpdated, you can override the defaultFetchPolicyof the query, by (for example) callingObservableQuerymethods likerefetchto force a network request. This automatic detection of invalidated queries provides an alternative to manually enumerating queries using therefetchQueriesmutation option. Also, if you return aPromisefromonQueryUpdated, the mutation will automatically await thatPromise, rendering theawaitRefetchQueriesoption unnecessary. @benjamn in #7827 -
Support
client.refetchQueriesas an imperative way to refetch queries, without having to passoptions.refetchQueriestoclient.mutate. @dannycochran in #7431 -
Improve standalone
client.refetchQueriesmethod to support automatic detection of queries needing to be refetched. @benjamn in #8000 -
Fix remaining barriers to loading
@apollo/client/coreas native ECMAScript modules from a CDN like esm.run. Importing@apollo/clientfrom a CDN will become possible once we move all React-related dependencies into@apollo/client/reactin Apollo Client 4. @benjamn in #8266 -
InMemoryCachesupports a new method calledbatch, which is similar toperformTransactionbut takes named options rather than positional parameters. One of these named options is anonDirty(watch, diff)callback, which can be used to determine which watched queries were invalidated by thebatchoperation. @benjamn in #7819 -
Allow
merge: truefield policy to mergeReferenceobjects with non-normalized objects, and vice-versa. @benjamn in #7778 -
Allow identical subscriptions to be deduplicated by default, like queries. @jkossis in #6910
-
Always use
POSTrequest when falling back to sending full query with@apollo/client/link/persisted-queries. @rieset in #7456 -
The
FetchMoreQueryOptionstype now takes two instead of three type parameters (<TVariables, TData>), thanks to usingPartial<TVariables>instead ofK extends typeof TVariablesandPick<TVariables, K>. @ArnaudBarre in #7476 -
Pass
variablesandcontextto a mutation'supdatefunction. Note: The type of theupdatefunction is now namedMutationUpdaterFunctionrather thanMutationUpdaterFn, since the older type was broken beyond repair. If you are usingMutationUpdaterFnin your own code, please useMutationUpdaterFunctioninstead. @jcreighton in #7902 -
A
resultCacheMaxSizeoption may be passed to theInMemoryCacheconstructor to limit the number of result objects that will be retained in memory (to speed up repeated reads), and callingcache.reset()now releases all such memory. @SofianHn in #8701 -
Fully remove result cache entries from LRU dependency system when the corresponding entities are removed from
InMemoryCacheby eviction, or by any other means. @sofianhn and @benjamn in #8147 -
Add expected/received
variablestoNo more mocked responses...error messages generated byMockLink. @markneub in #8340 -
The
InMemoryCacheversion of thecache.gcmethod now supports additional options for removing non-essential (recomputable) result caching data. @benjamn in #8421 -
Suppress noisy
Missing cache result fields...warnings by default unlesssetLogVerbosity("debug")called. @benjamn in #8489 -
Improve interaction between React hooks and React Fast Refresh in development. @andreialecu in #7952
Potentially disruptive changes
-
To avoid retaining sensitive information from mutation root field arguments, Apollo Client v3.4 automatically clears any
ROOT_MUTATIONfields from the cache after each mutation finishes. If you need this information to remain in the cache, you can prevent the removal by passing thekeepRootFields: trueoption toclient.mutate.ROOT_MUTATIONresult data are also passed to the mutationupdatefunction, so we recommend obtaining the results that way, rather than usingkeepRootFields: true, if possible. @benjamn in #8280 -
Internally, Apollo Client now controls the execution of development-only code using the
__DEV__global variable, rather thanprocess.env.NODE_ENV. While this change should not cause any visible differences in behavior, it will increase your minified+gzip bundle size by more than 3.5kB, unless you configure your minifier to replace__DEV__with atrueorfalseconstant, the same way you already replaceprocess.env.NODE_ENVwith a string literal like"development"or"production". For an example of configuring a Create React App project without ejecting, see this pull request for our React Apollo reproduction template. @benjamn in #8347 -
Internally, Apollo Client now uses namespace syntax (e.g.
import * as React from "react") for imports whose types are re-exported (and thus may appear in.d.tsfiles). This change should remove any need to configureesModuleInteroporallowSyntheticDefaultImportsintsconfig.json, but might require updating bundler configurations that specify named exports of thereactandprop-typespackages, to include exports likecreateContextandcreateElement(example). @devrelm in #7742 -
Respect
no-cachefetch policy (by not reading anydatafrom the cache) forloading: trueresults triggered bynotifyOnNetworkStatusChange: true. @jcreighton in #7761 -
The TypeScript return types of the
getLastResultandgetLastErrormethods ofObservableQuerynow correctly include the possibility of returningundefined. If you happen to be calling either of these methods directly, you may need to adjust how the calling code handles the methods' possibly-undefinedresults. @benjamn in #8394 -
Log non-fatal
invariant.errormessage when fields are missing from result objects written intoInMemoryCache, rather than throwing an exception. While this change relaxes an exception to be merely an error message, which is usually a backwards-compatible change, the error messages are logged in more cases now than the exception was previously thrown, and those new error messages may be worth investigating to discover potential problems in your application. The errors are not displayed for@client-only fields, so adding@clientis one way to handle/hide the errors for local-only fields. Another general strategy is to use a more precise query to write specific subsets of data into the cache, rather than reusing a larger query that contains fields not present in the writtendata. @benjamn in #8416 -
The
nextFetchPolicyoption forclient.watchQueryanduseQuerywill no longer be removed from theoptionsobject after it has been applied, and instead will continue to be applied any timeoptions.fetchPolicyis reset to another value, until/unless theoptions.nextFetchPolicyproperty is removed fromoptions. @benjamn in #8465 -
The
fetchMore,subscribeToMore, andupdateQueryfunctions returned from theuseQueryhook may now return undefined in edge cases where the functions are called when the component is unmounted. @noghartt in #7980
Bug fixes
-
In Apollo Client 2.x, a
refetchoperation would always replace existing data in the cache. With the introduction of field policymergefunctions in Apollo Client 3, existing field values could be inappropriately combined with incoming field values by a custommergefunction that does not realize arefetchhas happened.To give you more control over this behavior, we have introduced an
overwrite?: boolean = falseoption forcache.writeQueryandcache.writeFragment, and an option calledrefetchWritePolicy?: "merge" | "overwrite"forclient.watchQuery,useQuery, and other functions that acceptWatchQueryOptions. You can use these options to make sure anymergefunctions involved in cache writes forrefetchoperations get invoked withundefinedas their first argument, which simulates the absence of any existing data, while still giving themergefunction a chance to determine the internal representation of the incoming data.The default behaviors are
overwrite: trueandrefetchWritePolicy: "overwrite", which restores the Apollo Client 2.x behavior, but (if this change causes any problems for your application) you can easily recover the previous merging behavior by setting a default value forrefetchWritePolicyindefaultOptions.watchQuery:new ApolloClient({ defaultOptions: { watchQuery: { refetchWritePolicy: "merge", }, }, }) -
Make sure the
MockedResponseResultFunctiontype is re-exported. @hwillson in #8315 -
InMemoryCachenow coalescesEntityStoreupdates to guarantee only onestore.merge(id, fields)call peridper cache write. @benjamn in #8372 -
Fix polling when used with
<React.StrictMode>. @brainkim in #8414 -
Fix the React integration logging
Warning: Can't perform a React state update on an unmounted component. @wuarmin in #7745 -
Make
ObservableQuery#getCurrentResultalways callqueryInfo.getDiff(). @benjamn in #8422 -
Make
readFielddefault to reading from current object only when thefromoption/argument is actually omitted, not whenfromis passed toreadFieldwith an undefined value. A warning will be printed when this situation occurs. @benjamn in #8508 -
The
fetchMore,subscribeToMore, andupdateQueryfunctions no longer throwundefinederrors. @noghartt in #7980
Additional notes2 sources agree
Open source →New documentation
- Refetching queries with
client.refetchQueries. <br/> @StephenBarlow and @benjamn in #8265
Improvements
-
InMemoryCachenow guarantees that any two result objects returned by the cache (fromreadQuery,readFragment, etc.) will be referentially equal (===) if they are deeply equal. Previously,===equality was often achievable for results for the same query, on a best-effort basis. Now, equivalent result objects will be automatically shared among the result trees of completely different queries. This guarantee is important for taking full advantage of optimistic updates that correctly guess the final data, and for "pure" UI components that can skip re-rendering when their input data are unchanged. <br/> @benjamn in #7439 -
Mutations now accept an optional callback function called
onQueryUpdated, which will be passed theObservableQueryandCache.DiffResultobjects for any queries invalidated by cache writes performed by the mutation's finalupdatefunction. UsingonQueryUpdated, you can override the defaultFetchPolicyof the query, by (for example) callingObservableQuerymethods likerefetchto force a network request. This automatic detection of invalidated queries provides an alternative to manually enumerating queries using therefetchQueriesmutation option. Also, if you return aPromisefromonQueryUpdated, the mutation will automatically await thatPromise, rendering theawaitRefetchQueriesoption unnecessary. <br/> @benjamn in #7827 -
Support
client.refetchQueriesas an imperative way to refetch queries, without having to passoptions.refetchQueriestoclient.mutate. <br/> @dannycochran in #7431 -
Improve standalone
client.refetchQueriesmethod to support automatic detection of queries needing to be refetched. <br/> @benjamn in #8000 -
Fix remaining barriers to loading
@apollo/client/coreas native ECMAScript modules from a CDN like esm.run. Importing@apollo/clientfrom a CDN will become possible once we move all React-related dependencies into@apollo/client/reactin Apollo Client 4. <br/> @benjamn in #8266 -
InMemoryCachesupports a new method calledbatch, which is similar toperformTransactionbut takes named options rather than positional parameters. One of these named options is anonDirty(watch, diff)callback, which can be used to determine which watched queries were invalidated by thebatchoperation. <br/> @benjamn in #7819 -
Allow
merge: truefield policy to mergeReferenceobjects with non-normalized objects, and vice-versa. <br/> @benjamn in #7778 -
Allow identical subscriptions to be deduplicated by default, like queries. <br/> @jkossis in #6910
-
Always use
POSTrequest when falling back to sending full query with@apollo/client/link/persisted-queries. <br/> @rieset in #7456 -
The
FetchMoreQueryOptionstype now takes two instead of three type parameters (<TVariables, TData>), thanks to usingPartial<TVariables>instead ofK extends typeof TVariablesandPick<TVariables, K>. <br/> @ArnaudBarre in #7476 -
Pass
variablesandcontextto a mutation'supdatefunction. Note: The type of theupdatefunction is now namedMutationUpdaterFunctionrather thanMutationUpdaterFn, since the older type was broken beyond repair. If you are usingMutationUpdaterFnin your own code, please useMutationUpdaterFunctioninstead. <br/> @jcreighton in #7902 -
A
resultCacheMaxSizeoption may be passed to theInMemoryCacheconstructor to limit the number of result objects that will be retained in memory (to speed up repeated reads), and callingcache.reset()now releases all such memory. <br/> @SofianHn in #8107 -
Fully remove result cache entries from LRU dependency system when the corresponding entities are removed from
InMemoryCacheby eviction, or by any other means. <br/> @sofianhn and @benjamn in #8147 -
Expose missing field errors in results. <br/> @brainkim in #8262
-
Add expected/received
variablestoNo more mocked responses...error messages generated byMockLink. <br/> @markneub in #8340 -
The
InMemoryCacheversion of thecache.gcmethod now supports additional options for removing non-essential (recomputable) result caching data. <br/> @benjamn in #8421 -
Suppress noisy
Missing cache result fields...warnings by default unlesssetLogVerbosity("debug")called. <br/> @benjamn in #8489 -
Improve interaction between React hooks and React Fast Refresh in development. <br/> @andreialecu in #7952
Potentially disruptive changes
-
To avoid retaining sensitive information from mutation root field arguments, Apollo Client v3.4 automatically clears any
ROOT_MUTATIONfields from the cache after each mutation finishes. If you need this information to remain in the cache, you can prevent the removal by passing thekeepRootFields: trueoption toclient.mutate.ROOT_MUTATIONresult data are also passed to the mutationupdatefunction, so we recommend obtaining the results that way, rather than usingkeepRootFields: true, if possible. <br/> @benjamn in #8280 -
Internally, Apollo Client now controls the execution of development-only code using the
__DEV__global variable, rather thanprocess.env.NODE_ENV. While this change should not cause any visible differences in behavior, it will increase your minified+gzip bundle size by more than 3.5kB, unless you configure your minifier to replace__DEV__with atrueorfalseconstant, the same way you already replaceprocess.env.NODE_ENVwith a string literal like"development"or"production". For an example of configuring a Create React App project without ejecting, see this pull request for our React Apollo reproduction template. <br/> @benjamn in #8347 -
Internally, Apollo Client now uses namespace syntax (e.g.
import * as React from "react") for imports whose types are re-exported (and thus may appear in.d.tsfiles). This change should remove any need to configureesModuleInteroporallowSyntheticDefaultImportsintsconfig.json, but might require updating bundler configurations that specify named exports of thereactandprop-typespackages, to include exports likecreateContextandcreateElement(example). <br/> @devrelm in #7742 -
Respect
no-cachefetch policy (by not reading anydatafrom the cache) forloading: trueresults triggered bynotifyOnNetworkStatusChange: true. <br /> @jcreighton in #7761 -
The TypeScript return types of the
getLastResultandgetLastErrormethods ofObservableQuerynow correctly include the possibility of returningundefined. If you happen to be calling either of these methods directly, you may need to adjust how the calling code handles the methods' possibly-undefinedresults. <br/> @benjamn in #8394 -
Log non-fatal
invariant.errormessage when fields are missing from result objects written intoInMemoryCache, rather than throwing an exception. While this change relaxes an exception to be merely an error message, which is usually a backwards-compatible change, the error messages are logged in more cases now than the exception was previously thrown, and those new error messages may be worth investigating to discover potential problems in your application. The errors are not displayed for@client-only fields, so adding@clientis one way to handle/hide the errors for local-only fields. Another general strategy is to use a more precise query to write specific subsets of data into the cache, rather than reusing a larger query that contains fields not present in the writtendata. <br/> @benjamn in #8416 -
The
nextFetchPolicyoption forclient.watchQueryanduseQuerywill no longer be removed from theoptionsobject after it has been applied, and instead will continue to be applied any timeoptions.fetchPolicyis reset to another value, until/unless theoptions.nextFetchPolicyproperty is removed fromoptions. <br/> @benjamn in #8465 -
The
fetchMore,subscribeToMore, andupdateQueryfunctions returned from theuseQueryhook may now return undefined in edge cases where the functions are called when the component is unmounted <br/> @noghartt in #7980.
Bug fixes
-
In Apollo Client 2.x, a
refetchoperation would always replace existing data in the cache. With the introduction of field policymergefunctions in Apollo Client 3, existing field values could be inappropriately combined with incoming field values by a custommergefunction that does not realize arefetchhas happened.To give you more control over this behavior, we have introduced an
overwrite?: boolean = falseoption forcache.writeQueryandcache.writeFragment, and an option calledrefetchWritePolicy?: "merge" | "overwrite"forclient.watchQuery,useQuery, and other functions that acceptWatchQueryOptions. You can use these options to make sure anymergefunctions involved in cache writes forrefetchoperations get invoked withundefinedas their first argument, which simulates the absence of any existing data, while still giving themergefunction a chance to determine the internal representation of the incoming data.The default behaviors are
overwrite: trueandrefetchWritePolicy: "overwrite", which restores the Apollo Client 2.x behavior, but (if this change causes any problems for your application) you can easily recover the previous merging behavior by setting a default value forrefetchWritePolicyindefaultOptions.watchQuery:new ApolloClient({ defaultOptions: { watchQuery: { refetchWritePolicy: "merge", }, }, }); -
Make sure the
MockedResponseResultFunctiontype is re-exported. <br/> @hwillson in #8315 -
InMemoryCachenow coalescesEntityStoreupdates to guarantee only onestore.merge(id, fields)call peridper cache write. <br/> @benjamn in #8372 -
Fix polling when used with
<React.StrictMode>. <br/> @brainkim in #8414 -
Fix the React integration logging
Warning: Can't perform a React state update on an unmounted component. <br/> @wuarmin in #7745 -
Make
ObservableQuery#getCurrentResultalways callqueryInfo.getDiff(). <br/> @benjamn in #8422 -
Make
readFielddefault to reading from current object only when thefromoption/argument is actually omitted, not whenfromis passed toreadFieldwith an undefined value. A warning will be printed when this situation occurs. <br/> @benjamn in #8508 -
The
fetchMore,subscribeToMore, andupdateQueryfunctions no longer throwundefinederrors <br/> @noghartt in #7980.
- Refetching queries with
- 3.4.0-rc.2323 Jul 2021pre-release
Nothing published for this version
- 3.4.0-rc.2222 Jul 2021pre-release
Nothing published for this version
- 3.4.0-rc.2119 Jul 2021pre-release
Nothing published for this version
- 3.4.0-rc.2015 Jul 2021pre-release
Nothing published for this version
- 3.4.0-rc.1912 Jul 2021pre-release
Nothing published for this version
- 3.4.0-rc.189 Jul 2021pre-release
Nothing published for this version
- 3.4.0-rc.176 Jul 2021pre-release
Nothing published for this version
- 3.4.0-rc.166 Jul 2021pre-release
Nothing published for this version
- 3.4.0-rc.1528 Jun 2021pre-release
Nothing published for this version
- 3.4.0-rc.1424 Jun 2021pre-release
Nothing published for this version
- 3.4.0-rc.1323 Jun 2021pre-release
Nothing published for this version
- 3.4.0-rc.1222 Jun 2021pre-release
Nothing published for this version
- 3.4.0-rc.1117 Jun 2021pre-release
Nothing published for this version