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")

Links

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade