Stratus3D

Software Engineering, Web Development and 3D Design

Elixir 1.9 Configuration Merging

Elixir configuration can be placed in several different files. Config is often stored in config/config.exs and often config.exs is setup to load environment specific configuration files like config/test.exs, config/prod.exs, and so on. And now in Elixir 1.9 runtime configuration can be placed in config/releases.exs.

Configuration Evaluation

These various configuration files are evaluated at different times. config/config.exs is evaluated at compile time. Runtime configuration in config/releases.exs is evaluated inside the release at runtime.

Configuration Merging

If we use multiple configuration files configuration data is merged recursively. We can observe how this merging works by specifying multiple configurations in the same configuration file with the same root key and then loading the configuration values from it.

# Write this to a file named config_test.exs
import Mix.Config

config :config_test,
  param1: :some_value,
  param2: :another_value,
  nested_param: [keyword: :list]

config :config_test, :nested_param, [another: :keyword]

config :config_test,
  param1: :new_value

This file makes three config calls to set the configuration for the :config_test application. These config calls will be evaluated in the order they are defined in the file, but what will the final configuration be?

Loading the configuration using Config.Reader in the iex shell shows us the final values:

iex> Config.Reader.read!("config_test.exs")

[
  config_test: [
    param1: :new_value,
    param2: :another_value,
    nested_param: [keyword: :list, another: :keyword],
  ]
]

Config.Reader recursively merges the configurations in order until they are all combined.

The first config call defines the base configuration. The third changes the value of the :param1 key to :new_value. Even keys inside :nested_param keyword list get merged with the existing keyword list. We can also see that the whole configuration itself is just a set of nested keyword lists.

Conclusion

Elixir merges configuration spread across multiple files in a reasonable way, and makes it easy to combine configuration from config/config.exs, config/releases.exs, and any other file containing configuration data without having to duplicate any of the keys and values.

But remember, configuration files aren’t always best. Application configuration is global and therefore prevents libraries and applications from being used with different configurations in the same release. Avoiding configuration files entirely is usually the best approach for library applications.

Another important change related to configuration is that mix new will no longer generate a config/config.exs file. Relying on configuration is undesired for most libraries and the generated config files pushed library authors in the wrong direction.