Basics of GraphQL in Ruby

Altimetrik Poland Tech Blog
3 min readFeb 21, 2023

--

Source: https://blog.effectussoftware.com/graphql-and-ruby-on-rails/

Introduction — What is GraphQL?

GraphQL is an open-source data query language and server-side runtime for APIs.

It is available for multiple languages. Query and mutation results are returned in JSON format.
In this article, I will show how to easily implement it and use it in an ROR API application.

Why GraphQL and not a REST API?

It’s more flexible, easier for developers to integrate, and a huge advantage is that it allows you to pull the exact data you want from multiple data sources in a single API call from a single endpoint.

We will use graphiql-app to test our API.

Let’s start developing GraphQL API in a RoR project.

First, add the `graphql` gem to your Gemfile.

#Gemfile
gem "graphql"

The next required step is to run the generator.

rails g graphql:install

It creates a new directory under app/graphql with a group of files, for now the important ones for us are queries that are used to read data available in app/graphql/types/query_type.rb and mutations that are used to write data and are defined as separate files under app/graphql/types/mutation_types.

Queries

Let’s assume that our application has a post model with title and body attributes.
In order to query for records, we need to define a post type with a list of all available attributes as below:

# app/graphql/types/post_type.rb
class Types::PostType < Types::BaseObject
description “Single Blog Post”
field :id, ID, null: false, description: “Identifier of Post”
field :title, String, null: false, description: “Title of Post”
field :body, String, null: false, description: “Body of Post”
field :created_at, GraphQL::Types::SO8601DateTime, null: false, description: “Datetime of Post creation”
field :updated_at, GraphQL::Types::SO8601DateTime, null: false, description: “Datetime of Post last update”
end

Next, we need to define a query method for a single post and a collection of posts:

# app/graphql/types/query_type.rb
field :post, Types::PostType, null: true, description: "Returns one Post instance" do
argument :id, ID, required: true
end

def post(id:)
Post.find_by(id: id)
end

field :posts, [Types::PostType], null: true, description: "Returns collection of Posts"

def posts
Post.all
end

Now we should be able to query the data on the GraphQL client with one of the following examples:

{                                                                           
post(id: "12d08a32-1cee-4681-84d0-4ef45a51203b") {
id
title
body
}
}

{
posts {
Id
Title
Body
}
}

As you may have noticed all attributes that are returned in the response are camelcased, if you want to keep the snakecase format you need to add camelize: false in the argument definition.

Mutations

As we already know mutations are used to create/update/delete data, so now it’s time to define all these 3 methods for our post model in GraphQL as separate mutation files.

For create Post

# app/graphql/mutations/create_post.rb
class Mutations::CreatePost < GraphQL::Schema::Mutation
field :create_post, Types::PostType, null: true, description: "Create an Post" do
argument :title, String, required: true
argument :body, String, required: true
end

def resolve(title:, body:)
Post.create(title: title, body: body)
end
end

For update Post

# app/graphql/mutations/update_post.rb
class Mutations::UpdatePost < GraphQL::Schema::Mutation
field :update_post, Types::PostType, null: true, description: "Create an Post" do
argument :id, ID, required: true
argument :title, String, required: true
argument :body, String, required: true
end

def resolve(id:, title:, body:)
post = Post.find(id)
post.update(title: title, body: body)
end
end

For delete Post

# app/graphql/mutations/delete_post.rb
class Mutations::DeletePost < GraphQL::Schema::Mutation
field :create_post, Types::PostType, null: true, description: "Create an Post" do
argument :id, ID, required: true
end

def resolve(title:, body:)
Post.find(id).destroy
end
end

In the last step, we need to update the list of available mutations.

# app/graphql/types/mutation_type.rb
field :create_post, Types::PostType, mutation: Mutations::CreatePost
field :update_post, Types::PostType, mutation: Mutations::UpdateaPost
field :update_post, Types::PostType, mutation: Mutations::DeletePost

Now our API is ready to process all these 3 operations, let’s try them out on the examples below:

mutation { 
createPost(title: "New Post", body: "Another fantastic Post") {
id
title
body
}
}

mutation {
updatePost(id: "12d08a32-1cee-4681-84d0-4ef45a51203b", title: "Updated Post", body: "Updated Body") {
id
title
body
}
}

mutation {
deletePost(id: "12d08a32-1cee-4681-84d0-4ef45a51203b") {
id
}
}

You can find more examples and code for a sample application at: https://github.com/mosinski/graphql-api.

Words by Miłosz Osiński, Product & Platform Engineer

Editing by Kinga Kuśnierz, Content Writer

--

--

Altimetrik Poland Tech Blog

This is a Technical Blog of Altimetrik Poland team. We focus on subjects like: Java, Data, Mobile, Blockchain and Recruitment. Waiting for your feedback!