/confex

Useful helper to read and use application configuration from environment variables.

Primary LanguageElixirMIT LicenseMIT

Confex

Deps Status Hex.pm Downloads Latest Version License Build Status Coverage Status Ebert

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.

Installation

It's available on hex.pm and can be installed as project dependency:

  1. Add confex to your list of dependencies in mix.exs:
```elixir
def deps do
  [{:confex, "~> 1.4.1"}]
end
```
  1. Ensure confex is started before your application:
```elixir
def application do
  [applications: [:confex]]
end
```

Usage

  1. 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}`
  1. 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"]
```
  1. 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.

  1. 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.

Configuration priorities

By using Confex macro in your module, you allow to provide compile-time defaults for it.

  1. Declare module
```elixir
defmodule MyModule do
  use Confex
end
```
  1. 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.

Helpful links