Skip to content

Using viper for multiple environment

Viper is a golang library which is used to read env variables from config files. Also it presents a lot of functionality such as watching file changes, reload environment.

To use it, to be first we should create a .env file in main folder directory and assign

APP_ENV=development

and then create a config folder and create three environment json files.

test.json

{
  "host": "test",
  "port": "8080",
  "enabled": false
}

development.json

{
  "host": "development",
  "port": "8080",
  "enabled": false
}

production.json

{
  "host": "production",
  "port": "8080",
  "enabled": false
}

and create config.go file in config folder

package config

import (
	"fmt"
	"log"

	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
)

//Config is main viper pointer
var Config, env, test, development, production *viper.Viper

//setEnv assigns environment's viper instance to Config
func setEnv() {
	switch env.Get("APP_ENV") {
	case "development":
		Config = development
	case "test":
		Config = test
	case "production":
		Config = production
	default:
		Config = development
	}
}

//createInstance initalizes all environment variables
func createInstance(file string) *viper.Viper {
	v := viper.New()

	if file != ".env" {
		v.SetConfigFile(fmt.Sprintf("./config/%v.json", file))
	} else {
		v.SetConfigFile(file)
	}

	if err := v.ReadInConfig(); err != nil {
		log.Fatalf("Error reading config file, %s", err)
		return nil
	}

	v.WatchConfig()
	v.OnConfigChange(func(e fsnotify.Event) {
		fmt.Println("Config file changed:", e.Name)

		if e.Name == ".env" {
			setEnv()
		}
	})

	return v
}

//New is
func New() {
	env = createInstance(".env")
	development = createInstance("development")
	test = createInstance("test")
	production = createInstance("production")
	setEnv()
}
We can use Config instance in main.go file as below
func init() {
	config.New()
}

func main() {
	for {
		fmt.Println(config.Config.AllSettings())
		time.Sleep(1 * time.Second)
	}
}
if you change the .env or config files, can see change on Config instance and then can adjust your environment according to change.
(This may not be the best path to use environment files, if you have, you can write as comment. I’d appreciate.)
Published inGolang

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *