AshPhoenixGenApi.Transformers.DefineFunConfigs
(ash_phoenix_gen_api v1.0.3)
Copy Markdown
View Source
Transformer that generates PhoenixGenApi FunConfig structs and code interface functions from Ash resource actions.
This transformer reads the gen_api DSL section configuration and:
Generates
PhoenixGenApi.Structs.FunConfigstructs for each configured action, stored in a__ash_phoenix_gen_api_fun_configs__/0function on the resource module.Generates code interface functions for each enabled action (when
code_interface?istrue), allowing developers to call Ash actions directly as Elixir functions on the resource module.
Resolution Order
For each FunConfig field, values are resolved in this order:
- Action-level explicit config — e.g.,
action :foo do timeout 10_000 end - Resource section-level defaults — e.g.,
gen_api do timeout 5_000 end - Built-in defaults — e.g., timeout defaults to
5000
For arg_types and arg_orders:
- Explicit
arg_types/arg_orderson the action entity - Auto-derived from the Ash action's accepted attributes and arguments
using
AshPhoenixGenApi.TypeMapper
For mfa:
- Explicit
mfaon the action entity - Auto-generated as
{ResourceModule, :action_name, []}
For code_interface?:
- Action-level
code_interface?on the action entity - Section-level
code_interface?— e.g.,gen_api do code_interface? true end - Built-in default — defaults to
true
Generated Functions
After this transformer runs, the resource module will have:
def __ash_phoenix_gen_api_fun_configs__ do
[
%PhoenixGenApi.Structs.FunConfig{
request_type: "send_direct_message",
service: "chat",
nodes: {ClusterHelper, :get_nodes, [:chat]},
# ...
},
# ...
]
endThis function is used by AshPhoenixGenApi.Resource.Info.fun_configs/1 and
by the domain-level supporter module to aggregate FunConfigs.
Additionally, for each action with code_interface? enabled, the following
functions are generated. All functions use CodeInterface.params_and_opts/2
to properly disambiguate between args maps and opts keyword lists, allowing
callers to pass just opts (e.g., action(actor: user)) without wrapping
them in a second argument.
Create actions
def create_action(params_or_opts \\ [], opts \\ []) do
{args, opts} = CodeInterface.params_and_opts(params_or_opts, opts)
Changeset.for_create(__MODULE__, :create_action, args, opts)
|> Ash.create(opts)
end
def create_action!(params_or_opts \\ [], opts \\ []) do
{args, opts} = CodeInterface.params_and_opts(params_or_opts, opts)
Changeset.for_create(__MODULE__, :create_action, args, opts)
|> Ash.create!(opts)
endRead actions
def read_action(params_or_opts \\ [], opts \\ []) do
{args, opts} = CodeInterface.params_and_opts(params_or_opts, opts)
Query.for_read(__MODULE__, :read_action, args, opts)
|> Ash.read(opts)
end
def read_action!(params_or_opts \\ [], opts \\ []) do
{args, opts} = CodeInterface.params_and_opts(params_or_opts, opts)
Query.for_read(__MODULE__, :read_action, args, opts)
|> Ash.read!(opts)
endUpdate actions (require a record as first argument)
def update_action(record, params_or_opts \\ [], opts \\ []) do
{args, opts} = CodeInterface.params_and_opts(params_or_opts, opts)
Changeset.for_update(record, :update_action, args, opts)
|> Ash.update(opts)
end
def update_action!(record, params_or_opts \\ [], opts \\ []) do
{args, opts} = CodeInterface.params_and_opts(params_or_opts, opts)
Changeset.for_update(record, :update_action, args, opts)
|> Ash.update!(opts)
endDestroy actions (require a record as first argument)
def destroy_action(record, params_or_opts \\ [], opts \\ []) do
{args, opts} = CodeInterface.params_and_opts(params_or_opts, opts)
Changeset.for_destroy(record, :destroy_action, args, opts)
|> Ash.destroy(opts)
end
def destroy_action!(record, params_or_opts \\ [], opts \\ []) do
{args, opts} = CodeInterface.params_and_opts(params_or_opts, opts)
Changeset.for_destroy(record, :destroy_action, args, opts)
|> Ash.destroy!(opts)
endGeneric actions
def generic_action(params_or_opts \\ [], opts \\ []) do
{args, opts} = CodeInterface.params_and_opts(params_or_opts, opts)
ActionInput.for_action(__MODULE__, :generic_action, args, opts)
|> Ash.run_action(opts)
end
def generic_action!(params_or_opts \\ [], opts \\ []) do
{args, opts} = CodeInterface.params_and_opts(params_or_opts, opts)
ActionInput.for_action(__MODULE__, :generic_action, args, opts)
|> Ash.run_action!(opts)
end
Summary
Functions
Runs after all other transformers so that Ash action info is fully available.
Callback implementation for Spark.Dsl.Transformer.after_compile?/0.
Does not need to run before any specific transformer.
Functions
Runs after all other transformers so that Ash action info is fully available.
Callback implementation for Spark.Dsl.Transformer.after_compile?/0.
Does not need to run before any specific transformer.