dataloader.ex (1533B)
1 if Code.ensure_loaded?(Dataloader) do 2 defmodule Absinthe.Middleware.Dataloader do 3 @behaviour Absinthe.Middleware 4 @behaviour Absinthe.Plugin 5 6 @impl Absinthe.Plugin 7 def before_resolution(%{context: context} = exec) do 8 context = 9 with %{loader: loader} <- context do 10 %{context | loader: Dataloader.run(loader)} 11 end 12 13 %{exec | context: context} 14 end 15 16 @impl Absinthe.Middleware 17 def call(%{state: :unresolved} = resolution, {loader, callback}) do 18 if !Dataloader.pending_batches?(loader) do 19 resolution.context.loader 20 |> put_in(loader) 21 |> get_result(callback) 22 else 23 %{ 24 resolution 25 | context: Map.put(resolution.context, :loader, loader), 26 state: :suspended, 27 middleware: [{__MODULE__, callback} | resolution.middleware] 28 } 29 end 30 end 31 32 def call(%{state: :suspended} = resolution, callback) do 33 get_result(resolution, callback) 34 end 35 36 defp get_result(resolution, callback) do 37 value = callback.(resolution.context.loader) 38 Absinthe.Resolution.put_result(resolution, value) 39 end 40 41 @impl Absinthe.Plugin 42 def after_resolution(exec) do 43 exec 44 end 45 46 @impl Absinthe.Plugin 47 def pipeline(pipeline, exec) do 48 with %{loader: loader} <- exec.context, 49 true <- Dataloader.pending_batches?(loader) do 50 [Absinthe.Phase.Document.Execution.Resolution | pipeline] 51 else 52 _ -> pipeline 53 end 54 end 55 end 56 end