Extendible config values? Where multiple apps can append values to the same list?

I’m working on an umbrella app and it brought up an interesting use-case… I’d like to define a map in my config. But the trick is that each app may define its own key/values that get appended to that map. For example:

# AppOne
config :myapp, :my_map, %{x: "foo"}

And then in AppTwo:

# AppTwo
config :myapp, :my_map, %{y: "bar"}

The goal is that the umbrella app can have access to the merged map, e.g.

%{x: "foo", y: "bar"}

Is something like this even possible? Or is it a red-flag that I’m pushing the river and I should re-think my approach?

2 Likes

From Elixir v1.6 and Phoenix v1.4 we recommend all configuration for apps that are not in the umbrella to be in the config/config.exs at the umbrella root, exactly because configuration is shared. In other words, instead of defining subset of the config per app, you should definie the whole config :myapp, :my_map at once at the root.

3 Likes

Thanks José! That’s the conclusion I was reaching as well. How does that work when you are developing the applications separately? For example, it’s nice for an organization to split off development of smaller apps to different teams. Each app would require that this particular configuration value be defined… do those values get overridden when the application is used in the umbrella?

When you’re developing the apps without using an umbrella structure configuration is not merged at all. It’s always just the current apps configuration which is used, while the configuration of dependencies is ignored. The same stays true in umbrellas in that you cannot have configuration “merged”. You should think of it as one single set of configuration, which happens to be strategically spread over multiple files.

Sorry I’m unclear here… so if I have “AppOne” with its apps/appone/config/config.exs config that defines something critical like config :appone, :foo, "bar", when I include it in an umbrella, that config file is ignored? I am using the following in my umbrella’s config.exs:

import_config "../apps/*/config/config.exs"

If I’m understanding you correctly, it sounds like that may not be a great idea… instead I should manually copy all the necessary configuration into the umbrella’s config.exs ?

If you are using an umbrella, all configurations are merged together, so keeping them separate may give the impression that each app can configure a dependency in their own way, but that’s not true. So if you have multiple teams, it is even more important to keep all of the configuration at the root, to make conflicts more obvious. If that is not enough, it may be time to break the umbrella apart.

2 Likes

So would you recommend NOT using this line in your umbrella’s config.exs:

and instead list out the specific configuration that all apps in the umbrella require?

If I am understanding you correctly, I like it: that would allow us to specify configuration values when developing an application in isolation and then use a different configuration value when the application gets used inside the umbrella.

You cannot develop an application as a standalone package and within an umbrella at the same time without some hassle. There are also things in the mix.exs, which are different for standalone mix projects vs. umbrella ones.

That line is fine but we recommend for each apps/*/config/config.exs to only configure each child application and nothing more. Everything else goes to the rooot.

1 Like

Hmm… we’ve been doing stand-alone development and then running apps in the umbrella without problems. Testing and onboarding new devs has all been easier when working this way.