May 18, 2016

Apollo Client: GraphQL with React and Redux

Sashko Stubailo
Frontend

Update (Sept 2016): We’ve released version 0.4.0 of react-apollo which has a new API. You can read all about it in James’ post, and learn how to use react-apollo in the documentation.

However, many of the concepts in this post still apply.


React and Redux are a great team, but Redux doesn’t have a built-in solution for server-side data fetching. That’s why we built Apollo Client, the simplest way to bind GraphQL server data to your React components.

We’re focusing on React and Redux in this post, but we’re also working on seamless integration with Angular 2, RxJS, Meteor, and other technologies. Follow our publication to find out more about those!

Simple, transparent data flow

If you’re using React, there’s a good chance you’re either using or have heard of Redux. It’s on the path to becoming the standard client-side data management pattern for React, and for good reason — its simple concepts and nice developer tools give you the ultimate control over your app.

Unfortunately the patterns for asynchronously loading server data in a Redux app aren’t as well established, and often involve using external helper libraries, like redux-saga. You need to write custom code to call your server endpoints, interpret the data, normalize it, and insert it into the store — all while keeping track of various error and loading states.

This causes people to reach for more automatic server data management platforms, like Relay and Meteor, which can make your code more concise and declarative, but introduce a heavy dose of magic: You need a lot of knowledge of Meteor or Relay internals to fully understand where the data in your app is going, when it’s getting loaded, and why.

Wouldn’t it be awesome if you could get the magic of Relay and Meteor, but with all of the simplicity, transparency, and tooling you love in Redux?

That’s why we’re building Apollo Client, the new GraphQL client:

  1. It’s small and self-contained, so you can just npm install apollo-client react-apollo and start loading data
  2. It’s compatible with all GraphQL servers
  3. It integrates seamlessly with Redux and has a simple data flow model, so you always understand what your app is doing

With Apollo Client, you don’t have to think about manual data fetching, but you can still inspect exactly what is happening internally and plug in your own custom logic wherever you need to!

Data flow in Apollo Client is simple — all data passes through Redux.

Let’s take a quick tour through Apollo Client’s main features!

Wrap components with queries

With React and other view frameworks today, everyone has pretty much agreed that declaratively specifying your view structure is the way to go. We don’t use document.createElement directly when manipulating the DOM, and that means the rendering engine of our framework can transparently optimize how to make our UI match the desired state.

Apollo Client allows us to do the same thing with data fetching. Rather than manually calling fetches from componentDidMount , we can just decorate our components with queries, and let Apollo fetch the data for us. Best of all, it works just like connecting our store data from Redux:

// Works just like `react-redux` connect
import { connect } from 'react-apollo';
import Category from './category';

function mapQueriesToProps({ ownProps, state }) {
  return {
    category: {
      query: gql`
        query getCategory($categoryId: Int!) {
          category(id: $categoryId) {
            name
            color
          }
        }
      `,
      variables: {
        categoryId: 5,
      },
    },
  };
};

const CategoryWithData = connect({
  mapQueriesToProps,
})(Category);

export default CategoryWithData;

Track query loading with Redux devtools

One of the potential worries of declarative data loading is that you can lose track of what is actually happening to get the data to the client. With Apollo that’s not a problem at all — it’s super easy to understand and keep track of exactly what it’s doing, thanks to an idiomatic integration with Redux devtools:

Screenshot of the Redux developer tools in an app using Apollo Client

Every lifecycle action Apollo Client dispatches is fully documented.

This is just the first step — we’re building more tooling that will make it very easy to associate your data fetches with the UI components, and even track those requests across the client/server boundary to see what impact they have on your backends and databases.

Using Redux state in queries

One thing that’s very common in all kinds of applications is using your client-side state to control what data you fetch from the server. We think it should be very natural to use client state from Redux to drive your component queries and mutations, which is why we made sure that every Apollo query can be manipulated based on component props and Redux state , right in the container:

function mapMutationsToProps({ ownProps, state }) {
  return {
    postReply: (raw) => ({
      mutation: gql`
        mutation postReply(
          $topic_id: ID!
          $category_id: ID!
          $raw: String!
        ) {
          ...
        }
      `,
      variables: {
        // Use the container component's props
        topic_id: ownProps.topic_id,

        // Use the redux state
        category_id: state.selectedCategory,

        // Use an argument passed from the triggering of the mutation
        raw,
      },
    }),
  };
};

This makes the Redux dev tools even more valuable, since you can track the client-side actions that changed selectedCategory , and then see how that affected the mutation sent to the server!

Most server data fetching libraries take a hands-off approach to client-side state. In Apollo, we think that it should be easy to use that data together, and keep track of it with one tool.

Try it now

You can try Apollo Client now! Read the documentation and check out some of the UI components in our sample app. The best part is, there’s not much to learn — just put in your GraphQL queries and get data in your components.

Let’s work together!

If this sounds really awesome, we’re looking for people to give us feedback about Apollo and to contribute on GitHub. Just let me know and I’ll hook you up — there’s tons of cool stuff to build!

If you’re excited about GraphQL or application data loading, don’t forget to follow Building Apollo to learn about new tools, ideas, and developments in GraphQL.

Huge shout out to James Baxley III and John Pinkerton for making the React Apollo integration so awesome.

Written by

Sashko Stubailo

Stay in our orbit!

Become an Apollo insider and get first access to new features, best practices, and community events. Oh, and no junk mail. Ever.

Similar posts

July 17, 2020

Introducing the Apollo Client Best Practices Series

by Khalil Stemmler

Company