confex v3.2.0 Confex

Confex simplifies reading configuration at run-time with adapter-based system for resolvers.

Configuration tuples

Whenever there is a configuration that should be resolved at run-time you need to replace it’s value in config.exs by Confex configuration type. Common structure:

  @type fetch_statement :: {adapter :: atom() | module(), value_type :: value_type, key :: String.t, default :: any()}
                         | {value_type :: value_type, key :: String.t}
                         | {key :: String.t, default :: any()}
                         | {key :: String.t}

If value_type is set, Confex will automatically cast it’s value. Otherwise, default type of :string is used.

Confex TypeElixir TypeDescription
:stringString.tDefault.
:integerInteger.tParse Integer value in string.
:floatFloat.tParse Float value in string.
:booleantrue or falseCast ‘true’, ‘1’, ‘yes’ to true; ‘false’, ‘0’, ‘no’ to false.
:atomatom()Cast string to atom.
:modulemodule()Cast string to module name.
:listList.tCast comma-separated string (1,2,3) to list ([1, 2, 3]).

Examples:

  • var - any bare values will be left as-is.
  • {:system, "ENV_NAME", default} - read string from “ENV_NAME” environment variable or return default if it’s not set or has empty value.
  • {:system, "ENV_NAME"} - same as above, with default value nil.
  • {:system, :integer, "ENV_NAME", default} - read string from “ENV_NAME” environment variable and cast it to integer or return default if it’s not set or has empty value.
  • {:system, :integer, "ENV_NAME"} - same as {:system, :integer, "ENV_NAME", nil}.
  • {{:via, MyAdapter}, :string, "ENV_NAME", default} - read value by key “ENV_NAME” via adapter MyAdapter or return default if it’s not set or has empty value.
  • {{:via, MyAdapter}, :string, "ENV_NAME"} - same as above, with default value nil.

Adapters

:system - read configuration from system environment; :system_file - read file path from system environment and read configuration from this file.

You can create adapter by implementing Confex.Adapter behaviour with your own logic.

Link to this section Summary

Functions

Returns the value for key in app’s environment in a tuple. This function mimics Application.fetch_env/2 function

Returns the value for key in app’s environment. This function mimics Application.fetch_env!/2 function

Returns the value for key in app’s environment in a tuple. This function mimics Application.get_env/2 function

Recursively merges configuration with default values

Link to this section Types

Link to this type configuration_tuple()
configuration_tuple ::
  {value_type :: Confex.Type.t, key :: String.t, default :: any} |
  {value_type :: Confex.Type.t, key :: String.t} |
  {key :: String.t, default :: any} |
  {key :: String.t}

Link to this section Functions

Link to this function fetch_env(app, key)
fetch_env(app :: Application.app, key :: Application.key) ::
  {:ok, Application.value} |
  :error

Returns the value for key in app’s environment in a tuple. This function mimics Application.fetch_env/2 function.

If the configuration parameter does not exist or can not be parsed, the function returns :error.

Example

iex> :ok = System.put_env("MY_TEST_ENV", "foo")
...> Application.put_env(:myapp, :test_var, {:system, "MY_TEST_ENV"})
...> {:ok, "foo"} = Elixir.Confex.fetch_env(:myapp, :test_var)
{:ok, "foo"}

iex> :ok = System.delete_env("MY_TEST_ENV")
...> Application.put_env(:myapp, :test_var, {:system, :integer, "MY_TEST_ENV", "bar"})
...> {:ok, "bar"} = Elixir.Confex.fetch_env(:myapp, :test_var)
{:ok, "bar"}

iex> :ok = System.delete_env("MY_TEST_ENV")
...> Application.put_env(:myapp, :test_var, {:system, :integer, "MY_TEST_ENV"})
...> :error = Elixir.Confex.fetch_env(:myapp, :test_var)
:error

iex> :ok = System.put_env("MY_TEST_ENV", "foo")
...> Application.put_env(:myapp, :test_var, {:system, :integer, "MY_TEST_ENV"})
...> :error = Elixir.Confex.fetch_env(:myapp, :test_var)
:error

iex> Application.put_env(:myapp, :test_var, 1)
...> {:ok, 1} = Elixir.Confex.fetch_env(:myapp, :test_var)
{:ok, 1}
Link to this function fetch_env!(app, key)
fetch_env!(app :: Application.app, key :: Application.key) ::
  Application.value |
  no_return

Returns the value for key in app’s environment. This function mimics Application.fetch_env!/2 function.

If the configuration parameter does not exist or can not be parsed, raises ArgumentError.

Example

iex> :ok = System.put_env("MY_TEST_ENV", "foo")
...> Application.put_env(:myapp, :test_var, {:system, "MY_TEST_ENV"})
...> "foo" = Elixir.Confex.fetch_env!(:myapp, :test_var)
"foo"

iex> :ok = System.delete_env("MY_TEST_ENV")
...> Application.put_env(:myapp, :test_var, {:system, :integer, "MY_TEST_ENV", "bar"})
...> "bar" = Elixir.Confex.fetch_env!(:myapp, :test_var)
"bar"

iex> :ok = System.delete_env("MY_TEST_ENV")
...> Application.put_env(:myapp, :test_var, {:system, :integer, "MY_TEST_ENV"})
...> Elixir.Confex.fetch_env!(:myapp, :test_var)
** (ArgumentError) can't fetch value for application :myapp, can not resolve key MY_TEST_ENV value via adapter Elixir.Confex.Adapters.SystemEnvironment

iex> :ok = System.put_env("MY_TEST_ENV", "foo")
...> Application.put_env(:myapp, :test_var, {:system, :integer, "MY_TEST_ENV"})
...> Elixir.Confex.fetch_env!(:myapp, :test_var)
** (ArgumentError) can't fetch value for application :myapp, can not cast "foo" to Integer

iex> Application.put_env(:myapp, :test_var, 1)
...> 1 = Elixir.Confex.fetch_env!(:myapp, :test_var)
1
Link to this function get_env(app, key, default \\ nil)

Returns the value for key in app’s environment in a tuple. This function mimics Application.get_env/2 function.

If the configuration parameter does not exist or can not be parsed, returns default value or nil.

Example

iex> :ok = System.put_env("MY_TEST_ENV", "foo")
...> Application.put_env(:myapp, :test_var, {:system, "MY_TEST_ENV"})
...> "foo" = Elixir.Confex.get_env(:myapp, :test_var)
"foo"

iex> :ok = System.delete_env("MY_TEST_ENV")
...> Application.put_env(:myapp, :test_var, {:system, :integer, "MY_TEST_ENV", "bar"})
...> "bar" = Elixir.Confex.get_env(:myapp, :test_var)
"bar"

iex> :ok = System.delete_env("MY_TEST_ENV")
...> Application.put_env(:myapp, :test_var, {:system, :integer, "MY_TEST_ENV"})
...> nil = Elixir.Confex.get_env(:myapp, :test_var)
nil

iex> :ok = System.delete_env("MY_TEST_ENV")
...> Application.put_env(:myapp, :test_var, {:system, :integer, "MY_TEST_ENV"})
...> "baz" = Elixir.Confex.get_env(:myapp, :test_var, "baz")
"baz"

iex> :ok = System.put_env("MY_TEST_ENV", "foo")
...> Application.put_env(:myapp, :test_var, {:system, :integer, "MY_TEST_ENV"})
...> nil = Elixir.Confex.get_env(:myapp, :test_var)
nil

iex> nil = Elixir.Confex.get_env(:myapp, :does_not_exist)
nil

iex> Application.put_env(:myapp, :test_var, 1)
...> 1 = Elixir.Confex.get_env(:myapp, :test_var)
1
Link to this function merge_configs!(config, defaults)
merge_configs!(config :: Keyword.t | Map.t, defaults :: Keyword.t | Map.t) ::
  Keyword.t |
  Map.t

Recursively merges configuration with default values.

Both values must be either in Keyword or Map structures, otherwise ArtumentError is raised.

Example

iex> [b: 3, a: 1] = Elixir.Confex.merge_configs!([a: 1], [a: 2, b: 3])
[b: 3, a: 1]

iex> %{a: 1, b: 3} = Elixir.Confex.merge_configs!(%{a: 1}, %{a: 2, b: 3})
%{a: 1, b: 3}

iex> Elixir.Confex.merge_configs!(%{a: 1}, [b: 2])
** (ArgumentError) can not merge default values [b: 2] with configuration %{a: 1} because their types mismatch, expected both to be either Map or Keyword structures