Rails Kitchen

It's a place to write on stuff I learned recently.

GraphQL Server - Nested Query Implementation Example in Ruby on Rails

| Comments

One of the main advantages of GraphQL is, we can create queries with a different combination of datasets which will avoid multiple requests to fetch required data, thereby eliminating overheads. In this post, I am discussing how we can create nested datasets in GraphQL.

In the previous post, I mentioned about Article model and query to fetch an article. Here I’m going to fetch comments under the article. Assuming we have comments and user model with corresponding associations.

Now we need to add CommentType.
app/graphql/types/comment_type.rb
1
2
3
4
5
6
CommentType = GraphQL::ObjectType.define do
  name "Comment"
  field :id, types.Int
  field :comment, types.String
  field :user, UserType
end
Here we are exposing commented user which is UserType. So we need to define that type also in user_type.rb
app/graphql/types/user_type.rb
1
2
3
4
5
6
UserType = GraphQL::ObjectType.define do
  name "User"
  field :id, types.Int
  field :name, types.String
  field :email, types.String
end
Now we need to expose comments inside article model
app/graphql/types/article_type.rb
1
2
3
4
5
6
7
ArticleType = GraphQL::ObjectType.define do
  name "Article"
  field :id, types.Int
  field :title, types.String
  field :body, types.String
  field :comments, types[CommentType]
end

Here comments are an array of objects so we need to specify CommentType using types keyword. We can see in comment_type.rb we are not specifying types for UserType, as it is returning a single object. Since we defined association in, This will fetch all comments of the article by executing article.comments.

Put below code in application.rb to autoload graphql and types folder like so:
config/application.rb
1
2
config.autoload_paths << Rails.root.join('app/graphql')
config.autoload_paths << Rails.root.join('app/graphql/types')
Here’s an example of a GraphQL query that a client can use to ask a server about the title of the article, corresponding comments and commented user:
1
2
3
4
5
6
7
8
9
10
11
12
query {
  article(id: 1){
    title
    comments{
      comment
      user {
        id
        name
      }
    }
  }
}
Here’s a possible JSON response for that query:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
  "data": {
    "article": {
      "title": "A GraphQL Server",
      "comments": [
        {
          "comment": "Good article",
          "user": {
            "id": 1,
            "name": "Shaiju E"
          }
        },
        {
          "comment": "Keep going",
          "user": {
            "id": 1,
            "name": "Shaiju E"
          }
        }
      ]
    }
  }
}
You can see sample code here.

Comments