Hi there,
I come from Node.js world, when we got the config module. This one allows to specify several configuration files, such as default.json, development.json and production.json. Depending of environment variable, we serve either dev or prod file, fallbacking on default.json for not specified values.
Can we achieve the same process with Viper?
I guess we can switch on correct configuration file using a test on environment variable and viper.SetConfigName method. But what about the fallback feature? Can we tell Viper to get them from a file instead of setting them manually via several SetDefault calls?
+1 for this - exactly what I am trying to do.
This could be done in the way @jpetitcolas has mentioned with different files or the framework Revel has implemented it in one file with [enviroments] defined - https://revel.github.io/manual/appconf.html
Would it make sense to wrap the viper.New() function in your application, so that the wrapper sets up the returned _viper_ object with correct paths, config name, etc. per parameters you feed to the wrapper?
Fallback, the way I understand it, may be trickier, but I am not sure I gather what you mean as a fallback correctly. Using SetDefault(key string, value interface{}) while iterating over AllSettings() map[string]interface{} to post settings read into one _viper_ object into another may be what you are looking for, but that is my assumption.
Regardless, I am not sure that the functionality belongs to inside the _viper_ library - it may or may not be common enough use case to warrant the inclusion - even assuming I correctly understood what you are trying to achieve.
I think the ability to set defaults from a file is important functionality, but it looks like this could be done with the recent MergeConfig functionality from #132.
Scoped configs are also desired in #148. However, we can already scope configs with Viper's sub-tree feature. Is there an environment/scope use case that sub-tree doesn't cover?
func init() {
// Set viper path and read configuration
viper.AddConfigPath(".")
if os.Getenv("ENV") == "PRODUCTION" {
viper.SetConfigName("config")
} else {
viper.SetConfigName("devconfig")
}
err := viper.ReadInConfig()
// Handle errors reading the config file
if err != nil {
log.Fatalln("Fatal error config file", err)
}
}
I do this and have two files "config.toml" and "devconfig.toml"
@jaipradeesh Thanks for the above example but I have not understood one thing. How os.Getenv("ENV") is returning different value per dev and production? When same code runs in dev and prod it must give different values. I am not getting that part. Response is appreciated. Thank you.
@MaruthiVSM You need to set the variable explicitly in the environment.
For anyone else trying to use viper in a manner similar to node-config: its very easily achievable with a couple of lines of viper code. This will get most of the features that node-config provides.
Closing as there is a solution.
Most helpful comment
I do this and have two files "config.toml" and "devconfig.toml"