preface

In the daily development, it is necessary to read a variety of configuration files, such as JSON, YML, properties, ENV, INI and so on. Today we will introduce how to read yML configuration files in Go, and read different configurations according to different environments

To prepare

First we need to prepare a.yml configuration file, here is a brief post (named app.yml) :

# app.yml
app:
  id: 1000
  name: juejin
db:
  name: test
  username: root
  password: 123456
  port: 3306
ticks:
  - 100
  - 200
  - 300
maps:
  1: one
  2: two
  3: three
Copy the code

Define the structure

Once the configuration file is defined, we need to define the structure of the GO language according to the structure of the configuration file:

type App struct {
	Id   int
	Name string
}

type DB struct {
	Name     string
	Username string
	Password string
	Port     int
}

type AppConfig struct {
	App   App
	DB    DB
	Ticks []int
	Maps  map[int]string
}
Copy the code

read

Next, we start to read the YML configuration data. Here we need to use a dependent library: github.com/spf13/viper to read our YML file. The specific steps are as follows:

func main(a) {
	wd, err := os.Getwd()
	iferr ! =nil {
		panic(err)
	}
	c := &AppConfig{}
	v := viper.New()
	v.SetConfigName("app") // This is the file name we configured above, no need for suffix
	v.AddConfigPath(wd) // Directory path of the file
	v.SetConfigType("yml") // Here is the file format type
	err = v.ReadInConfig()
	iferr ! =nil {
		log.Fatal("Failed to read configuration file:", err)
		return
	}
	configs := v.AllSettings()
	for k, val := range configs {
		v.SetDefault(k, val)
	}
	err = v.Unmarshal(c) // Deserialize to the structure
	iferr ! =nil {
		log.Fatal("Error reading configuration:", err)
	}
}
Copy the code

Multi-environment Configuration

For example, the configuration of the development environment and test environment may be a little different, but it is too troublesome to change the default configuration file every time, but we can set the environment variable to fit the configuration reading of multiple environments. The final code is:

func main(a) {
	wd, err := os.Getwd()
	iferr ! =nil {
		panic(err)
	}
	c := &AppConfig{}
	v := viper.New()
	v.SetConfigName("app")
	v.AddConfigPath(wd)
	v.SetConfigType("yml")
	err = v.ReadInConfig()
	iferr ! =nil {
		log.Fatal("Failed to read configuration file:", err)
		return
	}
	configs := v.AllSettings()
	for k, val := range configs {
		v.SetDefault(k, val)
	}
	pa := os.Getenv("PROFILE_ACTIVE") // Reads the name of the current effective configuration set in the environment variable
	ifpa ! ="" {
		v.SetConfigName(pa)
		v.AddConfigPath(wd)
		v.SetConfigType("yml")
		err = v.ReadInConfig()
		iferr ! =nil {
			return
		}
	}
	err = v.Unmarshal(c)
	iferr ! =nil {
		log.Fatal("Error reading configuration:", err)
	}
}
Copy the code

Afterword.

The above methods are basic simple business configuration, and viper dependencies also support more configuration reading, such as: JSON, TOML, YAML, HCL, ENvFile and Java Properties;

😊 Finally, thank you for reading, thank you!