When working with environment variables, it’s a good pattern to store them in Elixir’s config files (Config
).
However, it’s up to the developer to choose where to store those values in the configuration.
Nothing stops us from writing this perfectly fine code:
# config/runtime.exs
config :my_app, :third_party,
base_url: System.get_env("THIRD_PARTY_BASE_URL"),
secret_key: System.get_env("THIRD_PARTY_SECRET_KEY")
# lib/my_app/third_party.ex
defmodule MyApp.ThirdParty do
def fetch_data do
# Use base_url() and secret_key() here
end
defp base_url, do: Application.get_env(:my_app, :third_party)[:base_url]
defp secret_key, do: Application.get_env(:my_app, :third_party)[:secret_key]
end
The :third_party
atom in which we store our values is pretty arbitrary. We should take advantage of the fact that we can use a module name (which is basically an atom) as the configuration key.
This adds an extra meaning to our configuration. We’re saying “We want to configure X” by using X as the key instead of another atom that doesn’t represent anything:
# config/runtime.exs
-config :my_app, :third_party,
+config :my_app, MyApp.ThirdParty,
base_url: System.get_env("THIRD_PARTY_BASE_URL"),
secret_key: System.get_env("THIRD_PARTY_SECRET_KEY")
# lib/my_app/third_party.ex
defmodule MyApp.ThirdParty do
def fetch_data do
# Use base_url() and secret_key() here
end
- defp base_url, do: Application.get_env(:my_app, :third_party)[:base_url]
- defp secret_key, do: Application.get_env(:my_app, :third_party)[:secret_key]
+ defp base_url, do: Application.get_env(:my_app, __MODULE__)[:base_url]
+ defp secret_key, do: Application.get_env(:my_app, __MODULE__)[:secret_key]
end
Both examples are fine, but in my opinion the second one is a little bit better 🙂