GraphQL and Relay on Rails — First relay powered react component

Gaurav Tiwari
4 min readJan 9, 2016

--

In our previous post, we looked into GraphQL schema and types. We also looked into how to query the Schema to fetch necessary data we need from rails console.

Now, in this post we are going to put everything we learned to create a full featured GraphQL server and a react component to fetch and render posts on our home page. Lets begin :)

Note: You can clone this branch to follow along, it has completed code for this post. You can also refer to first or second post if you are new to this series.

cd /to-your-work-directory
git clone -b blog/part2 git@github.com:gauravtiwari/relay-rails-blog.git blog
cd blog/

Resources

Schema generation

In our previous post, we manually ran commands in rails console to create and execute our schema, but that is not ideal in any real world application.

So, lets create a middleware to automate schema creation during query execution. A middleware will execute on each request and update schema.json file on client side in case it’s changed. Now, in our app root directory inside lib/ folder, lets create a simple Struct:

Rails middleware to generate schema on run time

Now, lets create RelaySchema module, we are using checksum to cache the digest of schema content using rails cache to make sure we don’t re-run the introspection query on each request. An introspection query, as word suggests queries a GraphQL server to get details about types, fields and connections defined on the server and generates a Schema.

A simple module to generate and dump schema on client side

Now as we have our server in place. Lets set up our views.

Setting up the client

Lets setup our first react component inside app/javascripts/components.we are just following standard react-rails gem workflow.

#app/javascripts/components/posts.es6.js

Posts component that renders a collection of posts

Everything above is fairly standard if you have used react components before, except the query fragment part. In nutshell, with Relay every react component defines a relay container that lists the data need for that particular component in a query format. This works similar to how a React component’s render method does not directly modify native views, Relay containers do not directly fetch data. Instead, containers declare a specification of the data needed to render. For example: In real world you would create a list of items before going on shopping for a trip to ensure you get exactly what you need for that trip.

Relay guarantees that this data is available before rendering. In this case, fetching posts connection which returns posts collection from ViewerType defined on our server.

We are also using getFragment method inside root query fragment to fetch PostPreview query fragment.The getFragment method on a component allows us to fetch any other component query fragment part, for reusability.

PostPreview component just renders a single post preview

In order to render our newly created posts component one last thing we need is a Relay route. Routes are responsible for defining the entry points into a Relay application. But in order to understand why routes are necessary, we must first understand the difference between GraphQL queries and fragments.

# Post field or connection on RootQuery Type
query Query {
Post(id: "1") {
id,
title
},
}
# Any fragment on any type
fragment User on Comment {
user(id: '2') {
name,
},
}

In GraphQL, queries declare fields or connections that exist on the root query type. On the other hand, GraphQL fragments declare fields that exist on any arbitrary type.

Below is our posts route that defines root field as it’s entry point for the query:

Posts route that defines entry point — root

To revise, see below the query type that contains root entry point that points to our ViewerType, which is responsible for returning posts connection. If you see the second post, root query type basically provides interface to read any available entry points on that type.

Note: A connection works like a field that that uses a resolve block to return any arbitrary data on any type.

Root Query Type containing root entry point

Note: We are using ViewerType because, relay doesn’t support querying collections for root type yet. See here: Issue#112

Below is our simple Struct class to create temporary data structure (root)

And here is our ViewerType:

ViewerType defines a posts connection to return posts collection

Now, in order to render these components with relay we will hack the components.js provided by react-rails gem.

Note: We will change this in our next post to render components dynamically, but for simplicity lets render it like so:

So, what’s going on in this file? Simple, we are requiring dependencies for this script using browserify and also our components. On DOM ready we are passing them to Relay root container which finally renders the component to DOM on id #posts. That’s it :) We are now rendering our first component using Relay using GraphQL server on top of our standard Rails stack.

In our next post, we will setup post show page and render it’s comments. We also look into how to implement infinite scroll using Relay. We will also look into relay mutations to edit, update and destroy model states on server.

Stay tuned!

--

--