Our Experience With Node.js + React + GraphQL

JetRuby Agency
JetRuby Agency
Published in
8 min readOct 19, 2017

We’ve been using Node.JS, React, Redux, GraphQL, and Webpack for a while now. With this combination, we’ve developed many cool applications that comply with all modern standards of both industry and market. Each of these technologies is undoubtedly important when implementing functionalities, but the key element in this combination is Node.JS. In this article, we’re going to show you how to use this technology with GraphQL and React to build web applications.

Environment setup

Choosing the right environment depends on the type of application you’re going to work on. In this example, we have a distributed application, allowing company employees to plan their time more efficiently. The client side is based on React.JS. It’s already finished and good to go. What we need to now is to set up and configure Node.JS on the server. However, there are several things to settle on first off:

  • architecture style;
  • framework;
  • database.

To implement the architecture, we decided to use GraphQL, which is a query language for APIs. It’s proven to be a useful and versatile solution in our recent Ruby on Rails projects. Next, we need to choose which framework to use. Luckily, Npm offers a wide range of options:

  • Hapi.js
  • Socket.io
  • Express
  • Mojito
  • Meteor
  • Derby
  • Mean.js
  • Sails.js, and others.

As a framework, we chose Express. It comes with everything you need for efficient development: extensive documentation, guidelines for both newbies and pros, and most importantly, a wide range of tools that enable you to solve various tasks. Express can also boast a few million downloads a week in npm. Plus, it’s quite popular on Github.

The final step is to settle on the database. We picked PostgreSQL, since we’ve been using it in many of our projects. In addition to PostgreSQL, we’re going to use Knex.JS to build SQL queries and Bookshelf.JS for object-relational display of data.

Now we need to configure the dependencies of the application.

Configuring dependencies

The file for configuring dependencies is called package.json. In our case, it includes the following basic configurations:

Next, we need to install the dependencies using the command below:

After that, we can configure and launch the server.

Babel

Nowadays, ECMAScript 6 (ES6) is considered to be a standard in the web development industry. However, it isn’t natively supported in Node.JS yet. Because of this, we need to transpile ES6 into ES5 using Babel. The configuration of plugins and presets for Babel is carried out in the file with the “.babelrc” extension. The one that we’ll be using looks like this:

As for the presets, es2015 comprises a whole bunch of additional plugins. It’s also responsible for compiling ES6 into ES5. The “stage-0” preset includes stage-1, stage-2, stage-3, and some other plugins, that allow for supporting features of ES6. If you want to find more detailed information, you can follow this link.

Environment variables

Now we need to define the environment variables, in which the application will operate. Doing this will allow us to store critical data in one place and replace it all at once, if needed. For this purpose, we can use the dotenv module.

The configuration of variables is carried out in the file with the “.env” extension. All the variables will be available as properties of the object “process.env” within the whole project.

Configuring the server

The next step is to configure the server. For this purpose, we’ve put the “app.js” file in the main directory. The file will be the access point to the app.

In order to check the result, we need to add a specific command in the “package.json” file. The command will initialize the server launch.

In the code above, we used the “nodemon” module, which perfectly fits the requirements. The module launches the server and monitors every change in the files. Additionally, it can reboot the server if necessary.

Now we need to execute “npm run dev” in the terminal and then open the page http://localhost:4000. Voila!

Database

After the main preparations have been finished, we can proceed to setting up the connection with the database. The first thing to do at this point is to create the “config” folder. Therein, we need to create two more folders (“migrations” and “seeds”) along with two files: “knexfile.js” and “db.js”.

The “migrations” folder will contain the list of migrations for the database, wherein migration files are created as a result of executing the command “knex — knexfile=config/knexfile.js migrate:make migration_name” in the terminal. The names of these files contain the time of creation (in the timestamp format), which is added automatically. It’s also necessary to figure out in what sequence the migrations were created.

Here’s an example. There are two migrations. Their purpose is to create a table with the list of users and their roles in the database.

The “seeds” folder contains the list of seeds to fill the database. In the example, the seeds are used to fill the table with users.

If you’d like to find more information about migrations, seeds, and other features, you can go to this page.

Knexfile.js contains the data required for setting up the connection with the database.

The purpose of the “db.js” is to export the instance of bookshelf, which we’ll need later when working with the database.

As a result, the architecture of the app will look the following:

+ — config
| + — migrations
| + — 20170116154958_roles.js
| + — 20170116154959_users.js
| + — seeds
| + — users.js
| + — db.js
| + — knexfile.js
+ — .babelrc
+ — .env
+ — app.js
+ — package.json

Next, we need to hook up migrations and seeds. To do this, we need to add two scripts in the “package.json” file.

Now we execute them in the terminal:

npm run db-migrate && npm run db-seed

To check out the result, we can use SQL Shell (psql) or any other graphic interface.

Here is the list of tables:

… and the list of users:

Creating models

The database is configured and the migrations are done. Now we can proceed to creating models for the tables. For this purpose, we’ll need Bookshelf.js. In the root of the app, one should create a folder named “models” and two files: “role.js” and “user.js”. This folder is the place where the models will be stored.

GraphQL

After that, we can start implementing GraphQL schemes. But first, we need to create a folder in the root of the app and then add the following schemas.

+ — config
+ — graphql
| + — Role
| + — index.js
| + — mutations.js
| + — queries.js
| + — resolvers.js
| + — schema.js
| + — User
| + — index.js
| + — mutations.js
| + — queries.js
| + — resolvers.js
| + — schema.js
| + — index.js
+ — models
+ — .babelrc
+ — .env
+ — app.js
+ — package.json

Wherein “index.js” combines and exports all schemas:

Now let’s take a closer look at the files that are in each schema.

“index.js” is an access point to the schema that combines all necessary data.

Adjusting the schemas according to the test data:

Now we need to add the “loadModules” function to assemble all the schemas into one. The function is in a separate file in the “utils” folder.

— config
+ — graphql
+ — models
+ — utils
| + — loadModules.js
+ — .babelrc
+ — .env
+ — app.js
+ — package.json

In the config file of the server, we need to add the schemas in the list for import and then add express-graphql in middlewares.

Now we can open the page http://localhost:4000/graphql, which should display GraphiQL.

GraphiQL is a great tool that comes extremely handy when developing apps. It provides developers with documentations that is automatically generated based on the schemas. Moreover, it allows you to send queries or mutations and view the results in a very convenient manner.

Integration with React

For integration on the server side of the app with its client side, we’ll be using react-apollo. It’s a module that allows you to receive data from the GraphQL server and use it to build simple and reactive interfaces. After the installation of react-apollo, there are some adjustments to be made. For example, we need to add the following import in the file that’s responsible for rendering of the app on the client side:

import { ApolloClient, ApolloProvider, createNetworkInterface } from ‘react-apollo’

Then we need to create a new instance of the object “ApolloClient”, defining the “uri” address that will be receiving queries.

Modifying the expression of the “render” method:

In this example, we’ve shown only the smaller part of the functionality that can be provided by react-apollo. It’s a very useful tool for working with the GraphQL server in the React environment.

Production

The final step in development is production. But first, the initial code has to go through several stages of processing, compilation, and minimization. The server environment has also to be prepared for production.

We need to add a few extra commands into package.json.

Finally, we need to execute the command “npm run build”. After that, the compiled code will appear in the “build” folder. That’s all!

Conclusion

Summing up, we can say that Node.JS is a powerful technology for web development. The range of areas in which you can use Node.js is really impressive: from server side to native applications. Moreover, combined with React and GraphQL, Node.JS will allow you to bring the quality of your project up to a whole different level.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Published in JetRuby Agency

We believe sharing knowledge pushes the industry forward and creates communication bridges. Our technical expertise includes Agritech, Healthcare, and many more.

Written by JetRuby Agency

JetRuby is a Digital Agency that doesn’t stop moving. We expound on subjects as varied as developing a mobile app and through to disruptive technologies.