I'm having a discussion regarding aero and config best practices with a few colleagues
I can see in your README that you suggest to have functions like
(defn something-enabled [config] (get-in config [...])
I kind of prefer to think about configuration as to a global constant map, so instead of passing it around everywhere I just have do calls like
(config/value :nested :key)
and then do some simple caching to not reload the config too many times in prod
I understand that in theory passing around the config map is more functional, but at the same time, if we do want to pass different arguments, we just use anyway a #profile
in the aero config
anyway the question is just, is that what you actually do to pass around the config everywhere and have a function for every configuration value?
Neither 😛
We've primarily migrated to integrant as our strategy for the config, and store our integrant system in the config.edn. Then the integrant system can #ref
config to itself.
You can see this happening in Edge https://github.com/juxt/edge/blob/master/examples/tutorial.vent/src/config.edn
For example the builder has separate config based on the profile: https://github.com/juxt/edge/blob/master/examples/tutorial.vent/src/config.edn#L64-L65 but could also use #ref
.
Notable is the granularity, each web endpoint has it's own component, so gets the granularity of config it needs. e.g. https://github.com/juxt/edge/blob/master/examples/tutorial.vent/src/config.edn#L3
We have applied this pattern to component as well, so it seems general. Although integrant is the easiest combo we've seen thus far.
ah cool thanks
can't speak much to your exact use-case, but I definitely prefer parameterized configuration over external global reads, it means that the tests can be run in parallel and functions can be composed by default (i.e. not requiring refactoring to make a -config variant).