Building APIs with GraphQL and Ruby on Rails
by Sergey Kuznetsov & Moses Kim
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
- Create a new project:
gem install bundler
gem install railsrails new example-graphql -v '5.2.0'cd example-graphql
- 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:
- Click the Docs to see the documentation generated for our queries.
Queries
- 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
- 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:
- 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: