Building a Real-time React App with GraphQL and Apollo

Nathan Zhang
carsales-dev
Published in
7 min readJul 18, 2019

@_@ It’s all because of Hack

At last October’s carsales Hackathon, I was part of a team that built a prototype environment donation website we named Green Fund. The carsales Hackathon is all about innovation and experimentation so we embraced the opportunity to experiment with some unfamiliar technologies including GraphQL and Apollo. The whole Hackathon experience was richly rewarding and in this article I will be focusing on the technology learnings that I took away from it, especially around how we setup and used GraphQL and Apollo to create a real time data web application.

The Big Picture

In this Hackathon, we chose a Javascript-based technology stack. Javascript was built for the web, traditionally for manipulating the HTML DOM but more recently it has also been used for the server-side and native applications. It has been around for a long time but I don’t see a direct replacement of Javascript as long as our web pages are still HTML and these days its use is more popular than ever!

Front-end development with Javascript has also evolved rapidly over the last 10 years. For me, the first major milestone was when Angular, Knockout and a few other frameworks started to focus on state rather than DOM manipulation. The second breakthrough was when the virtual DOM was introduced by Facebook bringing a new way of building the second generation of Javascript frameworks. The third happened when Redux/Flux was introduced, streamlining the workflow of front-end development and cleaning up state management in terms of naming, handlers, actions, etc.

At the same time Node arrived on the server-side, changing the landscape and making it possible to be a full-stack Javascript developer. The community has thrived and built a massive list of libraries, components, and tools on NPM and it’s just getting more and more exciting. Among more recent additions, GraphQL is definitely one of the shiniest stars and it is simply revolutionary. Since arriving in 2015 GraphQL has already matured and can be considered for integration into your production projects especially for use as a web proxy for certain cases which I will mention later.

What Are We Building?

This article will walk you through how to build an SPA with GraphQL, Node and React, based on code we used in our Green Fund carsales Hackathon project. The app we build allows users to make donations as well as realtime broadcasting of the total amount to any clients’ browser with the Green Fund home page open.

This article will also cover the fundamentals of three types of GraphQL interactions: Query, Mutation, and Subscription with Apollo.

1. Donation Page
2. Home Page

And the major steps we will walk through are:

  • Setting up a GraphQL server with Node.
  • Building an Apollo client with React.

Setting up GraphQL Server With Node

This article will not cover fundamentals of Node and will skip steps regarding setting up an express server, view engine, middleware as well as routers. We assume you have the above running and the server listening to port 3000.

3. Node Server

From app.js you can find SubscriptionServer and schema and it runs as a web socket server which will be explained later.

Next, we will setup GraphiQL which is an in-browser IDE to test and edit GraphQL queries or mutations. GraphiQL requires graphiqlExpress (replaced by ApolloServer in later releases) from graphql-server-express.

4. Node Router

From routers/index.js we’ve already had GraphQL server running on localhost:3000/graphql and GraphiQL interface running on localhost:3000/graphiql which should look like:

5. GraphiQL Interface

We now have the skeleton ready but we don’t have the GraphQL schema. For those who don’t know what schema is, by definition it is a description of capabilities of the API which could contain three valid types: Query, Mutation, and Subscription. Schema needs to map with a resolver which is the actual implementation of API which is specified by a schema definition. If you are lost right here don’t worry, it will become clearer with some hands-on practice.

From here we’ve created a Query type for the total amount of all donations, a Mutation type which expects an input as the amount of the donation each user puts in. And we’ve also defined a Subscription which expects to receive a donation total value as a response in CurrentDonation type.

6. Schema

Now let’s implement them in resolvers: Query, Mutation, and Subscription.

7. Resolvers

From code, we have hidden the complexity of logic in the donationServices. But:

  • For GraphQL Query, the app will fetch the current donation amount and return it.
  • For Mutation, the app will add a new donation to the current total and publish the new total amount for subscribers.

Thanks to makeExecutableSchema which can wrap schema and resolver in one. In our program, we exported the result of makeExecutableSchema as a schema to graphQLExpress (router/index.js) and SubscriptionServe (app.js).

8. makeExecutableSchema

We have now finished our backend and can test it.

9. Test Query

Cool, Query is working and let us try to donate some money via the Mutation method.

10. Test Mutation

Fantastic, it’s important to make sure the backend is correct before we move onto UI. This is really helpful for debugging and addressing issues and I love reducing risk in coding.

Set Up Apollo Client With React

Before we dive into React and Apollo, let’s review what we have built up to now:

  • We have a GraphQL connection ready which is on localhost:3000/graphql
  • Also, we’ve got a Web socket link running from localhost:3000/subscriptions

So the next thing to start with is initializing connections from the client app.

11. Set Up Connections (client/app.js)

We see ApolloClient takes two connections here: localhost:3000/graphql for Query and Mutation and localhost:3000/subscription where the web socket client listens to (Subscription).

Then ApolloProvider which is similar to a Redux Provider wraps a React app as the highest order function and injects the client in as a prop. The beauty is you can easily call the backend with the provided methods in a React component.

12. Call Mutation Method in React Component
14. Subscription From React

From donation.js and home.js we see two ways of accessing GraphQL in React. You can either call built-in functions from global props, for example, Query and Mutation; Or you can use a react-apollo component which is the recommended approach.

The benefit of using Apollo as a state management tool is not just about GraphQL, it also provides normalized data from the backend and you can utilize some really helpful features like the “loading” flag.

So, what did we just build?

We’ve created a Node server and wrapped express with GraphQL Subscription server. Apollo from the client-side tunnels through to both GraphQL as well as the Subscription server and passes GraphQL accessibilities into React components, from where we could query, mutate and subscribe to the data. Similar to how Redux manages global stores, Apollo goes even further and synchronizes UI action triggered state changes directly to the backend. This is an additional benefit Apollo and GraphQL bring from their innate flexibility and declarative data fetching style.

Back to our hackathon project! In the picture of the home page below, the total amount raised dynamically updated through subscription to the realtime backend data. This is very impressive especially when you are demonstrating your ideas to visitors during such an interactive event like a hackathon! I appreciate how GraphQL and Apollo make building real-time applications such a simple task leaving developers more time to focus on building new features and business logic.

When should you use GraphQL?

GraphQL has its limitations. In comparison to RESTful APIs, it makes some tasks more complex, for example, in some projects you probably don’t need types or what you need is just a simple request and response without the need to consider scalability. Also, there are fewer resources in the community, for example, on error handling or caching. So you will need to think twice before jumping in and using GrahpQL. But at least, GraphQL is ideal for listing and searching scenarios.

To sum up, if you have a broad range of selections from backend data which don’t structurally change all the time and if you love having the freedom to pick and choose data for the UI, try GraphQL. However, if you have complex application flows, such as a purchase journey or your data is dependent heavily on product flows, or your databases or micro-services are cross-referencing and super complex, hold on and estimate the cost before you go.

Github: https://github.com/lovedisaster/GraphQL_Apollo

--

--