Apollo Client 0.5
Last week during GraphQL summit, we released Apollo Client 0.5, with several awesome new features and a few bug fixes. With the 0.5 release, Apollo Client is officially fully featured, stable and ready to be used in production.
This post is a quick overview of where we stand today, what’s changed since the last version, and a look into the future of Apollo Client and GraphQL.
Apollo Client today
I’m absolutely amazed by how far we’ve come with Apollo Client since the project’s start in March of this year. We set out to build a modular and powerful GraphQL client that works with any view layer and is at feature-parity with Relay. What we’ve achieved is much more than that: Not only have we built a fully-featured GraphQL client and grown our community to over 100 contributors, we’ve even added new cutting-edge features like subscriptions that advance the state of GraphQL.
Today we have over 1100 stars on GitHub and 25,000 monthly downloads on npm (now growing at 40% month over month!), and we have companies such as Coursera, CreditKarma, Google, Shopify and Zendesk among our users and contributors!
New Features since 0.4
It’s been several months since our last release, and with the help of our community, we’ve added a ton of features since then.
Here are just a few highlights:
We’ve added GraphQL subscriptions to Apollo Client. Subscriptions are great when you want your UI to stay up-to-date with what’s on the server, and polling isn’t fast enough. Right now, you can use subscriptions either with the
client.subscribe method, or with the
subscribeToMore method on the
ObservableQuery object returned by
client.watchQuery. See the docs.
Fully static queries
We’ve decided to make all queries fully static by removing query diffing from Apollo Client. This means that any query is sent to the server in full, if it cannot be read entirely fulfilled from the cache. Using only static queries enables much better tooling and instrumentation, and it’s one of the main differences between Relay 1 and the future Relay 2 that Facebook announced.
Sometimes you find yourself wanting to update the result of a query in the store based on the result of another operation — be it a mutation, a query or a subscription. Result reducers let you do exactly that. They receive all the Redux actions, and operate on the query result. They are similar to the
updateQueries function that already existed, but let you operate on any Redux action. See the docs.
Mutations now accept an
optimisticResponse argument, which is applied to the store immediately, and replaced with the real result from the server, once it’s returned. This can make the UI feel a lot faster in cases where you can predict the server result. See the docs.
In the latest version of Apollo Client, we’re exposing more information about the state of a query. Rather than just knowing when the query is loading and when it isn’t,
networkStatus tells you when the query’s variables were changed, and when it’s refetching, polling etc. To reduce unnecessary re-renders of your components, you have to explicitly request notifications by passing the
notifyOnNetworkStatusChange: true option to the query.
Bonus feature: Fragments
We’ve also created a package that lets you work with GraphQL fragments in your UI components in way that’s very similar to how things work in Relay. See the docs, and keep an eye out for a future blog post on this!
Sometimes you have to break things to make progress. Here are the two breaking changes we’ve made in the 0.5 release in order to improve stability and performance, and make Apollo Client easier to understand.
We’ve taken the batching option from Apollo Client and moved it to the network interface. Instead of passing the
shouldBatch option to Apollo Client, you can now do transport batching by using
createBatchingNetworkInterface to create a network interface that automatically batches queries. We’ve also removed query merging, which means that the new batching mechanism will only work with servers that support it (eg. graphql-server).
Stability, usability and performance improvements
We’ve also made some major changes to Apollo Client that are not visible to most users. These changes make Apollo Client more stable, faster and easier to use.
Standard library for store reads + writes
Apollo Client now uses the excellent graphql-anywhere package to read from and write to the normalized store. This has helped up simplify the client’s internals and eliminate several bugs in the process.
Tighter integration with React + Angular
We realized that there was a fair bit of similar code in the angular2-apollo and react-apollo packages, so we’ve taken that and moved it to Apollo Client itself to make it easier for other view layers like Ember and Vue.js to integrate with it. For example, we’ve added the ability to change the variables and options of an existing query, rather than having to make a new one.
As with every release, we’ve also fixed a number of bugs, most notably around loading state, store reset, fragment handling, and subscribing to the same query multiple times.
This was just a quick summary of the most important changes. You can find many more in the changelog.
Where we’re going from here
For the next release of Apollo Client, we’re going to focus on some of the features and improvements most requested by the community:
Client-side resolve functions
With client-side resolve functions, you’ll be able to extend the server-side GraphQL schema with computed fields on the client or combine it with data from another API. Client-side resolvers will also provide a way to tell Apollo Client if an item is already in the cache under a different key, thus saving a round-trip to the server
Currently, Apollo Client has very coarse-grained error handling and doesn’t write responses that contain an error to the store. In our next release, we will add the ability to decide on a per-field basis whether or not to write the result to the store, and expose the errors to the calling function in a way that lets you deal with it directly in the UI
Apollo Client is still under active development, and we wouldn’t be where we are without an amazing community of contributors. If you have ideas, suggestions, or time to contribute, we want to hear from you! Join our slack channel, file an issue or make a pull request!
Many thanks to everyone who contributed to this release!
Sashko Stubailo, Dhaivat Pandya, Jonas Helfer, Slava Kim, Tom Coleman, Amanda Liu, Robin Ricard, Kamil Kisiela, davidwoody, Edvin Erikson, Ruben, Jesper Håkansson, Olivier Ricordeau, Jason, James Baxley, Bryan White, Ian Grayson, David Alan Hjelle, Chris Metz, PsiCat, Pavol Fulop, Maxime Quandalle, John Pinkerton, Ian MacLeod, Hagai Cohen, Vladimir Guguiev, Tim Mikeladze, Rob Wilkinson, Pedro Almeida, Marc-André Giroux, Jack Moore, David Yahalomi, Daniel Rinehart and Agustin Polo!