DEV Community

Humberto Arroyo
Humberto Arroyo

Posted on

How to Create a GraphQL API With Ruby on Rails: A Step-by-Step Guide - Part 1

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
Enter fullscreen mode Exit fullscreen mode

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 the app/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. Within app/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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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!'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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":{}}'

Enter fullscreen mode Exit fullscreen mode

In Postman, for example, the result should look like this:

Image description

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)