“This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!”

Configuration files are very important in a project, especially how to read them efficiently. The most common way to get the contents of a file without using any three-party libraries is through file I/O, but after all, I just want to read a configuration file, which requires file manipulation, which is a bit cumbersome. In addition, files come in a variety of formats, and how to read the contents of files in different formats and environments can be a challenge. In this article, I describe four ways to read configuration files, depending on your requirements.

Introduction to four reading methods

Two of them stand out, including Viper and GoDotEnv, which have a wide audience. Viper has the most star on Github and more comprehensive documentation, followed by GoDotEnv. There are also two more niche lightweight models, including Gonfig and Go-Akka. See Github for an introduction to each.

go-akka

Currently Not Available!!

Making the conveyor belt

godotenv(Available)

A Go (golang) port of the Ruby dotenv project (which loads env vars from a .env file)

Making the conveyor belt

gonfig

gonfig is a lightweight Golang package for intergrating both JSON configs and enviornment variables into one config object.

Making the conveyor belt

viper(Available,Most stars)

Viper is heading towards v2 and we would love to hear what you would like to see in it.

Making the conveyor belt

Go-akka Practice

Configuration file config.yaml

port: 8081
debug: true
Copy the code

Parse configuration config.go

import "github.com/go-akka/configuration"
​
type Config struct {
    Port  uint16 `yaml:"port"`
    Debug bool   `yaml:"debug"`
    Raw   *configuration.Config
}
​
func (c *Config) parseConfig(path string) *Config {
    c.Raw = configuration.LoadConfig(path)
    c.Port = uint16(c.Raw.GetInt32("port", 8008))
    c.Debug = c.Raw.GetBoolean("debug", false)
    return c
}
Copy the code

Test config_test. Go

func TestConfig(t *testing.T) {
    assert.NotPanics(t, func() {
        cfg := new(Config).parseConfig("./cfg.yaml")
        fmt.Printf(" port=%d,debug=%t", cfg.Port, cfg.Debug)
    })
}
Copy the code

3. Godotenv Practice

Test the file.env

Key1=value1
Key2 =value2
Copy the code

Parse configuration config.go

func init() { if err := godotenv.Load("./.env"); err ! = nil { log.Fatal("Error loading .env file") } } func ReadEnv() { value1 := os.Getenv("Key1") value2 := os.Getenv("Key2") value3 := os.Getenv("Key3") if value1 == "" || value2 == "" { panic("load error") } Printf("key1=%s,key2=%s, key3=%s", value1, value2, value3)}Copy the code

The test file is config_test.go

func TestEnv(t *testing.T) {
    assert.NotPanics(t, func() {
        ReadEnv()
    })
}
Copy the code

Four, GONFIG practice

The configuration file

dev_config.json

{" DB_USERNAME ":" test ", "DB_PASSWORD" : "test", "DB_PORT" : "3306", "DB_HOST" : "127.0.0.1", "DB_NAME" : "test"}Copy the code

prd_config.json

{" DB_USERNAME ":" prd_test ", "DB_PASSWORD" : "prd_test", "DB_PORT" : "3306", "DB_HOST" : "127.0.0.1", "DB_NAME" : "prd_test" }Copy the code

Config parsing config.go

type Configuration struct { DB_USERNAME string DB_PASSWORD string DB_PORT string DB_HOST string DB_NAME string } func ParseConfig(params ... string) Configuration { configuration := Configuration{} env := "dev" if len(params) > 0 { env = params[0] } fName := fmt.Sprintf("./%s_config.json", env) if err := gonfig.GetConf(fName, &configuration); err ! = nil { panic(err) } return configuration }Copy the code

The test file is config_test.go

func TestConfig(t *testing.T) { assert.NotPanics(t, func() { fmt.Println("Dev Conf :") cfg := ParseConfig() fmt.Printf("userName=%s,password=%s,port=%s,host=%s,name=%s \n",  cfg.DB_USERNAME, cfg.DB_PASSWORD, cfg.DB_PORT, cfg.DB_HOST, cfg.DB_NAME) cfg = ParseConfig("prd") fmt.Printf("userName=%s,password=%s,port=%s,host=%s,name=%s \n", cfg.DB_USERNAME, cfg.DB_PASSWORD, cfg.DB_PORT, cfg.DB_HOST, cfg.DB_NAME) }) }Copy the code

V. Viper practice

Configuration file config.yml

server:
  port: 8080
​
database:
  dbname:
  dbuser: "dbuser"
  dbpassword: "dbpassword"
​
EXAMPLE_VAR: "variable from config.yml"
EXAMPLE_PATH: "path from config.yml"
Copy the code

Parse configuration config.go

type Configurations struct { Server ServerConfigurations Database DatabaseConfigurations EXAMPLE_PATH string EXAMPLE_VAR  string } // ServerConfigurations exported type ServerConfigurations struct { Port int } // DatabaseConfigurations exported type DatabaseConfigurations struct { DBName string DBUser string DBPassword string } func readConfig() { viper.SetConfigName("config") viper.AddConfigPath(".") viper.AutomaticEnv() viper.SetConfigType("yml") var configuration  Configurations if err := viper.ReadInConfig(); err ! = nil { fmt.Printf("Error reading config file, %s", err) } viper.SetDefault("database.dbname", "test_db") err := viper.Unmarshal(&configuration) if err ! = nil { fmt.Printf("Unable to decode into struct, %v", err) } fmt.Printf("reading using model:\n database=%s,port=%d,path=%s,var=%s \n", configuration.Database.DBName, configuration.Server.Port, configuration.EXAMPLE_PATH, configuration.EXAMPLE_VAR) fmt.Printf("reading without model:\n database=%s,port=%d,path=%s,var=%s \n", viper.GetString("database.dbname"), viper.GetInt("server.port"), viper.GetString("EXAMPLE_PATH"), viper.GetString("EXAMPLE_VAR")) }Copy the code

The test file is config_test.go

func TestConfig(t *testing.T) {
    assert.NotPanics(t, func() {
        readConfig()
    })
}
Copy the code

Six, summarized

Choose one of the four read-environment configuration practices according to your own circumstances. For production environments, use Viper and Godotenv, because it’s much more reliable to be well-trained, and never forget to include your environment variables in the.gitignore file.

github repo


Hey, man, don’t panic! Leave a like and comment. Welcome to gothing, the practical Go language column, to learn go hand in hand. Also welcome to pay attention to me, must do a long more good man.