AshPhoenixGenApi.JsonConfig (ash_phoenix_gen_api v1.0.3)

Copy Markdown View Source

Utility for generating JSON function config lists from Ash resources and domains.

Generates configuration maps in the PhoenixGenApi JSON function config format, where each key is a "request_type - Description" string and each value contains the event/data structure for the gateway.

Output Formats

The module supports multiple output formats via the :format option:

  • :fun_configs (default) — Returns the original list of PhoenixGenApi.Structs.FunConfig structs (Ash Resource type)
  • :map — Returns an Elixir map in the JSON config list format
  • :json — Returns a JSON-encoded string
  • {Module, :function, args} — Custom encoder MFA that receives the FunConfig list and returns the desired format

JSON Config List Format

The map format produces a structure like:

%{
  "send_direct_message - Send direct message to other user" => %{
    "event" => "phoenix_gen_api",
    "data" => %{
      "user_id" => "user_1",
      "device_id" => "device_1",
      "request_type" => "send_direct_message",
      "request_id" => "request_1",
      "service" => "chat",
      "version" => "0.0.1",
      "args" => %{
        "to_user_id" => "",
        "content" => "",
        "reply_to_id" => ""
      }
    }
  }
}

Usage

# Default: returns FunConfig structs (Ash Resource type)
AshPhoenixGenApi.JsonConfig.generate(MyApp.Chat)
#=> [%PhoenixGenApi.Structs.FunConfig{...}, ...]

# As Elixir map (JSON config list format)
AshPhoenixGenApi.JsonConfig.generate(MyApp.Chat, format: :map)
#=> %{"send_direct_message - ..." => %{...}, ...}

# As JSON string
AshPhoenixGenApi.JsonConfig.generate(MyApp.Chat, format: :json)
#=> "{\"send_direct_message - ...\": {...}, ...}"

# Custom encoder MFA
AshPhoenixGenApi.JsonConfig.generate(MyApp.Chat, format: {MyEncoder, :encode, []})

# With custom descriptions
AshPhoenixGenApi.JsonConfig.generate(MyApp.Chat,
  format: :map,
  descriptions: %{"send_direct_message" => "Send direct message to other user"}
)

# With description function
AshPhoenixGenApi.JsonConfig.generate(MyApp.Chat,
  format: :map,
  descriptions: fn fun_config ->
    String.replace(fun_config.request_type, "_", " ")
  end
)

# With custom arg values
AshPhoenixGenApi.JsonConfig.generate(MyApp.Chat,
  format: :map,
  arg_values: %{
    "send_direct_message" => %{
      "to_user_id" => "user_2",
      "content" => "Hello, how are you?",
      "reply_to_id" => ""
    }
  }
)

# With arg values function
AshPhoenixGenApi.JsonConfig.generate(MyApp.Chat,
  format: :map,
  arg_values: fn fun_config ->
    # Generate example values based on arg types
    fun_config.arg_types
    |> Enum.map(fn {name, type} -> {name, example_value(type)} end)
    |> Map.new()
  end
)

Summary

Types

Source for argument example/default values.

Source for description strings used in config keys.

Output format for the generated config.

Option for generate/2.

Functions

Returns a default example value for a PhoenixGenApi argument type.

Converts a single FunConfig struct to a map entry tuple.

Generates a function config list from an Ash domain or resource.

Generates a function config list from an Ash domain.

Generates a function config list from an Ash resource.

Converts a list of FunConfig structs to a JSON string.

Converts a list of FunConfig structs to the JSON config map format.

Types

arg_values()

@type arg_values() ::
  %{required(String.t()) => %{required(String.t()) => term()}}
  | (map() -> map())
  | nil

Source for argument example/default values.

  • A map of %{request_type => %{arg_name => value}} for static values
  • A function (fun_config -> args_map) for dynamic values
  • nil — Uses type-based default values

description_source()

@type description_source() ::
  %{required(String.t()) => String.t()} | (map() -> String.t()) | nil

Source for description strings used in config keys.

  • A map of %{request_type => description} for static descriptions
  • A function (fun_config -> description) for dynamic descriptions
  • nil — Uses request_type as the key without description

format()

@type format() :: :fun_configs | :map | :json | {module(), atom(), [any()]}

Output format for the generated config.

  • :fun_configs — Returns PhoenixGenApi.Structs.FunConfig structs (Ash Resource type)
  • :map — Returns Elixir map in JSON config list format
  • :json — Returns JSON-encoded string
  • {Module, :function, args} — Custom encoder MFA

option()

@type option() ::
  {:format, format()}
  | {:user_id, String.t()}
  | {:device_id, String.t()}
  | {:request_id, String.t()}
  | {:descriptions, description_source()}
  | {:event_name, String.t()}
  | {:arg_values, arg_values()}

Option for generate/2.

  • :format — Output format (default: :fun_configs)
  • :user_id — Default user_id in data (default: "user_1")
  • :device_id — Default device_id in data (default: "device_1")
  • :request_id — Default request_id in data (default: "request_1")
  • :descriptions — Description source for key names (default: nil)
  • :event_name — Event name string (default: "phoenix_gen_api")
  • :arg_values — Argument values source (default: nil)

Functions

default_value_for_type(type)

@spec default_value_for_type(atom() | tuple() | keyword()) :: term()

Returns a default example value for a PhoenixGenApi argument type.

Useful for generating placeholder values in the args map.

Examples

iex> AshPhoenixGenApi.JsonConfig.default_value_for_type(:string)
""

iex> AshPhoenixGenApi.JsonConfig.default_value_for_type(:num)
0

iex> AshPhoenixGenApi.JsonConfig.default_value_for_type(:boolean)
false

iex> AshPhoenixGenApi.JsonConfig.default_value_for_type(:datetime)
""

iex> AshPhoenixGenApi.JsonConfig.default_value_for_type(:naive_datetime)
""

iex> AshPhoenixGenApi.JsonConfig.default_value_for_type(:map)
%{}

iex> AshPhoenixGenApi.JsonConfig.default_value_for_type(:list)
[]

iex> AshPhoenixGenApi.JsonConfig.default_value_for_type({:list_string, 100, 50})
[]

iex> AshPhoenixGenApi.JsonConfig.default_value_for_type({:list_num, 100})
[]

iex> AshPhoenixGenApi.JsonConfig.default_value_for_type({:string, 255})
""

iex> AshPhoenixGenApi.JsonConfig.default_value_for_type({:map, 100})
%{}

iex> AshPhoenixGenApi.JsonConfig.default_value_for_type({:list, 100})
[]

fun_config_to_entry(fun_config, opts \\ [])

@spec fun_config_to_entry(map(), [option()]) :: {String.t(), map()}

Converts a single FunConfig struct to a map entry tuple.

Returns {key, value} where key is the config key string and value is the event/data map.

Parameters

Examples

fun_config = %PhoenixGenApi.Structs.FunConfig{request_type: "send_direct_message", ...}
{key, value} = AshPhoenixGenApi.JsonConfig.fun_config_to_entry(fun_config)
#=> {"send_direct_message", %{"event" => "phoenix_gen_api", "data" => %{...}}}

generate(source, opts \\ [])

@spec generate(module(), [option()]) :: term()

Generates a function config list from an Ash domain or resource.

Automatically detects whether the source is a domain or resource and retrieves the appropriate FunConfig structs.

Parameters

  • source — An Ash domain or resource module
  • opts — Options for generation and encoding

Options

  • :format — Output format (default: :fun_configs)
    • :fun_configs — Returns list of PhoenixGenApi.Structs.FunConfig structs
    • :map — Returns Elixir map in JSON config list format
    • :json — Returns JSON-encoded string
    • {Module, :function, args} — Custom encoder MFA
  • :user_id — Default user_id in data. Default: "user_1"
  • :device_id — Default device_id in data. Default: "device_1"
  • :request_id — Default request_id in data. Default: "request_1"
  • :descriptions — Description source for key names. Can be:
    • A map of %{request_type => description}
    • A function (fun_config -> description)
    • nil — Uses request_type as key (default)
  • :event_name — Event name string. Default: "phoenix_gen_api"
  • :arg_values — Argument values source. Can be:
    • A map of %{request_type => %{arg_name => value}}
    • A function (fun_config -> args_map)
    • nil — Uses type-based defaults (default)

Returns

The generated config in the specified format.

Examples

# From a domain — default format (FunConfig structs)
AshPhoenixGenApi.JsonConfig.generate(MyApp.Chat)
#=> [%PhoenixGenApi.Structs.FunConfig{request_type: "send_direct_message", ...}, ...]

# From a domain — map format
AshPhoenixGenApi.JsonConfig.generate(MyApp.Chat, format: :map)
#=> %{"send_direct_message" => %{...}, ...}

# From a resource — map format
AshPhoenixGenApi.JsonConfig.generate(MyApp.Chat.DirectMessage, format: :map)

# With custom descriptions
AshPhoenixGenApi.JsonConfig.generate(MyApp.Chat,
  format: :map,
  descriptions: %{"send_direct_message" => "Send direct message to other user"}
)

# With custom encoder MFA
AshPhoenixGenApi.JsonConfig.generate(MyApp.Chat, format: {MyEncoder, :encode, []})

generate_from_domain(domain, opts \\ [])

@spec generate_from_domain(module(), [option()]) :: term()

Generates a function config list from an Ash domain.

Same as generate/2 but explicitly for domain modules.

Parameters

  • domain — An Ash domain module
  • opts — Same options as generate/2

Examples

AshPhoenixGenApi.JsonConfig.generate_from_domain(MyApp.Chat, format: :map)

generate_from_resource(resource, opts \\ [])

@spec generate_from_resource(module(), [option()]) :: term()

Generates a function config list from an Ash resource.

Same as generate/2 but explicitly for resource modules.

Parameters

  • resource — An Ash resource module
  • opts — Same options as generate/2

Examples

AshPhoenixGenApi.JsonConfig.generate_from_resource(MyApp.Chat.DirectMessage, format: :map)

to_json(fun_configs, opts \\ [])

@spec to_json([map()], [option()]) :: String.t()

Converts a list of FunConfig structs to a JSON string.

Parameters

Examples

fun_configs = AshPhoenixGenApi.Resource.Info.fun_configs(MyApp.Chat.DirectMessage)
AshPhoenixGenApi.JsonConfig.to_json(fun_configs)
#=> "{\"send_direct_message\": {...}}"

to_map(fun_configs, opts \\ [])

@spec to_map([map()], [option()]) :: map()

Converts a list of FunConfig structs to the JSON config map format.

This is useful when you already have FunConfig structs and want to convert them to the map format without re-fetching from a domain/resource.

Parameters

Examples

fun_configs = AshPhoenixGenApi.Resource.Info.fun_configs(MyApp.Chat.DirectMessage)
AshPhoenixGenApi.JsonConfig.to_map(fun_configs)
#=> %{"send_direct_message" => %{...}, ...}

AshPhoenixGenApi.JsonConfig.to_map(fun_configs,
  descriptions: %{"send_direct_message" => "Send direct message"}
)