This is helper module that provides a nice way to read environment configuration at runtime. It's inspired by Phoenix {:system, value}
definition for HTTP port.
It's available on hex.pm and can be installed as project dependency:
- Add
confex
to your list of dependencies inmix.exs
:
```elixir
def deps do
[{:confex, "~> 1.4.1"}]
end
```
- Ensure
confex
is started before your application:
```elixir
def application do
[applications: [:confex]]
end
```
- Defining configurations
Define your configuration in config.ex of your application.
```elixir
config :ap_cfpredictor, AssetProcessor.AMQP.Producer,
queue: [
name: {:system, "OUT_QUEUE_NAME", "MyQueueOut"},
error_name: {:system, "OUT_ERROR_QUEUE_NAME", "MyQueueOut.Errors"},
routing_key: {:system, "OUT_ROUTING_KEY", ""},
durable: {:system, "OUT_DURABLE", false},
port: {:system, :integer, "OUT_PORT", 1234},
],
```
List of supported formats:
* `var` - any bare values will be left as-is.
* `{:system, "ENV_NAME", default}` - read string from system ENV, return `default` if it's nil.
* `{:system, "ENV_NAME"}` - read string from system ENV, returns `nil` if environment variables doesn't exist.
* `{:system, :string, "ENV_NAME", default}` - same as `{:system, "ENV_NAME", default}`.
* `{:system, :string, "ENV_NAME"}` - same as `{:system, "ENV_NAME"}`.
* `{:system, :integer, "ENV_NAME", default}` - same as `{:system, "ENV_NAME", default}`, but will convert value to integer if it's not `nil`. Default value type **will not** be changed.
* `{:system, :integer, "ENV_NAME"}` - same as `{:system, :integer, "ENV_NAME", nil}`.
* `{:system, :boolean, "ENV_NAME", default}` - same as `{:system, "ENV_NAME", default}`, but will convert value to boolean if it's not `nil`. Default value type **will not** be changed.
* `{:system, :boolean, "ENV_NAME"}` - same as `{:system, :boolean, "ENV_NAME", nil}`.
* `{:system, :atom, "ENV_NAME"}`
* `{:system, :atom, "ENV_NAME", :default}`
* `{:system, :module, "ENV_NAME"}`
* `{:system, :module, "ENV_NAME", Default}`
- Reading configuration
Read string values:
```elixir
iex> Confex.get(:myapp, MyKey)
"abc"
```
Read integer values:
```elixir
Confex.get(:myapp, MyIntKey)
123
```
Read map values:
```elixir
Confex.get(:myapp, MyIntKey)
[a: 123, b: "abc"]
```
- Using macros
Confex is supplied with helper macros that allow to attach configuration to specific modules of your application.
```
defmodule Connection do
use Confex, otp_app: :myapp
end
```
Connection
in this case will read configuration from app :myapp
with key Connection
. Also it will provide helper function config/0
that will return values at run-time.
- Configuration validation
Sometimes you want to validate configuration, for this you can define def validate_config(config)
method, that will be called on each config/0
usage.
Confex doesn't give opinions on a validator to be used in overrided methods.
By using Confex macro in your module, you allow to provide compile-time defaults for it.
- Declare module
```elixir
defmodule MyModule do
use Confex
end
```
- Provide defaults when using it
```elixir
use MyModule,
otp_all: :myapp,
host: {:system, "HOST"}
```
This configs will overwritten by any configuration that you have in your application env.