Phoenix application configuration

Deankinyua

Deankinyua

2 hours ago

The config folder plays a pivotal role in any phoenix application. Its constituents are normally config.exs, dev.exs, prod.exs, runtime.exs and test.exs. But what is the purpose of these files and how can you benefit from using them? The observation that I made after looking at these files for the first time is that they all have the .exs extension. This means that these files are scripts and the thing with scripts is that they are written to be invoked once and are not compiled. In other words, you don’t put application logic that is intended to be invoked frequently in these files.

So what can you put in these files? The answer lies in the name : Application Configuration. Environment-specific configuration can be set in the dev, prod and test files. That’s why tests that require the database do not persist changes after they are done; the test database environment uses a sandbox.

Take this example:

  @spec upload_file(filepath(), content_type()) :: {:ok, url()} | {:error, reason()}
  def upload_file(filepath, content_type),
    do: impl().upload_file(filepath, content_type)

  defp impl, do: Application.get_env(:skeptic_bot, :storage_provider, TigrisStorageProvider)

  ...
  # in test_helper.exs
  Mox.defmock(SkepticBot.Storage.MockStorageProvider, for: SkepticBot.Storage.StorageProvider)
  Application.put_env(:skeptic_bot, :storage_provider, SkepticBot.Storage.MockStorageProvider)

Here we are calling the impl function to which determine which storage provider we should use. Since we did not set anything, TigrisStorageProvider will be used. The thing is we don’t really want to upload anything during tests but we want to mock that behaviour. So in tests we set the storage provider to a mock implementation.

The config.exs and runtime.exs files are highly important. Kindly note that anything in a config file is evaluated at compile time unless it’s runtime.exs which is evaluated at runtime. This offers a pretty good solution if we want to change a variable depending on the current environment.

# config.exs
config :skeptic_bot,
  ecto_repos: [SkepticBot.Repo],
  generators: [binary_id: true, timestamp_type: :utc_datetime],
  related_episode_threshold: 0.688

Since config.exs is evaluated at compile time, we can use it as a module attribute:

  alias SkepticBot.Repo

  @episode_threshold Application.compile_env!(:skeptic_bot, :related_episode_threshold)