Building a full on GraphQL app

Featuring React, Rails and GraphQL, Stack ❤

--

Stack ❤

For an upcoming project, I will be working with Rails, GraphQL And React. In order to gain more exposure to the stack, I decided to go back to an earlier project of mine and redo it with these technologies.

As a result, I will be documenting my entire process in the hopes that it can serve as a guide for others. This is the first in a series of posts that I will be creating over the coming months as I build out these applications. The first app will be a bit of a toy app, but will feature a full authentication system and a React front end.

Here is a link to the repository for the demo application. You will find most of the GraphQL code within the /app/graph directory.

Picking the Stack

One of the most fun parts of any project is the architecture phase. I am always excited to sit down and map out a high level overview of the application architecture.

Above is a diagram showing the stack that I chose for this project. For now, I will dive into the various components and talk about the choices I made when building this diagram.

Postgres, Rails and GraphQL

For the back end of this project, I chose to use GraphQL running on Rails. GraphQL helps to simplify data fetching and fits very nicely into a typical Rails application.

One main draw of using GraphQL is that you only need one API Endpoint. Even with somewhat small Rails applications, it is typical to have half a dozen endpoints, all with controllers to manage them. One endpoint in Rails means one controller.

This reminds me a bit of the setup on the Front End. With Redux, all of your data is located in one place and the only way to interact with that data is through a tightly controlled, yet declarative mechanism. Sounds great to me!

Let’s take a look at the Rails controller to see how GraphQL gets connected to Rails

Other than one helper method, that ensures that our parameters are a hash, all we need to do is connect an incoming request to GraphQL. GraphQL will execute our requests and respond with JSON data. We will see in a bit what it looks like to resolve queries and mutations with GraphQL. To expose this as an endpoint, all we have to do now is add the api resource to our routes file.

We also bind the GraphiQL editor to the /graphiql endpoint.

React, Redux and ES6

This choice was easy as I have been using these technologies as my Front End stack of choice for a long time. Although there are several options to integrate React directly into the Rails asset pipeline using the React_rails gem, I chose to build the two in isolation for a number of reasons.

I began this project as a fork of my React / Redux microframework and built it as normal, albeit within the client directory of the repo. I actually use Apollo, rather than Relay with this project. You can read about this setup in my other article.

Authentication System

Most of the demo GraphQL on Rails apps go into how the data layer works, but I have yet to see one with an example of Authentication, which is a key piece to any API.

The tricky part to this was to come up with an approach to have protected and non-protected queries. You see a lot of the data in this app needed to be public, while some of it needed to be private. With rails, typically the approach is to require auth for specific routes / resources. This approach doesn’t really work with GraphQL, because you only use one endpoint.

The approach that I took was to have two categories of types. Public types and protected types. This way, I can make the data I wish to be public available without authentication and make the private data types available when a user is authenticated.

For example, I have a User type and an AuthUser type

The user type is data that is available publicly and the auth user type is data that can only be accessed to an authenticated user.

On my root level query type, when the auth user is requested, I check that the auth token was passed as an argument.

Queries

What I like best about GraphQL, is that it maps perfectly to React. Just like how React lets you describe your UI as a Graph, GraphQL lets you describe your data requirements as a Graph.

For each container in my project, I have a query that takes care of loading the exact schema that I need to render that container and its child components.

On the back end, I have a event field, which contains a resolve method that knows exactly how to handle this query. When my view loads, bam I get the exact data that I need. Amazing!

On top of that, I can do a sort of rude pagination, by refetching data with a different “Current” cursor value. Check out below for the server-side code.

The magic in how this works, in my case, is abstracted by the Apollo Client and React Apollo libaries. An alternative would be to use the Relay library, but I have found Apollo to be a joy to use. You can read more about Apollo in the React Weekly Implementing GraphQL into a Redux App article.

Mutations

One of the most powerful features of GraphQL is mutations. Mutations are different from queries in that they represent mutative operations. If you map this to Rails CRUD, mutations are your CUD, i.e. Create, Update and Delete.

I’d like to show you some of the code from both the front end and the back end in order to demonstrate this concept.

On the front end, the real magic happens. Using ApolloClient, we can declaratively interact with GraphQL mutations. The idea here is to colocate all of our data needs within our container components. This idea is so incredibly powerful!

Let’s look at one final mutation together. This one is for the user profile page. As you can see, this is a giant container. The thing is, the UI is really not all that complex and it’s still totally reusable. You couple only the container to the implementation and then are free to create as much reusable UI as you’d like.

And then, behind the scenes, here are the user mutations on the back end.

This may have been the most complex component of our app. As you can see, however, by using GraphQL we can describe our data needs very declaratively. If you want to see what this looks like without GraphQL, take a look at this one action creator I created recently for an app that does not use GraphQL.

In this example, I had to hit two endpoints in order to complete signup for the app. The code took me like 2 hours to get perfect and I am without a doubt over-fetching data. I am here to tell you that there is a much better way to handle data fetching and it is GraphQL. If you or your company wants to greatly simplify your application and the development experience, I strongly urge you to consider GraphQL! Maybe we will even end up working together!

Wrapping it Up

This post is just an introduction into building a web application with GraphQL, Rails and React. I intend to document the rest of the process, but hopefully this article has whet your appetite. If you are like me, you may want to dig through the codebase for this project.

Also, the demo application can be found here. If you want to learn more about the required Front End setup, please checkout my article on the subject and stay tuned for more. Until next time!

--

--

Ryan C. Collins
Front End Engineering by Ryan C. Collins

Hey, I’m Ryan! I work in the Tech industry and post content about tech, leadership, and personal finance. https://www.ryanccollins.com