Packages
cqrs_tools
0.2.21
0.5.28
0.5.27
0.5.26
0.5.25
0.5.24
0.5.23
0.5.22
0.5.21
0.5.20
0.5.19
0.5.18
0.5.17
0.5.16
0.5.15
0.5.14
0.5.13
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.19
0.4.18
0.4.17
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.22
0.3.21
0.3.20
0.3.19
0.3.18
0.3.17
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.30
0.2.29
0.2.28
0.2.27
0.2.26
0.2.25
0.2.24
0.2.23
0.2.22
0.2.21
0.2.20
0.2.19
0.2.18
0.2.17
0.2.16
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.1
0.1.0
A collection of handy Elixir macros for CQRS applications.
Current section
Files
Jump to
Current section
Files
lib/cqrs/absinthe.ex
if Code.ensure_loaded?(Absinthe) do
defmodule Cqrs.Absinthe do
@moduledoc """
Macros to derive queries and mutations from [Queries](`Cqrs.Query`) and [Commands](`Cqrs.Command`), respectfully.
## Configuration
* `:context_metadata_keys` - A list of the keys in the `Absinthe.Resolution` `context` to pass to queries and mutations as metadata
config :cqrs_tools, :absinthe, context_metadata_keys: []
## Example
defmodule ExampleApi.Types.UserTypes do
@moduledoc false
use Cqrs.Absinthe
use Absinthe.Schema.Notation
alias Example.Queries.{ListUsers, GetUser}
alias Example.Users.Protocol.{CreateUser, SuspendUser, ReinstateUser}
import ExampleApi.Resolvers.UserResolver
enum :user_status do
value :active
value :suspended
end
object :user do
field :id, :id
field :name, :string
field :email, :string
field :status, :user_status
end
object :user_queries do
derive_query GetUser, :user,
as: :user,
except: [:name]
derive_query ListUsers, list_of(:user),
as: :users,
arg_types: [status: :user_status]
end
derive_mutation_input CreateUser
object :user_mutations do
derive_mutation CreateUser, :user, input_object?: true, then: &fetch_user/1
derive_mutation SuspendUser, :user, then: &fetch_user/1
derive_mutation ReinstateUser, :user, then: &fetch_user/1
end
end
"""
alias Cqrs.Guards
alias Cqrs.Absinthe.{Mutation, Query}
defmacro __using__(_) do
quote do
use Absinthe.Schema.Notation
import Cqrs.Absinthe,
only: [
derive_mutation_input: 1,
derive_mutation_input: 2,
derive_mutation: 2,
derive_mutation: 3,
derive_query: 2,
derive_query: 3
]
end
end
@doc """
Defines an `Absinthe` `query` from a [Query](`Cqrs.Query`).
## Options
* `:as` - The name to use for the query. Defaults to the query_module name snake_cased.
* `:only` - Use only the filters listed
* `:except` - Create filters for all except those listed
"""
defmacro derive_query(query_module, return_type, opts \\ []) do
opts = Macro.escape(opts)
return_type = Macro.escape(return_type)
field =
quote location: :keep do
Guards.ensure_is_query!(unquote(query_module))
opts = Keyword.merge(unquote(opts), source: unquote(query_module), macro: :derive_query)
Query.create_query(
unquote(query_module),
unquote(return_type),
unquote(opts)
)
end
Module.eval_quoted(__CALLER__, field)
end
@doc """
Defines an `Absinthe` `input_object` for a [Command](`Cqrs.Command`).
## Options
* `:as` - The name to use for the query. Defaults to the command_module name snake_cased with `_input` appended.
"""
defmacro derive_mutation_input(command_module, opts \\ []) do
opts = Macro.escape(opts)
input =
quote location: :keep do
opts =
unquote(opts)
|> Keyword.merge(source: unquote(command_module), macro: :derive_mutation_input)
|> Keyword.drop([:only, :except])
Guards.ensure_is_command!(unquote(command_module))
Mutation.create_input_object(unquote(command_module), opts)
end
Module.eval_quoted(__CALLER__, input)
end
@doc """
Defines an `Absinthe` `mutation` for a [Command](`Cqrs.Command`).
## Options
* `:as` - The name to use for the mutation. Defaults to the query_module name snake_cased.
* `:then` - A `function/1` that accepts the result of the command execution. The function should return the standard `Absinthe` `{:ok, response}` or `{:error, error}` tuple.
* `:input_object?` - `true | false`. Defaults to `false`
* If `true`, one arg with the name of `:input` will be generated.
* If `true`, an `input_object` for the [Command](`Cqrs.Command`) is expected to exist. See `derive_mutation_input/2`.
"""
defmacro derive_mutation(command_module, return_type, opts \\ []) do
opts = Macro.escape(opts)
return_type = Macro.escape(return_type)
mutation =
quote location: :keep do
Guards.ensure_is_command!(unquote(command_module))
opts =
unquote(opts)
|> Keyword.merge(source: unquote(command_module), macro: :derive_mutation)
|> Keyword.drop([:only, :except])
Mutation.create_mutatation(
unquote(command_module),
unquote(return_type),
unquote(opts)
)
end
Module.eval_quoted(__CALLER__, mutation)
end
end
end