I'm using https://github.com/spf13/viper for configuration manager.
I've come across a use case where I've to use multiple config files .json, .env and environment variables in such a way.
- First all config from
.jsonis loaded - All non-empty variables from
.envis loaded. Empty variables on.envor non-existing variables wouldn't override values from.json - All non-empty variables from environment variables of platform is loaded. Empty variables on
.envor non-existing variables wouldn't override values from.json
For the same purpose, I tried with following snippet but doesn't seem to work.
package main
import (
"github.com/spf13/viper"
"log"
)
type ServerConfiguration struct {
Port int
}
type DatabaseConfiguration struct {
ConnectionUri string
}
type Configuration struct {
Server ServerConfiguration
Database DatabaseConfiguration
}
func main() {
var configuration Configuration
readFromConfigFile()
readFromEnvFile()
viper.AutomaticEnv()
err := viper.Unmarshal(&configuration)
if err != nil {
log.Fatalf("unable to decode into struct, %v", err)
}
log.Printf("database uri is %s", configuration.Database.ConnectionUri)
log.Printf("port for this application is %d", configuration.Server.Port)
}
func readFromConfigFile() {
viper.SetConfigName("config")
viper.AddConfigPath(".")
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("Error reading config file, %s", err)
}
}
func readFromEnvFile() {
viper.SetConfigName(".env")
viper.SetConfigType("env")
viper.AddConfigPath(".")
if err := viper.MergeInConfig(); err != nil {
log.Fatalf("Error reading config file, %s", err)
}
}
{
"database": {
"connectionUri": "test uri"
},
"server": {
"port": 8283
}
}
DATABASE_CONNECTION_URI="test2 uri"
Expected result:
2023/03/15 17:07:42 database uri is test2 uri
2023/03/15 17:07:42 port for this application is 8283
Actual result:
2023/03/15 17:07:42 database uri is test uri
2023/03/15 17:07:42 port for this application is 8283
I tried with the suggestion mentioned here but didn't help
Multiple config files with go-viper
Is it possible to attain as mentioned? If so, how could I achieve the functionality
github.com/spf13/viperfits your requirement perfectly.The issue here is that the key in
.envis incorrect. The default key delimiter is.(see the source code). So the key should beDATABASE.CONNECTIONURI. Here is the corrected configuration (please note that_inCONNECTION_URIshould be removed too):