Crudry v2.4.0 Crudry.Resolver View Source
Generates CRUD functions to DRY Absinthe Resolvers.
Requires a previously generated Context.
Usage
To generate CRUD functions for a given schema resolver, simply do
defmodule MyApp.MyResolver do
alias MyApp.Repo
alias MyApp.MyContext
alias MyApp.MySchema
require Crudry.Resolver
Crudry.Resolver.generate_functions MyContext, MySchema
end
And the resolver will have all these functions available:
defmodule MyApp.MyResolver do
alias MyApp.Repo
alias MyApp.MyContext
alias MyApp.MySchema
require Crudry.Resolver
def get_my_schema(%{id: id}, _info) do
id
|> MyContext.get_my_schema()
|> nil_to_error("my_schema", fn record -> {:ok, record} end)
end
def list_my_schemas(_args, _info) do
{:ok, MyContext.list_my_schemas([])}
end
def create_my_schema(%{params: params}, _info) do
MyContext.create_my_schema(params)
end
def update_my_schema(%{id: id, params: params}, _info) do
id
|> MyContext.get_my_schema()
|> nil_to_error("my_schema", fn record -> MyContext.update_my_schema(record, params) end)
end
def delete_my_schema(%{id: id}, _info) do
id
|> MyContext.get_my_schema()
|> nil_to_error("my_schema", fn record -> MyContext.delete_my_schema(record) end)
end
# If `result` is `nil`, return an error. Otherwise, apply `func` to the `result`.
def nil_to_error(result, name, func) do
case result do
nil -> {:error, %{message: "not found", schema: name}}
%{} = record -> func.(record)
end
end
def add_info_to_custom_query(custom_query, info) do
fn initial_query -> custom_query.(initial_query, info) end
end
end
Link to this section Summary
Functions
Sets default options for the resolver.
Generates CRUD functions for the schema_module
resolver.
Link to this section Functions
Sets default options for the resolver.
Options
:only
- list of functions to be generated. If not empty, functions not specified in this list are not generated. Defaults to[]
.:except
- list of functions to not be generated. If not empty, only functions not specified in this list will be generated. Defaults to[]
.list_opts
- options for thelist
function. See available options inCrudry.Query.list/2
. Defaults to[]
.create_resolver
- customcreate
resolver function with arity 4. Receives the following arguments: [Context, schema_name, args, info]. Defaults tonil
.not_found_message
- custom message for thenil_to_error
function. Defaults to"not found"
.primary_key
- custom primary key argument to use in get, update and delete resolvers. Defaults to:id
.
Note: in list_opts
, custom_query
will receive absinthe's info as the second argument and, therefore, must have arity 2. See example in generate_functions/3
.
The accepted values for :only
and :except
are: [:get, :list, :create, :update, :delete]
.
Examples
iex> Crudry.Resolver.default only: [:create, :list]
:ok
iex> Crudry.Resolver.default except: [:get!, :list, :delete]
:ok
iex> Crudry.Resolver.default list_opts: [order_by: :id]
:ok
iex> Crudry.Resolver.default list_opts: [custom_query: &scope_list/2]
:ok
Generates CRUD functions for the schema_module
resolver.
Custom options can be given. To see the available options, refer to the documenation of Crudry.Resolver.default/1
, noting that the not_found_message
must only be configured using default/1
.
Examples
Overriding functions
To define a custom function, add it to except
and define your own. In the following example, the schema is updated with its association.
defmodule MyApp.Resolver do
alias MyApp.Repo
alias MyApp.MyContext
alias MyApp.MySchema
require Crudry.Resolver
Crudry.Resolver.generate_functions MyContext, MySchema, except: [:update]
def update_my_schema(%{id: id, params: params}, _info) do
id
|> MyContext.get_my_schema()
|> nil_to_error("My Schema", fn record -> MyContext.update_my_schema_with_assocs(record, params, [:assoc]) end)
end
end
By using the nil_to_error
function, we DRY the nil checking and also ensure the error message is the same as the other auto-generated functions.
Custom create resolver
It's possible to define a custom create function, useful when all functions in a resolver change the data in the same way before creating:
defmodule MyApp.Resolver do
alias MyApp.Repo
alias MyApp.MyContext
alias MyApp.MySchema
require Crudry.Resolver
Crudry.Resolver.default create_resolver: &create_resolver/4)
Crudry.Resolver.generate_functions MyContext, MySchema
Crudry.Resolver.generate_functions MyContext, OtherSchema
def create_resolver(context, schema_name, args, %{context: %{current_user: %{company_id: company_id}}}) do
apply(context, :"create_#{schema_name}", [Map.put(args.params, :company_id, company_id)])
end
end
Now when creating MySchema
and OtherSchema
, the custom function will put the current user's company_id
in the params.
Custom query
It's also possible to use a custom query that has access to absinthe's info
:
defmodule MyApp.Resolver do
alias MyApp.Repo
alias MyApp.MyContext
alias MyApp.MySchema
require Crudry.Resolver
def scope_list(MySchema, %{context: %{current_user: current_user}} = _info) do
where(MySchema, [p], p.user_id == ^current_user.id)
end
Crudry.Resolver.generate_functions MyContext, MySchema, list_opts: [custom_query: &scope_list/2]
end
With this, the list function will effectively become:
def list_my_schemas(_args, info) do
{:ok, MyContext.list_my_schemas(custom_query: add_info_to_custom_query(scope_list, info))}
end
See Crudry.Query.list/2
for further information on the custom_query
option.