A few weeks ago, we shipped mission control, a new dashboard for Fabric that shows you the most important information across all of your apps on the same page. To build it, we turned to two fairly new technologies, GraphQL and Relay, because of the flexibility they bring to fetching data. Although investigating and productionizing these new technologies added an upfront cost to the project, we found that they paid off over the course of development and we’re excited by their potential as we develop more for Fabric.

What does it take to responsibly dive headfirst into a new technology and framework? Here’s how we went about it:

Bringing together the data

Just from the description of mission control (“all your apps, all their important information”), we knew that we were going to faceplant into the limitations of our existing API architecture. Before mission control, pages on fabric.io were limited to showing one kit’s worth of information for one app at a time, and our RESTful APIs and backend data providers reflected that design. If we were going to show you the most important data for any of your kits, for all of your apps, in under 500 network requests from the browser, we’d need to build something new.

That “new” could have been mission control–specific endpoints in our Ruby on Rails API layer, but, as we’ll see, that would have been forcing an architecture we already weren’t satisfied with to do something it wasn’t suited for. Instead, we took this as an opportunity to vet GraphQL, a technology that, on its surface, was tailor-made to our problem. If this experiment went well, we could see ourselves adopting GraphQL for more features, bringing its benefits to all Fabric teams.

Rendering a page with the information diversity and density we were going for requires making multiple API calls to a variety of backend systems, such as those for Answers, Crashlytics, and Beta. A RESTful public endpoint that combined those sources would actually spend most of its time waiting for those API responses, something our existing Ruby on Rails setup is decidedly poor at. Making the API calls in serial would take far too long, but parallel requests in Rails would require bringing in a concurrency library like EventMachine, and even then we’d still be tying up one of our limited Unicorn processes for the duration of the request.

GraphQL for a better server

GraphQL, developed at Facebook, is a query language for, well, graphs of data. You start with a strongly-typed schema of your data, which is defined principly as objects and their fields. A user Account might have strings for name and email address, but it might also have a “connection” to a list of Apps. Those Apps will have their own fields, like name, icon, or current number of active users. An App might also have a connection back to a list of member Accounts. GraphQL lets you start at a “root” in your schema — say, the current account — and query for the subset of fields you’d like returned. In our case, one query might be for the account’s starred Apps, their names, icons, and the timestamp / value pairs of their daily and monthly active user data.

It’s important to note that the queries come from the client. For mission control, that’s a webapp written in JavaScript. The server is a general engine that can fulfill any query that matches the schema. That flexibility will be very important later on.

By using the reference GraphQL implementation, graphql-js, we would have access to Node’s native concurrency, giving us the “wait fast” behavior we want. Backend API requests could happen in parallel, and running out of Unicorn workers during those waits wouldn’t be a concern. This has since been proven in production: loading the mission control details for an app can approach two dozen internal API requests but still return in only a few hundred milliseconds to the browser.

Relay for a better process

Adopting GraphQL would also give us the opportunity to adopt Relay, another Facebook library that integrates GraphQL and React (we love React). Relay essentially annotates React components with a GraphQL query that describes the data they need for rendering. Defining the query next to the rendering code allows a component to be developed and maintained in isolation, rather than in concert with server-side API changes. That means it’s faster and easier to make changes during development.

We knew we would be rapidly iterating mission control in response to usability studies and beta tester feedback, so anything that reduced what we needed to change to bring in new data would pay off and speed those cycles up. Having new data available with just a tweak to the GraphQL query and a hot reload in the browser changed how we were able to work. We iterated on mission control in mob sessions with our product manager and designer, and Relay let us instantly respond to their feedback and see changes working live.