absinthe-graphql / absinthe_ecto

DEPRECATED: Use dataloader
MIT License
130 stars 36 forks source link

Don't preload if only requesting the "id" field of a belongs_to association #32

Open Betree opened 6 years ago

Betree commented 6 years ago

This is a duplicate of https://github.com/absinthe-graphql/dataloader/issues/7. I'm not using dataloader anymore at the moment and figured out it has more of its place here.

Let's say I have a :fruits_basket object that can contains fruits and that can be placed in another basket. Something like:

object :fruits_basket do
  field :id, non_null(:id)
  field :slug, non_null(:string)
  field :fruits, list_of(:delicious_fruit), do: resolve assoc(:fruits)
  field :parent, :fruits_basket, do: resolve assoc(:parent_basket)
end

As of today a request like:

basket(slug: "grandma-basket") {
  id
  fruits {
    name
    color
  }
  parent {
    id # We only ask for parent's id and no other field
  }
}

...would make two queries like:

SELECT (...) FROM fruits_baskets WHERE slug = "grandma-basket" -- Get basket
SELECT (...) FROM fruits_baskets WHERE id = 42 -- Get parent basket

The thing is that second query is not necessary: we already have the parent id in grandma's basket.

I think it is a very common pattern to query only for the id of an association. In this example, the request could be used to show a "Go to parent" link on the frontend.

My real use case is a comment system where comments can reply to each others by using a reply_to field. I would love to see assoc use the reply_to_id field instead of preloading the full reply_to when requesting only the id.

The easiest way to achieve this with actual system is to add a field for the id:

...
field :reply_to_id, :id
field :reply_to :comment, do: resolve assoc(:reply_to)
...

But that doesn't look very neat to me.