Skip to content

Instantly share code, notes, and snippets.

@sapandiwakar
Last active April 18, 2023 04:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sapandiwakar/067b283d14905f0c9dcafb378c783cd7 to your computer and use it in GitHub Desktop.
Save sapandiwakar/067b283d14905f0c9dcafb378c783cd7 to your computer and use it in GitHub Desktop.
Using Dataloader with Absinthe to avoid N+1 queries
# my_app/blog.ex
defmodule MyApp.Blog do
def data(), do: Dataloader.Ecto.new(MyApp.Repo, query: &query/2)
def query(queryable, _params), do: queryable
end
# my_app_web/resolvers/blog.ex
defmodule MyAppWeb.Resolvers.Blog do
def list_posts(%{}, %Absinthe.Resolution{}) do
{:ok, Blog.list_posts()}
end
end
# my_app_web/schema.ex
defmodule MyAppWeb.Schema do
use Absinthe.Schema
import Absinthe.Resolution.Helpers, only: [dataloader: 2]
alias MyAppWeb.Resolvers
object :author do
field :id, non_null(:id)
field :first_name, :string
end
object :post do
field :id, non_null(:id)
field :title, non_null(:string)
field :author, non_null(:author),
resolve: dataloader(MyApp.Blog, :author)
end
query do
field :posts, non_null(list_of(:post)),
resolve: &Resolvers.Blog.list_posts/2
end
def context(ctx) do
loader =
Dataloader.new
|> Dataloader.add_source(Blog, Blog.data())
Map.put(ctx, :loader, loader)
end
def plugins do
[Absinthe.Middleware.Dataloader] ++ Absinthe.Plugin.defaults()
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment