ToEatApp Rails-React-Relay-GraphQL Tutorial - Application Setup

In this series of posts we will explore how to render a React based front end that uses Relay and GraphQl to communicate with a Ruby on Rails server. We will be writing ES6 Javascript that gets transpiled by Webpack into 'regular' javascript. The applicaton can be viewed at toeatapp.startuplandia.io and the codebase can be viewed at github.com/jcdavison/to_eat_app.

This tutorial is aimed at web developers who are comfortable with relational data storage, http/rest ideology and rails and who want to quickly learn some powerful client-side data caching and state management techniques. If you are new to coding and reading this tutorial and lots of things don't make sense, that is ok, just work as far as you can get, submit your commits to antipattern.io and I will give you relevant guidance.

Words to the Wise

The application code runs at toeatapp.startuplandia.io. This tutorial utilizes Rails 4.2, NPM 3.8, Node 4.2.

Utilize the source code...

to_eat_app
git clone git@github.com:jcdavison/to_eat_app.git
#  woohoo !!

Application Setup and Tooling

This app will run a standard rails process and a seperate node process that will utilize webpack to transpile es6 based jsx files into one big javascript file.

  git clone git@github.com:jcdavison/to_eat_app.git
  cd to_eat_app
  bundle install
  npm install
  # in one terminal window 
  bin/rake db:create
  bin/rake db:migrate
  bin/rails server
  # in a different terminal window
  webpack -w
  # then go to your browser and visit
  # http://localhost:3000/

How are WebPack/Babel and Asset Pipeline working together?

Our Rails application server doesn't know anything about any of the underlying node or javascript transpiling technologies.

Notice the contents of ./app/assets/javascripts/application.js.

  //= require jquery
  //= require packed/transpiled_output

The only file that Rails is requiring that has js application code in it is packed/transpiled_output. This file is created by the WebPack process, which is watching ./app/assets/javascripts/src/app.jsx, anytime a change occurs WebPack converts app.jsx and all includes to one large file packed/transpiled_output that has transpiled the ES6 js to regular internet ready js. Also notice that all the js application logic lives inside /javascripts/src and that app.jsx uses ES6 module imports to require dependencies.

Files to notice.

./package.json

All the javascript dependencies that we need. Notice that we are requiring things like react, relay and graphql here. Our rails server won't be using anything other than the most vanilla useage of the asset pipeline, ie 'render this javascript file that webpack just built'.

  {
    "name": "ToEatApp",
    "description": "Got Food Trucks?",
    "version": "1.0.0",
    "repository": "ToEatApp",
    "license": "MIT",
    "dependencies": {
      "babel": "6.5.0",
      "babel-core": "6.3.15",
      "babel-loader": "6.2.4",
      "babel-plugin-transform-class-properties": "6.6.0",
      "babel-preset-es2015": "^6.6.0",
      "babel-preset-react": "^6.5.0",
      "babel-relay-plugin-loader": "^0.6.1",
      "graphql": "^0.4.18",
      "node-jsx": "0.13.3",
      "react": "^0.14.7",
      "react-dom": "^0.14.7",
      "react-relay": "^0.6.0",
      "react-router": ">=2.0.0-rc2",
      "react-router-relay": "^0.9.0",
      "webpack": ">=1.12.14"
    },
    "metadata": {
      "graphql": {
        "schema": "./schema.json"
      }
    }
  }

./schema.json

schema.json tells graphql about the shape, location and required params needed to interact in a declarative fashion with the rails application server. Important note, lib/tasks/graphql.rake contains a rake task that programmatically builds schema.json. The below is an excerpt and the actual schema.json over 2k lines and generally not intended for human consumption.

  {
    "data": {
      "__schema": {
        "queryType": {
          "name": "RootQuery"
        },
        "mutationType": {
          "name": "RootMutation"
        },
        // begin redaction
      },
    },
  }

./webpack.config.js

Webpack is a fancy node library that enables all kinds of magic like 'transpiling'. In this case, we will be using webpack and babel to transpile a bunch of .jsx files that are written with ES6 into a more browser friendly form of javascript.

  module.exports = {
    entry: ["./app/assets/javascripts/src/app.jsx"],
    output: {
      path: "./app/assets/javascripts/packed",
      filename: "transpiled_output.js"
    },
    module: {
      loaders: [
        { test: /\.jsx$/, exclude: /node_modules/, loader: "babel-loader" }
      ]
    },
    resolve: {
      extensions: ['', '.js', '.jsx']
    }
  };

./.babelrc

Babel is the really fancy node library that converts ES6 compliant javascript into browser runnable 'normal' javascript.

  {
    "sourceMaps": "both",
    "plugins": ["babel-relay-plugin-loader", "transform-class-properties"],
    "presets": ["react", "es2015"]
  }

Next Steps

Read the next post in this series, ToEatApp React-Relay-GraphQL Tutorial - Queries.

The Fine Print

Particular Disclaimer: This tutorial isn't intended to be 100% every single step you need to take to make things work, this tutorial will help you create a mental model for how graphql and relay keep track of data, above all, the source code has all the details required to make the application work its magic.
Other Particular Disclaimer: I don't intend for this tutorial to be the 'right' or 'perfect' or 'best' way to do something. This tutorial is 'a' way to get a desired result. If you desire a different result or a different way of getting the same result, feel free to do that.
General Disclaimer: Things change, operating environments aren't all the same, people have different ideas about things, people are wrong, people are right, things don't always add up and when in doubt, look at the source code.
I continually seek new software engineering contracts and product collaboration opportunities so please, send email to jd@startuplandia.io.