Back-end Engineering Articles

I write and talk about backend stuff like Ruby, Ruby On Rails, Databases, Testing, Architecture / Infrastructure / System Design, Cloud, DevOps, Backgroud Jobs, and more...

Twitter:
@daniel_moralesp

2020-03-27

Rails & GraphQL - Part II

1- Rails Side


# app/graphql/types/item_type.rb
module Types
  class ItemType < Types::BaseObject
    field :id, ID, null: false
    field :title, String, null: true
    field :description, String, null: true
    field :image_url, String, null: true
    field :user, Types::UserType, null: false
  end
end

# app/graphql/types/query_type.rb
module Types
  class QueryType < Types::BaseObject
	  ...
    field :fetch_items, resolver: Queries::FetchItems
  end
en

Way to tun query

#Way to run in GraphiQL
query {
  fetchItems {
    id
    title
    user {
      id
      email
    }
  }
}

2- React Side


## Add to Gemfile
gem 'webpacker'

## console
$ bundle install
$ bundle exec rake webpacker:install
$ bundle exec rake webpacker:install:react

**## EVERYTHING NOW NEEDS TO BE DONE VIA YARN NOT NPM**

## add react and others
yarn add react

Adding Apollo Client

$ yarn add apollo-client apollo-cache-inmemory apollo-link-http apollo-link-error apollo-link graphql graphql-tag react-apollo

In last JS

# /app/javascript/components/Library/index.js

import React from 'react';
import { Query } from 'react-apollo';
import gql from 'graphql-tag';

const LibraryQuery = gql`
    {
        fetchItems {
            id
            title
            user {
                id
                email
            }
        }
    }
    
`;

export default () => (
    <Query query={LibraryQuery}>
        {({ data, loading }) => (
        <div>
            {loading
            ? 'loading...'
            : data.fetchItems.map(({ title, id, user }) => (
                <div key={id}>
                    <b>{title}</b> {user ? `added by ${user.email}` : null}
                </div>
                ))}
        </div>
        )}
    </Query>
);

Deploying Webpacker with Capistrano

In reality we don't need to do anything fancy, because caspitrano deals with the precompilation. The only thing I needed to do was to upgrade my Node version to the last one, bacsue webpacker 5 needed a newest version. The second thing was to give permissions to node/.config inside the Ubuntu server, and everyhing works as expected

# inside the Ubuntu production machine

$ node --version
v8.17.0
$ sudo npm cache clean -f
$ sudo npm install -g n
$ sudo n stable
$ exit

Reenter
$ node --version
v16.13.0

Giving permissions

# inside the Ubuntu production machine

$ sudo chown -R $USER:$GROUP ~/.npm
$ sudo chown -R $USER:$GROUP ~/.config

Problem when deploying to production

With yarn, please pin your babel deps manually in your package.json, then use yarn install again:

"resolutions": { "@babel/core": "7.13.15", "@babel/preset-env": "7.13.15" }

Something like this

{
  "name": "danielmorales",
  "private": true,
  "dependencies": {
    "@babel/preset-react": "^7.16.0",
    "@rails/webpacker": "^5.4.3",
    "apollo-cache-inmemory": "^1.6.6",
    "apollo-client": "^2.6.10",
    "apollo-link": "^1.2.14",
    "apollo-link-error": "^1.1.13",
    "apollo-link-http": "^1.5.17",
    "babel-plugin-transform-react-remove-prop-types": "^0.4.24",
    "graphql": "^16.0.1",
    "graphql-tag": "^2.12.6",
    "prop-types": "^15.7.2",
    "react": "^17.0.2",
    "react-apollo": "^3.1.5",
    "react-dom": "^17.0.2"
  },
  "devDependencies": {
    "webpack-dev-server": "^4.4.0"
  },
  "resolutions": {
    "@babel/core": "7.13.15",
    "@babel/preset-env": "7.13.15"
  }
}

Original link: https://evilmartians.com/chronicles/graphql-on-rails-1-from-zero-to-the-first-query