Ash Domain extension for PhoenixGenApi configuration.
This extension provides domain-level configuration for PhoenixGenApi, including default service settings and automatic generation of a "supporter" module that aggregates FunConfigs from all resources in the domain.
The generated supporter module implements the PhoenixGenApi client
config interface (get_config/1, get_config_version/1), allowing
gateway nodes to pull API configurations from service nodes.
Usage
Add the extension to your Ash domain:
defmodule MyApp.Chat do
use Ash.Domain,
extensions: [AshPhoenixGenApi.Domain]
gen_api do
service "chat"
nodes {ClusterHelper, :get_nodes, [:chat]}
choose_node_mode :random
timeout 5_000
response_type :async
request_info true
version "0.0.1"
supporter_module MyApp.Chat.GenApiSupporter
end
resources do
resource MyApp.Chat.DirectMessage
resource MyApp.Chat.GroupMessage
end
endThis will generate MyApp.Chat.GenApiSupporter with:
defmodule MyApp.Chat.GenApiSupporter do
@moduledoc """
Auto-generated PhoenixGenApi supporter module for MyApp.Chat.
Aggregates FunConfigs from all resources in the domain.
"""
alias PhoenixGenApi.Structs.FunConfig
def get_config(remote_id) do
{:ok, fun_configs()}
end
def get_config_version(remote_id) do
{:ok, "0.0.1"}
end
def fun_configs do
MyApp.Chat.DirectMessage.__ash_phoenix_gen_api_fun_configs__() ++
MyApp.Chat.GroupMessage.__ash_phoenix_gen_api_fun_configs__()
end
def list_request_types do
fun_configs() |> Enum.map(& &1.request_type)
end
def get_fun_config(request_type) do
fun_configs() |> Enum.find(&(&1.request_type == request_type))
end
endDomain-Level Defaults
Domain-level settings serve as defaults for all resources in the domain
that use AshPhoenixGenApi.Resource. Each resource can override these
defaults in its own gen_api section.
Resolution order for any setting:
- Resource action-level (e.g.,
action :foo do timeout 10_000 end) - Resource section-level (e.g.,
gen_api do timeout 5_000 end) - Domain section-level (this extension, e.g.,
gen_api do timeout 5_000 end) - Built-in defaults (e.g., timeout defaults to 5000)
Gateway Node Configuration
On the Phoenix gateway node, configure the supporter module in config.exs:
config :phoenix_gen_api, :gen_api,
service_configs: [
%{
service: "chat",
nodes: {ClusterHelper, :get_nodes, [:chat]},
module: MyApp.Chat.GenApiSupporter,
function: :get_config,
args: [:gateway_1]
}
]Active Push Configuration
In addition to the pull-based model (where the gateway pulls config from service nodes), you can configure the supporter module to actively push its configuration to gateway nodes.
Set push_nodes to specify which gateway nodes to push to:
gen_api do
service "chat"
supporter_module MyApp.Chat.GenApiSupporter
version "0.0.1"
push_nodes [:"gateway1@host", :"gateway2@host"]
# Or use an MFA tuple for runtime resolution:
# push_nodes {ClusterHelper, :get_gateway_nodes, []}
endThis adds the following functions to the generated supporter module:
build_push_config/0- Builds aPushConfigstruct from the domain configpush_to_gateway/2- Pushes config to a specific gateway nodepush_on_startup/2- Pushes config on application startupverify_on_gateway/2- Verifies config version on a gateway noderesolve_push_nodes/0- Resolvespush_nodesat runtimepush_to_configured_nodes/1- Pushes to all configured push_nodes
Example usage during application startup:
def start(_type, _args) do
# ... start supervision tree, then:
MyApp.Chat.GenApiSupporter.push_to_configured_nodes()
# Or push to a specific node:
MyApp.Chat.GenApiSupporter.push_on_startup(:"gateway1@host")
end