AbsintheUtils.Middleware.ArgLoader (absinthe_utils v0.3.0)
View SourceAbsinthe 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 (or path) to a keyword list, containing:
new_name: the new key to push the loaded entity into, can be a list of atoms to push the entity into a nested map. (optional, defaults to the argument name - the key of the map configuration).load_function: the function used to load the argument into an entity. As an input accepts two arguments:context: the context of the current resolution (prior to any modifications of the current middleware).input_value: the value received in the value ofargument_name. The function should return the entity or a list of entities.nilor an empty list when not found .
nil_is_not_found: whether to considernilas a not found value. (optional, defaults totrue).
Examples
query do
field :user, :user do
arg(:id, :id)
# Add the middleware before your resolver
middleware(
ArgLoader,
%{
id: [
new_name: :user,
load_function: fn _context, id ->
get_user_by_id(id)
end,
nil_is_not_found: false
]
}
)
resolve(fn _, arguments, _ ->
{:ok, Map.get(arguments, :user)}
end)
endThis will define a user query that accepts an id input. Before calling the resolver,
List of entities
ArgLoader can also be used to load a list_of arguments:
query do
field :users, non_null(list_of(:user)) do
arg(:ids, non_null(list_of(:id)))
middleware(
ArgLoader,
%{
ids: [
new_name: :users,
load_function: fn _context, ids ->
ids
|> get_users_by_id()
|> AbsintheUtils.Helpers.Sorting.sort_alike(ids, & &1.id)
end
]
}
)
resolve(fn _, params, _ ->
{:ok, Map.get(params, :users)}
end)
end
endDeep nested arguments
Using ArgLoader to load and rename deep nested arguments:
input_object :complex_input_object do
field(:user_id, :id)
end
query do
field :users, :boolean do
arg(:input, :complex_input_object)
middleware(
ArgLoader,
%{
[:input, :user_id] => [
new_name: [:loaded_entities, :user],
load_function: fn _context, user_id ->
get_user_by_id(user_id)
end
]
}
)
resolve(fn _, params, _ ->
# params.loaded_entities.user will contain the loaded user
{:ok, true}
end)
end
endNote the use of AbsintheUtils.Helpers.Sorting.sort_alike/2 to ensure the returned list of
entities from the repository is sorted according to the user's input.