Tales of a React Native Beginner: Why GraphQL🏆 Is The Real MVP

Charles D. Mangwa
hello JS
Published in
9 min readFeb 21, 2017

--

GraphQL and React Native walking down the street

In the previous episode

This article follows the previous one I wrote about my React Native and JavaScript learning experience. To fully understand all the references I’ll make in this article, I would recommend to have a look at it.

TL;DR: I started JavaScript and React Native about a year ago. It was hard, painful, I suffered, a lot
 Just kidding: the experience was top notch (and still is!). So throughout this so called “Year of learning”, I had the opportunity to work on 5~6 real-world apps. And today we’ll focus on one of them, Wino đŸ·: the app I’ve spent the most time on to this day!

Wino
wait what?

I have to give them this one: my friends really nailed it with the naming 😅
 2 years ago, 5 friends of mine started this adventure with a simple goal in mind:

Create the app that will tell you what wine you should buy, according to where and when you’ll be drinking it.

This is how Wino was born. They launched the 1st beta of the app back in 2015, and everything was going well!

Wino v0.5 👌

In July 2016, my brother in arms LĂ©o Le Bras came up to me and asked if I’d like to work on the v1 with him. And gosh did he have great plans about what we’ll be doing. As soon as I heard the worlds “React Native 
 Apollo Client 
 Apollo Server 
 GraphQL 
” coming out of his mouth I went full:

GraphQL: the real MVP

The main reason Wino distinguishes itself from any other apps I’ve worked on is fairly simple: it’s the 1st React Native project where I used GraphQL. For those who are not familiar with it:

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools. -graphql.org

I’ll suggest you to read Give it a REST: use GraphQL for your APIs by David Celis to understand what’s GraphQL, and why it’s more interesting than REST

People usually call every interaction with a GraphQL server a “query”. But the language supports 3 kinds of “requests”: mutations, subscriptions and 
 queries! That’s why we’ll talk about “GraphQL operations”. Sashko Stubailo from the Apollo core team broke down the anatomy of a GraphQL operation in this nice article.

As you can see, GraphQL lets you write some kind of JSON-ish operation and answers with the same format as your operation, plus your data. The possibilities given by this bad boy are pretty exciting, especially when you’re working on a mobile app! The app could fetch the exact amount of data it needs, when it needs it, and nothing else!

In order to use GraphQL in JavaScript, we choose Apollo Client for the app, and Apollo Server for 
 well, the servers. As you may have guessed, Apollo is a JavaScript GraphQL client.

From there, something really impressed me with this React Native # GraphQL combo:

Fetching, storing and using data is incredibly easy, no matter the quantity!

There are several levels of “complexity” with GraphQL operations, but if you keep things simple, here’s what it looks like:

As you can see, we are just asking who’s the hero of 2 different Star Wars movies, using arguments in our selection set (that’s how we call the content of a GraphQL operation). And then, GraphQL returns a data object that follows the same pattern as the operation. Easy peasy👌

But wouldn’t the best way to prove how cool and powerful this is to show it to you? Wino has a specific page where you can set up the city where you currently are. Here, we need cities’ name and background pattern as props of our Carousel component. As you can see, it’s a very simple example, but we could start from there. Well: let’s build our GraphQL operation for this part of the app!

Let’s start by writing something similar to our Star Wars example. Our operation should look like:

{
city {
id
image
location
name
}
}

Sounds like a good way to start. But what if our operation grows with time? What if we decide to also fetch every wine cellar in each city at the same time, or something more complicated? In order to solve these kind of problems where your operation could be too complex, GraphQL allows us to use fragments.

Fragments let you construct sets of fields, and then include them in operations where you need to.

So fragments are like Lego you can use to build a complex operation. For now, we seem to have a simple one, so we won’t need it. But at least you know they are there if you do! So as with any kind of request, we’ll break it down into 3 simple steps:

A. Write the operation

B. Fetch the data

C. Use the data

A. The Operation

For this part, we’ll need a new package named graphql-tag. It’s a JavaScript template literal tag that parses GraphQL operation strings into the standard GraphQL AST. Our file will look like this:

import gql from ‘graphql-tag’export const getAllCities = gql`
query getCities {
cities {
id
image
location
name
radius
}
}
`

That’s what a GraphQL operation looks like, a simple object without its value. We just exported getAllCities() that contains the real query getCities inside of it. As you can see, it’s pretty straightforward!

By the way, if you wonder what kind of sorcery this gql`
` syntax is, it’s an ES2015 feature called tagged template literals. Max Stoiber uses it in styled-components 💅 and wrote a great article about it!

B. The Data

Fragment ✅, operation ✅: we just need to fetch our data then! For this specific part, why not use a HOC (Higher-Order Component)? Not that we absolutely need it here, just to show that you can use Apollo with it.

A higher-order component is a function that takes a component and returns a new component. -React’s doc

By the way, Sashko Stubailo also wrote a great article about using Apollo & recompose to get nice and beautiful HOCs in your React components: you should definitely check it out!

import { compose } from 'recompose'
import { graphql } from 'react-apollo'
import { withRouter } from 'react-router-navigation'
import { getAllCities } from './queries'export default (component) => compose(
withRouter,
graphql(getAllCities),
)(component)

So our HOC -let’s call it connect- will take a React component as a parameter, add another HOC (withRouter) and the result of our query to its props, and then output a new component. So long story short:

Our GraphQL result is waiting for us in this.props.data.cities!

C. The Result

We just have to get cities out of this.props.data and we’re good to go:

import connect from './connect'const CitiesContainer = ({ children, ...props }) => children(props)
export default connect(CitiesContainer)

If you have noticed in our connect file, graphql() is also a HOC. It means that if we don’t want to use another HOC, we could write this component like this:

import { graphql } from 'react-apollo'
import { getAllCities } from './queries'
const CitiesContainer = ({ children, ...props }) => children(props)export default graphql(getAllCities)(CitiesContainer)

But Tte good news is that now we can freely access each city’s name and background patterns we needed for the Carousel component:

class App extends Component {
// ...
render() {
<CitiesContainer>
{({ data: { cities } }) => (
<Carousel cities={cities} />
)}
</CitiesContainer>
}
}

And surprise: that’s it, we’re done!

And the best thing about this is that you don’t even need to bother with Redux: Apollo is shipped with it right out the box! By default, Apollo Client creates its own internal Redux store to manage operations and their results. But obviously, you can also use your own Redux reducers, and it’s super simple. The only thing you need is to set up your ApolloProvider:

import React from 'react'
import { AppRegistry } from 'react-native'
import ApolloClient from 'apollo-client'
import { ApolloProvider } from 'react-apollo'
import { createStore, combineReducers } from 'redux'
import { userReducer } from '@store/reducers'const client = new ApolloClient()const store = createStore(
combineReducers({
users: userReducer,
apollo: client.reducer(),
}),
{}, // initial state
)
const App = () => (
<ApolloProvider store{store} client={client}>
<MyRootComponent />
</ApolloProvider>
)
AppRegistry.registerComponent('MyApp', () => App)

So that’s how we use GraphQL in a nutshell and I find it pretty straightforward! GraphQL is a very powerful query language and we had the opportunity to admire its full potential in a mobile app.

Basically when you build a mobile app, the Holy Grail is to reduce network requests as much as you can, without impacting the user experience. No relentless loading screens.

With GraphQL (and Apollo by extend), whenever you make an operation, the request and its result are stored. Whenever you’ll make the same operation, Apollo will apply it on its store, instead of your GraphQL server. Nevertheless, you can specifically ask it to fetch fresh data from the server.

// We use the built-in method to refetch data when needed
const onRefreshClicked = () => {
this.props.data.refetch()
}
// Here Apollo automatically refetches data every 10s
const feedWithData = graphql(feedEntries, {
options: { pollInterval: 10000 },
})(Feed)

Hence, you’ll have less loading screens than before and moreover, you can persist Apollo’s store into local storage (AsyncStorage in React Native) for offline purposes.

Well, things become even more interesting with graphql-anywhere. The description speaks for itself:

Run a GraphQL query anywhere, without a GraphQL server or a schema. Just pass in one resolver. Use it together with graphql-tag.

Yes, you’ve read it right. This package let you write GraphQL anywhere 
 even for your own “normal” Redux store! You can even filter/normalize the result of an operation, even if it’s not from a GraphQL server!

Once again, I hand it over to Sashko Stubailo with his great article about graphql-anywhere.

If you want to give it a closer look, Wino đŸ· is already available on iOS through the link down there (the Android version will be rolling out in a couple of weeks). Kudos to all the guys at Facebook and Meteor for giving us GraphQL and Apollo!

Thanks for taking the time to read my article, I hope you found it interesting. Very special thanks to ThĂ©o Kunetz & LĂ©o Le Bras for reviewing it, and hello JS & React Amsterdam teams for this opportunity! If you have any question or feedback: I’m 24/7 on Twitter đŸ»!

--

--

React Native lyricist ⚛, part-time sneakerhead 👟