How to access config key in package?

The way most libraries do this is to let the user configure it using their own config.exs. The config.exs in the library is only used when developing the library.

In your library you fetch the config, if there is none set by the user you use a default.

Example: https://github.com/thoughtbot/bamboo/blob/d6ff3e74de9e4365b0c7d326bf4323b7300f64ee/lib/bamboo/adapters/mailgun_adapter.ex#L133

2 Likes

Bitwalker made a fantastic little helper at https://gist.github.com/bitwalker/a4f73b33aea43951fe19b242d06da7b9 that lets you get a configuration from the config file, or from an environment variable, or a default, all in one call. Just save that Gist as a Config.ex in your project (Bitwalker really should make that into a library, small though it may be, he still should). Just use it like:

some_config = Config.get(:my_application, :the_config_key, "Default value")
2 Likes

It was my intention to actually to avoid:

  • Spreading @config_key_default all over my code
  • Moving the config from config.exs just for the sake of it

:thumbsup: for the info that config/config.exs in libraries is actually only intended for use in lib development

I used flasked for reading at startup time from System.get_env(), but getting Bitwalkers helper into elixir-lang/elixir would be really nice.

1 Like

I ran into a similar issue as @PatNowak when including a local dependency (proj_a) in a project I am working on (proj_b).

In proj_a I am using Application.get_env(:proj_a, :some_key) for mocking as detailed by José here.

This thread was very informative, but it made me question José suggestion as now any project that includes proj_a will also have to add configuration settings to make sure that Application.get_env(:proj_a, :some_key) is correctly defined.

This seems like it can lead to confusion and may be error prone.

1 Like

If you are writing a library then instead of:

  @twitter_api Application.get_env(:my_app, :twitter_api)

You could write:

  @twitter_api Application.get_env(:my_app, :twitter_api, MyApp.Twitter.HTTPClient)

So that when the configuration is not explicitly set there is a sensible default (the production config).

On a more meta note, the confusion around this (and I’ve had my own share of confusion) seem to indicate that application configuration could use a more prominent section in the Elixir guides. Currently it is at the bottom of this page and doesn’t cover the issue of end-user vs library applications at all:
https://elixir-lang.org/getting-started/mix-otp/distributed-tasks-and-configuration.html

4 Likes