Building APIs with GraphQL and Ruby on Rails

Moses Kim
Shakuro Writes
Published in
5 min readJan 11, 2019

by Sergey Kuznetsov & Moses Kim

Mutation by Tarot House

GraphQL is a query language for APIs and a server environment for fulfilling those queries. It uses the type system defined according to your specific requirements. GraphQL was developed by Facebook in 2012, it is considered by many to be the future of APIs.

I am interested in building APIs using GraphQL with Ruby on Rails, and that’s what I’m going to do. GraphQL is not tied to any programming language or technology, that’s why it can be used with different platforms for the development of the APIs.

GraphQL is not just for building new APIs but also for improving and expanding the existing ones.

GraphQL defines the types and their fields and provides the tools to work the fields of each type (mutations, resolvers, and so on). GraphQL supports reading, mutating, and real-time updates.

Here’s the example of a user list query:

{
allUsers {
name,
email
}
}

The result must be in JSON:

{
"data": {
"allUsers": [
{
"name": "Mickey",
"email": "mickey@api.com"
},
]
}
}

To be honest, GraphQL is a huge topic and I’m making no claims I can cover it all here. However, to illustrate the practical use and some of the basic features of GraphQL, I’ll go with an example below. In it, I will show the implementation of an API with the following features:

  • Getting the list of articles
  • Getting a specific article
  • Creating an article
  • Deleting an article

⚠️ Note: these examples are purely demonstrational and should not be used in live projects.

Building APIs with GraphQL and Ruby on Rails

  1. Create a new project:
gem install bundler
gem install rails
rails new example-graphql -v '5.2.0'cd example-graphql
  1. Add GraphQL into the Gemfile:
echo "gem 'graphiql-rails', group: :development" >> Gemfile
echo "gem 'graphql'" >> Gemfile

3. Launch:

bundle install
rails generate graphql:install
rails server

4. Go to http://localhost:3000/graphiql to see the Web IDE:

  1. Click the Docs to see the documentation generated for our queries.

Queries

  1. Create an article model:
rails g model article title:string description:text

2. Add validation to the app/models/article.rb model:

class Article < ApplicationRecord
validates :title, :description, presence: true
end

3. Apply changes:

rake db:migrate

4. Populate the database with data:

rails s
Article.create!(title: 'Title1', description: 'Description1')
Article.create!(title: 'Title2', description: 'Description2')
exit

5. Create the new Article type:

app/graphql/types/article_type.rbclass Types::ArticleType < Types::BaseObject
graphql_name 'Article'
field :id, ID, null: false
field :title, String, null: false
field :description, String, null: false
end

6. Update QueryType:

app/graphql/types/query_type.rbmodule Types
class QueryType < Types::BaseObject
field :allArticles, [ArticleType], null: false
field :article, ArticleType, null: true
argument :id, ID, required: true
end
def all_articles
Article.all
end
  1. Get the list of articles:

Or get the information about a specific article:

Mutations

GraphQL allows you to easily modify the data by means of mutation.

Mutations are special fields which do not include the task of getting the data or making computations. They are used to change the following app states by:

  • Creating, updating, and deleting database records.
  • Creating associations.
  • Cleaning the cache.
  • Working with files.

These actions are called “side effects”.

To make a record in the database, you need a new mutation. Create it with a built-in generator and the following command:

rails g graphql:mutation create_article

This will create a new file:

app/graphql/mutations/created_article.rb

Change it:

module Mutations
class CreateArticle < GraphQL::Schema::RelayClassicMutation
# TODO: define return fields
# field :post, Types::PostType, null: false
field :article, Types::ArticleType, null: false # TODO: define arguments
# argument :name, String, required: true
argument :title, String, required: true
argument :description, String, required: true
# TODO: define resolve method
# def resolve(name:)
# { post: ... }
# end
def resolve(title:, description:)
article = Article.create!(title: title, description: description)
{
article: article
}
end
end
end

Define the mutation field:

app/graphql/types/mutation_type.rbmodule Types
class MutationType < Types::BaseObject
field :createArticle, mutation: Mutations::CreateArticle
end
end

Now you can create an article:

Similarly, you can delete the objects through mutations. Here’s how:

  1. Create a new mutation:
rails g graphql:mutation remove_article

This will update the existing mutation type:

app/graphql/types/mutation_type.rbmodule Types
class MutationType < Types::BaseObject
field :removeArticle, mutation: Mutations::RemoveArticle
# TODO: remove me
# field :test_field, String, null: false,
# description: "An example field added by the generator"
# def test_field
# "Hello World"
# end
field :createArticle, mutation: Mutations::CreateArticle
end
end

Edit the new file:

app/graphql/mutations/remove_article.rbmodule Mutations
class RemoveArticle < GraphQL::Schema::RelayClassicMutation
# TODO: define return fields
# field :post, Types::PostType, null: false
field :article, Types::ArticleType, null: false # TODO: define arguments
# argument :name, String, required: true
argument :id, ID, required: true
# TODO: define resolve method
# def resolve(name:)
# { post: ... }
# end
def resolve(id:)
article = Article.find(id)
article.destroy!
{ article: article }
end
end
end

The query will look like this:

This is how you build APIs with GraphQL and Ruby on Rails. There’s a lot more to talk about and if you feel like exploring further, here are some sources:

graphql.org

wikipedia.org/wiki/GraphQL

graphql-ruby.org

--

--

Moses Kim
Shakuro Writes

Creative producer. Former UX writer and researcher.