Avoiding Duplicate Queries with Absinthe

I am starting to get into GraphQL with Absinthe, and I really like it so far. One thing I’m trying to understand is the most efficient way to process queries.

One situation I’ve run into is that if I request the data of an association again through a nested request, it results in two queries. While this isn’t as bad as the N+1 problem, I’m guessing there is a better way of doing it. Here is an example query of what I’m referring to:

{
  post(id: 1){
    title
    comments {
      body
      post {
        title
      }
    }
  }
}

I’m using Dataloader(.Ecto), so this would result in a query for Post, a query for Comment, then a query Post again to get the nested Post value.

Is there a good way to avoid this?

I’ve provided some example code below just for context, but you might not need it.

In my schema, I have:

  query do
    @desc "Get all Posts"
    field :posts, list_of(:post) do
      resolve &Resolvers.Posts.list_posts/3
    end
  end

My resolver is simply something like this

  def list_posts(_parent, _args, _resolution) do
    {:ok, Posts.list_posts()}
  end

My post type would like something like:

  object :post do
    field(:id, :id)

    field(:title, non_null(:string))
    field(:comments, list_of(:comment), resolve: dataloader(Comments))
  end

Comments type would like something like:

  object :comment do
    field(:id, :id)

    field(:body, non_null(:string))
    field(:post, :post, resolve: dataloader(Posts))
  end
1 Like