Building Native Mobile Apps with GraphQL

For almost a year now, attention of the whole Meteor community has been drawn to the Apollo project. At ReactEurope 2016 conference, Martijn Walraven from Meteor Development Group (MDG) gave a one-sentence summary of what Apollo is about:

It’s about building tools to improve the GraphQL developer experience.

Connection of GraphQL to different backend and frontend technologies, and the languages other than JavaScript is a challenge the MDG is dealing with. There are server side implementations of GraphQL in different languages, e.g. Python, Scala, but the client still mostly remains in JavaScript. The main focus of the Apollo team is on modularity, transparency and simplicity. They strive to build tools that

do one thing well

are easy to understand

are easy to debug

offer an API surface that helps to integrate these tools into new
environments.

In 2012 the Facebook team rewrote its main app from HTML5-based to a fully
native iOS application. GraphQL data querying language was developed as a
part of this effort. However, today there’s still no easy way of using
GraphQL in native mobile environments outside of Facebook.

Mobile as an Important Use Case for GraphQL

The main issue for mobile clients is that they connect to networks with fairly high latency (even up to several seconds). That’s why it’s strongly desired to avoid repeated round trips to get data for the single view.

You start out with a neatly designed REST structure, separate
endpoints for every object.

When you need the data together, and still want to avoid repeated round
trips, you create new endpoints: the ones that give you exactly the
data you need.

Since there are multiple clients for different platforms with
slightly different data requirements, you’re sending data to the
clients that don’t actually need it. You are overfetching data.

And when you consider different versions of these clients, for
major versions you may actually have to create new endpoints.
Endpoints that you’d have to maintain, and that duplicate code.

It’s obvious that the whole REST model of clients connecting to separate endpoints and servers deciding what to send is unscalable.

GraphQL is an amazing solution to this:

the server defines what data is available to clients in a form of a
GraphQL schema;

clients write queries that specify the exact data needs that they have.

Thus, it’s a great way of decoupling of the clients and services.

How to Connect a Mobile App to a GraphQL Server?

Every developer who would like to find an answer to this question will face
the following challenges:

the technology used in Facebook is tightly coupled to the Facebook
infrastructure and is not open-source

the GraphQL specification is well-written, however, it’s quite
overwhelming, and hardly will help to convince people that GraphQL
is simple.

Martijn shows an example app to demonstrate the capabilities of GraphQL
clients. The GraphQL schema that underlies this app contains data both from
an application specific database, and information that comes from the
GitHub API. Martijn mentions a few ways to query the information in this
schema in a native app.

HTTP POST request with GraphQL query.

The basic conceptual model of
GraphQL is Request => Response.

The most often used network transport is HTTP. There’s a simple way to make
HTTP POST request with GraphQL query and get JSON back. This gives a lot of
the GraphQL benefits without doing much Graph QL specific work on a client.
But it does not fully utilize GraphQL.

Typing and code generation. It’s convenient to use JSON format with plain JavaScript objects. However, it gets difficult in tight languages like Swift or Java, as you have to cast and to make sure you don’t return NULLs. To avoid this you can insert a typed layer that parses JSON responses into typed objects. GraphQL has a nice built in type system. So you could generate value types based on the GraphQL type information.

Yet, type generation based on the GraphQL schema has its drawbacks.

Fields generation in the classes causes the schemas grow.
Eventually, they may contain hundreds of fields. And you definitely
don’t want all that information in your data types.

When you specify the exact data needs in a query, you want to make
sure that in your UI code you only have access to the existing
requested data.

As the types are specific to the part of the query they are in, Martijn
also suggests using fragments to generate interfaces or protocols. This
would give a really easy way of getting both type safety and the ability to
still have query-specific data classes.

Martijn shows a corresponding demo in swift,
and remarks that similar solution is applicable for Java as well.

GraphQL Clients and Data Consistency

Quite often you make a query and use the value you get to show something in
your UI. As the values may change in time, when you repeat the same query,
you get a value different from the one you’ve got the first time. However,
the original UI component will not update automatically. So, what you want
as a GraphQL client is a single source of truth. Martijn shows the way to
use a normalized data cache to make sure that objects have a single
representation in the system.

Break up the tree of your query into separate objects

Normalize the results

Store those results separately using an object ID

Use that single normalized cache to distribute data to your
different UI components.

Consequently, the client uses the queries bound to UI components to query
the cache. This gives the results of the queries you’ve done yourself, and
also updates information that might come in from other queries, or even
from other update mechanisms. In addition, this allows to minimize the
queries that you actually send to the server. Moreover, you can reuse the
information that’s already in the cache, and only query for information
that’s not there.

What’s next?

Martijn shared his plans to work on the other topics interesting for mobile
developers. Those include mutations, offline support, pagination, fragment
composition - things we know from the sophisticated JavaScript clients like
Relay, and that definitely have their place on mobile.

As Apollo is a community-driven project, he encourages developers who are
interested in using GraphQL to share their ideas. The common effort will
certainly help to bring native clients base for GraphQL further.

It's a pleasure for us to work on projects which include GraphQL development. With the benefits, mentioned above, we believe that the technology might find its place in your marketplace platform creation process.