Skip to content
This repository has been archived by the owner on Feb 17, 2020. It is now read-only.

Commit

Permalink
Add dataloader support for resolving N+1 queries
Browse files Browse the repository at this point in the history
  • Loading branch information
pozhega committed Nov 12, 2018
1 parent 1e5ec25 commit 6486d03
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 12 deletions.
11 changes: 11 additions & 0 deletions lib/crudimentary/absinthe/dataloader/source.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defmodule CertifyEdWeb.API.Graphql.Dataloader.Source do
import Ecto.Query

@repo Confex.get_env(CRUDimentary.MixProject.project()[:app], :repo)

def data(), do: Dataloader.Ecto.new(@repo, query: &query/2)

defp query(queryable, _params) do
from(q in queryable, select: %{data: q})
end
end
32 changes: 21 additions & 11 deletions lib/crudimentary/absinthe/middlewares/default.ex
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
defmodule CRUDimentary.Absinthe.Middlewares.Default do
def call(%{source: source} = resolution, %{field: field, object: object}) do
value =
with %_{} <- source,
false <- String.ends_with?(object.name, "Result"),
object_resolver when not is_nil(object_resolver) <- extract_object_resolver(object),
{:ok, value} <-
object_resolver.(source, resolution.definition.argument_data, resolution) do
value
else
_ -> Map.get(source, field.identifier)
end
with %_{} <- source,
false <- String.ends_with?(object.name, "Result"),
object_resolver when not is_nil(object_resolver) <- extract_object_resolver(object) do
case object_resolver.(source, resolution.definition.argument_data, resolution) do
{:ok, value} ->
add_resolution_value(resolution, value)

%{resolution | state: :resolved, value: value}
{:middleware, module, opts} ->
add_resolution_middlware(resolution, {module, opts})
end
else
_ ->
add_resolution_value(resolution, Map.get(source, field.identifier))
end
end

defp extract_object_resolver(object) do
Expand All @@ -23,4 +25,12 @@ defmodule CRUDimentary.Absinthe.Middlewares.Default do
nil
end
end

defp add_resolution_value(resolution, value) do
%{resolution | state: :resolved, value: value}
end

defp add_resolution_middlware(resolution, middleware) do
%{resolution | state: :unresolved, middleware: [middleware | resolution.middleware]}
end
end
3 changes: 2 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ defmodule CRUDimentary.MixProject do
{:odgn_json_pointer, "~> 2.3"},
{:paginator, "~> 0.3"},
{:phoenix, ">= 0.0.0"},
{:confex, "~> 3.3.1"}
{:confex, "~> 3.3.1"},
{:dataloader, "~> 1.0.4"}
]
end
end
1 change: 1 addition & 0 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"absinthe_plug": {:hex, :absinthe_plug, "1.4.5", "f63d52a76c870cd5f11d4bed8f61351ab5c5f572c5eb0479a0137f9f730ba33d", [:mix], [{:absinthe, "~> 1.4.11", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.2 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
"base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"},
"confex": {:hex, :confex, "3.3.1", "8febaf751bf293a16a1ed2cbd258459cdcc7ca53cfa61d3f83d49dd276a992b4", [:mix], [], "hexpm"},
"dataloader": {:hex, :dataloader, "1.0.4", "7c2345c53c9e5b61420013fc53c8463ba347a938b61f66677eb47d9c4a53ac5d", [:mix], [{:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
"decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"},
"delirium_tremex": {:git, "https://github.com/floatingpointio/delirium_tremex.git", "b1c487386f9b822cf9a398620a1d355b86b3b867", []},
"earmark": {:hex, :earmark, "1.2.5", "4d21980d5d2862a2e13ec3c49ad9ad783ffc7ca5769cf6ff891a4553fbaae761", [:mix], [], "hexpm"},
Expand Down

0 comments on commit 6486d03

Please sign in to comment.