In the ever-evolving world of Ruby on Rails web development, the adoption of GraphQL has taken a leading role due to its flexibility and efficiency in creating APIs. In this article, I'll walk you through a step-by-step approach to integrating GraphQL into a Rails project focused on articles and comments. From initial setup to creating specific queries and resolvers, we'll explore together how to leverage the power of GraphQL in our application.
Creating the Rails Application and Configuring GraphQL
Before we dive into the fascinating world of GraphQL, make sure you have your development environment up and running.
Let's start by creating a new Rails application and configuring GraphQL. Let's run the following commands to start our project:
rails new articles-graphql-app
cd articles-graphql-app
bundle add graphql
This set of commands sets the basics for integrating GraphQL into our application:
rails new articles-graphql-app
: This command creates a new Rails application named "articles-graphql-app".cd articles-graphql-app
: This command changes the current working directory to the newly created "articles-graphql-app" directory. Move inside the project folder to perform specific actions in that context.bundle add graphql
: Adds the graphql gem to your project's Gemfile. The graphql gem provides the necessary tools to implement GraphQL in your Rails application.
Now let's run the rails generate graphql:install
command in the root of the project which sets up the basic infrastructure for GraphQL in your Rails application. It organizes your GraphQL code into specific folders, making it easier to manage and scale as you add more functionality to your GraphQL API, generating the following points:
Route for GraphQL that adds a new route in your
config/routes.rb
file that maps the/graphql
URL to the generated GraphQL driver. This route acts as the entry point for GraphQL requests.Controller named
GraphqlController
in theapp/controllers
directory. This controller is responsible for handling GraphQL requests and orchestrating the execution of queries and mutations.-
Folder
app/graphql
in which all related GraphQL files will be organized. Withinapp/graphql
, specific subfolders are created to organize different components:- mutations: Here you can define and manage GraphQL mutations that modify data in your application.
- resolvers: In this folder, you can implement resolvers that handle GraphQL queries and mutations. The resolvers are responsible for obtaining and returning the requested data.
- types: Contains the definitions of GraphQL types that represent your models and data structures in the application.
Generating models and data for Post and Comment models
To be able to interact with the models you must generate the models and data. In this case you are going to use a gem called faker
. We will run the following command to add the gem to the Gemfile
bundle add faker
Faker is a useful tool to generate dummy data in a realistic way, which will ease the creation of test data for your article and comment models.
Now you are going to generate the model for Post that includes two fields: title of type string and content of type text. This model will represent the articles in the application.
rails generate model Post title:string content:text
Now you are going to generate the Comment model that includes a text content field and establishes a belongs_to association with the Post model. This will allow each comment to be linked to a specific article in our application.
rails generate model Comment post:belongs_to content:text
You must set the reverse relationship in the Post model. Open the app/models/post.rb
file and add the line has_many :comments
to indicate that an article can have many comments. Your app/models/post.rb
file might look something like this:
class Post < ApplicationRecord
has_many :comments
end
Now let's edit the db/seeds.rb
file so that you can create 20 articles, each with a generated fake title and three related comments, each with fictitious content. The script should look like this:
require 'faker'
20.times do
post = Post.create(
title: Faker::Lorem.sentence
)
3.times do
Comment.create(
post: post,
content: Faker::Lorem.paragraph
)
end
end
puts 'Seed data created successfully!'
To run the seed script, simply place this code in the db/seeds.rb
file. Then, you can run the following commands to ensure that all the data has been created as expected:
rails db:migrate
rails db:seed
Ready to move on to the next steps? 🚀
Setting Resolvers for Posts
Basically a resolver is a function that handles the logic to obtain the data requested by a GraphQL query or mutation. In other words, a resolver answers the question "how to get this specific data?".
Now let's set up resolvers and GraphQL types to handle specific queries. Add this line to app/graphql/types/query_type.rb
:
field :posts, resolver: Resolvers::PostsResolver
To display the file app/graphql/types/query_type.rb
like this:
module Types
class QueryType < Types::BaseObject
description "The query root of this schema"
field :posts, resolver: Resolvers::PostsResolver
end
end
By adding the :posts
field to your GraphQL query type (QueryType
) and associating it with the Resolvers::PostsResolver
, you are configuring GraphQL to handle posts queries. This resolver will take care of getting and returning the necessary information when a posts query is performed.
Now we're going to create the resolver to get all the posts in app/graphql/resolvers/posts_resolver.rb
:
module Resolvers
class PostsResolver < BaseResolver
type [Types::PostType], null: false
def resolve
::Post.all
end
end
end
Setting Types for Posts and Comments
To give some context, a Type refers to the data structure that you can query or modify using the GraphQL query language. In GraphQL, types represent the entities in our system and define the fields that can be queried or mutated on those entities.
Now let's define the post type in app/graphql/types/post_type.rb
:
class Types::PostType < Types::BaseObject
field :id, ID, null: false
field :title, String, null: false
field :content, String, null: false
field :comments, [Types::CommentType],
description: "This post's comments, or null if this post has comments disabled."
end
By creating the PostType type in app/graphql/types/post_type.rb
, you are defining how it will be structured and what fields will be available when information about a post is requested through GraphQL. This PostType type includes fields such as id, title, and content, and also provides a comments field that represents the comments associated with that post.
With the post type definition in place, your GraphQL schema now has a clear representation of how posts are structured and their relationships to other types.
Now let's define the comment type in app/graphql/types/comment_type.rb
:
class Types::CommentType < Types::BaseObject
field :id, ID, null: false
field :post, Types::PostType, null: false
field :content, String, null: false
end
In this CommentType type, you are specifying that a comment has fields such as id, post, and content. The post field represents the relationship between a comment and the post it belongs to, using the PostType type you defined earlier.
With the comment type definition in place, you now have a more complete GraphQL schema that clearly represents the structure of your data
Testing the Posts API
After setting up our GraphQL API for Posts, execute your rails server
and now you can test it using cURL directly from the command line or with more visual tools like Postman:
curl --location 'http://localhost:3001/graphql' \
--header 'Content-Type: application/json' \
--data '{"query":"query {\n posts {\n id\n title\n comments {\n id\n content\n }\n }\n}\n","variables":{}}'
In Postman, for example, the result should look like this:
In this journey through implementing GraphQL in a Ruby on Rails application, we've covered everything from initial setup to creating GraphQL resolvers and types to handle specific queries. GraphQL gives us the flexibility to request exactly the data we need, resulting in more efficient and tailored APIs.
We've explored creating types, resolvers and how to test our queries using cURL and Postman. Now with a solid foundation, but in the next post we will add to our schema GraphQL includes an additional query called post, which uses the Resolvers::PostResolver resolver to handle retrieving a specific post by its id.
Top comments (0)