# `AshPhoenixGenApi.Domain`
[🔗](https://github.com/ohhi-vn/ash_phoenix_gen_api/blob/v1.0.3/lib/ash_phoenix_gen_api/domain.ex#L1)

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
    end

This 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
    end

## Domain-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:
1. Resource action-level (e.g., `action :foo do timeout 10_000 end`)
2. Resource section-level (e.g., `gen_api do timeout 5_000 end`)
3. Domain section-level (this extension, e.g., `gen_api do timeout 5_000 end`)
4. 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, []}
    end

This adds the following functions to the generated supporter module:

- `build_push_config/0` - Builds a `PushConfig` struct from the domain config
- `push_to_gateway/2` - Pushes config to a specific gateway node
- `push_on_startup/2` - Pushes config on application startup
- `verify_on_gateway/2` - Verifies config version on a gateway node
- `resolve_push_nodes/0` - Resolves `push_nodes` at runtime
- `push_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

# `gen_api`
*macro* 

---

*Consult [api-reference.md](api-reference.md) for complete listing*
