Manage config in Golang to get variables from file and env variables
If we want to implement the best practices for manage our conf files. So getting variables from a conf file, and from the environment as well. But many developers does not want to manage 2 repository of information. They are used to work with only one config file. So in order to help those who don’t want to manage 2 repositories …
We can scaffold a project like :
main.go
config
|- config.development.json
|- config.production.json
On our main.go (or in a config.go dedicated to manage all configuration)
We should have a struct representing our configuration
type Configuration struct {
Port int
Static_Variable string
Connection_String string
}
On our json file we have a json, describing our configurations key/value :
{
"Port": 8080
"Static_Variable": "static"
}
we will also have the connection_string, but this one will be on the environment variables.
- So we have to get information from the json :
//filename is the path to the json config file
file, err := os.Open(filename) if err != nil { return err }
decoder := json.NewDecoder(file)
err = decoder.Decode(&configuration)
if err != nil { return err }
- and from the environment variables
configuration.Connection_String = os.Getenv("Connection_String")
If you don’t want to manage it by yourself, you can use gonfig or viper.
using gonfig
Gonfig will be useful to:
- have a static configuration context allowing you to have all the configuration everywhere in your app.
- have a generic way to get all env variables define in your struct.
So in order to use gonfig :
$ go get github.com/tkanos/gonfig
then you just have to define your struct
type Configuration struct {
Port int
Static_Variable string
Connection_String string
}
and send the filename and the struct to gonfig :
configuration := Configuration{}
err := gonfig.GetConf("path/to/myjonfile.json", &configuration)
So now we are able to manage conf like if we had only one config source.
fmt.Println(configuration.Port);
using Viper
go get github.com/spf13/viper
On your code you will need to declare your variables
var (
Port string
)
Viper will be able to read in a toml file, or in the env variables, so if you want to have a config file for your Development environment, but use the env vars, for Production, you can write a code like :
if os.Getenv("ENVIRONMENT") == "DEV" {
viper.SetConfigName("config")
viper.SetConfigType("toml")
viper.AddConfigPath(filepath.Dir(dirname))
viper.ReadInConfig()
} else { viper.AutomaticEnv() }
And then to init your variable :
// To add a default value :
viper.SetDefault("APP_PORT", "8080")
//To get from the toml file or env var
Port = viper.GetString("APP_PORT")