GraphQL is something you may have heard in passing, usually from the web team. It's a Facebook API technology, that describes itself as a A Data Query Language and Runtime. GraphQL is a spec, and there are multiple implementations of it. As mobile engineers, we can consider it an API, where the front-end team have as much control as the backend.

This blog post covers our usage of GraphQL, and what I've learned in the last 3 months of using it in Eigen.

So what is GraphQL

You can get the full explanation on the GraphQL website. Though, I found running through Learn GraphQL site to really hammer down how it works. Reading the introduction blog post can be useful too.

GraphQL is an API middle-layer. It acts as an intermediate layer between multiple front-end clients and multiple back-end APIs. This means it can easily coalesce multiple API calls into a single request, this can be a massive user experience improvement when you have a screen that requires information from multiple sources before you can present anything to a user.

As a client, you send a "JSON-shaped query" structure, which is hierarchical and easy to read:

1
2
3
4
5
6
7
8
9
{
  artwork(id: "kimber-berry-as-close-to-magic-as-you-can-get") {
    id
    additional_information

    is_price_hidden
    is_inquireable
  }
}

This will search for a specific artwork, sending back the Artwork's id, additional_information, is_price_hidden and is_inquireable.

It's important to note here, the data being sent back is only what you ask for. This is not defined on the server as a short or embedded version of a model, but the specific data the client requested. When bandwidth and speed is crucial, this is the other way in which GraphQL improves the app-user experience.

That's the two killer features:

  1. Coalesce Multiple Network Requests. Reducing the amount of network requests that need to be made.
  2. Only Send The Data You Want. Only sending the data you are interested in.

With mobile apps you're working with unreliable, slow networks with high bandwidth costs. Optimising towards less networking with richer data means your app is more resiliant to things outside of your control.

This is in stark contrast to existing API concepts, like HAL and JSON-API - both of which are optimised for caching, and rely on "one model, one request" types of API access. E.g. a list of Artworks would actually contain a list of hrefs instead of the model data, and you have to fetch each model as a separate request.

Using GraphQL

Artsy's GraphQL server is (unsurprisingly) open-source, it's at artsy/metaphysics. However, it's not publicly accessible, (yet?). One of the coolest things about developing against a GraphQL server is GraphiQL - an IDE for exploring your API. I can't show you ours, but I can send you to Clay Allsop's GraphQLHub:

Here ( I strongly recommend pausing to open that link in a new window. Press cmd + enter to see the results. We also have an example of refactoring that request here. )

GraphQL comes with a playground for the API! It's amazing! Clay called it the "Killer App" of GraphQL - I'm inclined to concur. I've never had API docs this useful. This is built on top of the schema/docs/type reflection APIs inside the GraphQL spec.

 
 

How GraphQL Changed How We Write Native Code

View Models

Our GraphQL server is owned by the web-practice and the mobile practice also help out occasionally. This ownership distinction is important, an API like this would normally be handled by our platform team.

Because of Metaphysics' ownership as a "front-end" product, it can contain additional information that is specific to front-end needs. For example, in our first example of a request to our GraphQL server we requested id, additional_information, is_price_hidden and is_inquireable - only two of these items come from the database. Both is is_price_hidden and is_inquireable are derived from the API results on the server.

This is awesome, because before a lot of this logic existed in a Google Doc which needed to be re-implemented in 3-4 clients. On the native side we would find we were out-of-date mid-release cycle and needed to rush to catch up.

So, what does this mean for view models? It lessens the need for them. If you can move a lot of your derived data to the server - this handles the logic that goes in a view model for you. Now it is provided server-side, and is consistent across platforms.

We've not stopped writing view models, but now discussions on them includes "should this move to Metaphysics?".

React Native

We've already shipped one full view controller in React Native for our flagship app, Eigen. The advantages that came from GraphQL were a big part of the discussion around using React Native.

There will be longer articles on the "why" and "how" we choose to work this way. However, the key thing that we're excited about in using React Native is Relay. Using Relay, our views can declare a fragment of the GraphQL query that each respective view needs.

So, in our Artist View Controller, the Biography "View" (component) declares "when I am in the view hierarchy, you need to grab a bio, and blurb"

1
2
3
4
5
6
7
8
9
10
export default Relay.createContainer(Biography, {
  fragments: {
    artist: () => Relay.QL`
      fragment on Artist {
        bio
        blurb
      }
    `,
  }
});

Once your views are declaring what data they need, and are acting on that data - you see less of a need to use models.


GraphQL is having a massive impact in the way that we write our apps. It means we can make much faster mobile apps, as the network is our critical path. Faster apps means happier users, happier users means happier developers. I want to be happy. So I'm thankful that the Web practice gave GraphQL a try, and welcome'd us to the party.

Categories: eigen, graphql, mobile

Part of a series: React Native at Artsy