Packages
absinthe_utils
0.0.1-development
0.3.0
0.2.0-1
0.1.0
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1-main-fc1bcd7a9a3344c3b816f69996b44e81c7df841e
0.0.1-main-f3f7019eeb29e81e58b52a1904179d5651d5ce47
0.0.1-main-da68e7b37af94f1d1ff6ba949de0bbc71944a428
0.0.1-main-d5a2fe6243598a29dec4ddb349d351661463aec6
0.0.1-main-d255e08b6c32fe6449757ed94e6abba8bb9a31e7
0.0.1-main-b324c3236f3971cfc05577e796dca31477a46391
0.0.1-main-96f126a7c33a43fc8af80891c168df27cb6fe738
0.0.1-main-8a629d261d43f2b462d4b7e6bbd32fee4871d54b
0.0.1-main-72f3aaa55e5beeeb85467282d2d97db0eb3f4f43
0.0.1-main-6cbd7212b9c6abb25241183c5764ec6b58af0cfd
0.0.1-main-413ca15b56c2636667dc5f1b7898f81da11032b0
0.0.1-main-2bcf8f0401b45d43a9c4592f2311f2e2cfd9309c
0.0.1-main-02ce6a58b060743c268bd76061f9b1ef0d90354a
0.0.1-development
Collection of utils for absinthe
Current section
Files
Jump to
Current section
Files
lib/middleware/arg_loader.ex
defmodule AbsintheUtils.Middleware.ArgLoader do
@moduledoc """
Absinthe middleware for loading entities in `field` arguments.
This middleware should be defined before `resolve`. It will manipulate the arguments
before they are passed to the resolver function.
As configuration it accepts a map of original argument names to a keyword list, containing:
- `load_function`: the function used to load the argument into an entity.
As an input accepts one single argument: the input received in the resolution.
It returns a tuple of `{:ok, nil}` `{:ok, nil}` o
- `new_name`: the new name to push the loaded entity into.
(optional, defaults to the original argument name).
## Example
```
query do
field :user, :user do
arg(:id, :id)
middleware(
ArgLoader,
%{
id: [
new_name: :user,
load_function: &get_user_by_id/1
]
}
)
resolve(fn _, arguments, _ ->
{:ok, Map.get(arguments, :user)}
end)
end
```
This will define a `user` query that accepts an `id` input. Before calling the resolver,
it will load the user via `get_user_by_id(id)` into the `user` argument, removing `id`.
"""
@behaviour Absinthe.Middleware
alias AbsintheUtilsTest.Helpers.Errors
@impl true
def call(
resolution = %{arguments: arguments},
opts
) do
{arguments, not_found_arguments} =
opts
|> Enum.reduce(
{arguments, []},
fn {argument_name, opts}, {arguments, not_found_arguments} ->
case load_entities(
arguments,
argument_name,
opts
) do
:not_found ->
{
arguments,
[argument_name | not_found_arguments]
}
arguments ->
{
arguments,
not_found_arguments
}
end
end
)
if Enum.empty?(not_found_arguments) do
%{
resolution
| arguments: arguments
}
else
Errors.put_error(
resolution,
"The entity(ies) provided in the following arg(s), could not be found: " <>
Enum.join(not_found_arguments, ", "),
"NOT_FOUND"
)
end
end
def load_entities(arguments, argument_name, opts)
when is_map_key(arguments, argument_name) do
load_function = Keyword.fetch!(opts, :load_function)
push_to_key = Keyword.get(opts, :new_name, argument_name)
{input_value, arguments} = Map.pop!(arguments, argument_name)
case load_function.(input_value) do
nil ->
:not_found
values when is_list(values) ->
# FIXME: we should not assume a list based on the output of the load function
# WE could also check the input type, but it would be better to replace it with a configuration flag
if length(values) != length(input_value) do
:not_found
else
Map.put(arguments, push_to_key, values)
end
value ->
Map.put(arguments, push_to_key, value)
end
end
def load_entities(arguments, _argument_identifier, _opts) do
arguments
end
end