Location>code7788 >text

Viper: A Powerful Go Configuration Parsing Library

Popularity:172 ℃/2024-08-20 08:02:52

1 Introduction

Viperis a complete configuration solution for Go applications. It is designed to work within applications and can handle all types of configuration requirements and formats. Currently Star 26.6k, it supports the following features:

  • Setting default values
  • Reads configuration information from configuration files in JSON, TOML, YAML, HCL, envfile, and Java properties formats.
  • Real-time monitoring and re-reading of configuration files (optional)
  • Read from environment variable
  • Read and monitor configuration changes from a remote configuration system (etcd or Consul)
  • Reading Configuration from Command Line Parameters
  • Read configuration from buffer
  • explicit configuration value

2 Usage in Golang Projects

2.1 Installing Viper in go

# Enter the following command in the terminal
ArchitePlus@MacBook-Air % go get /spf13/viper

2.2 Preparation of a generic configuration file

Because it can support multiple configuration file formats, including JSON, TOML, YAML, HCL, INI, envfile and Java attribute files, it is convenient for developers to choose the appropriate format according to the needs of the project.
We'll use yaml as an example.

Create aconfFolders, add subfoldersfilesand then add the following, in which you can put some basic, generic configuration information.

app: # Basic application configuration
  env: local # Environment name
  port: 8888 # Service listening port number
  app_name: traffic-demo # app name
  app_url: http://localhost # Application access address


MySQL: # MySQL configuration
  host: 127.0.0.1 # MySQL host address
  port: 3306 # MySQL port number
  user: root # MySQL username
  password: <PASSWORD>
  db_name: traffic # MySQL database name

As you can see, we have two pieces of configuration information, one for app and one for MySQL.

2.3 Writing user-defined configuration files

There are also some user-defined configuration files (there may be more than one), which need to be distinguished according to the different runtime environments (local, dev, beta, prod). Therefore, we will use theconfig/files/Create four folders belowlocaldevbetaprod Four folders, each with afile, when When the value of the file is changed, the file read is also changed, the following is the information of local

white_list.
  user_id: # list of users
  - 063105015
  - 063105024
  - 063105028
  request_path: # Access path
  - /api/v1/users
  - /api/v1/ops

2.4 Structures for Configuration Mapping

We need a configuration structure (entity object) to map these two configurations, so that it's easy to call them later.
existconfAdd subfolders under the foldermodelwhich holds the structure for parsing the mapping.and afile, which reads as follows:

2.4.1

package config

// Configuration file parsing summary
type Configuration struct {
	App App `mapstructure:"app" json:"app" yaml:"app"`
	MYSQL MYSQL `mapstructure:"mysql" json:"mysql" yaml:"mysql"`
}

// Configuration file parsing:app
type App struct {
	Env string `mapstructure:"env" json:"env" yaml:"env"`
	Port string `mapstructure:"port" json:"port" yaml:"port"`
	AppName string `mapstructure:"app_name" json:"app_name" yaml:"app_name"`
	AppUrl string `mapstructure:"app_url" json:"app_url" yaml:"app_url"`
}

// Configuration file parsing:mysql
type MYSQL struct {
	Host string `mapstructure:"host" json:"host" yaml:"host"`
	Port string `mapstructure:"poet" json:"port" yaml:"port"`
	User string `mapstructure:"user" json:"user" yaml:"user"`
	Password string `mapstructure:"password" json:"password" yaml:"password"`
	DbName string `mapstructure:"db_name" json:"db_name" yaml:"db_name"`
}

2.4.2

package config

type Custom struct {
	WhiteList whiteList `mapstructure:"white_list" json:"white_list" yaml:"white_list"`
}

// Configuration file parsing summary
type whiteList struct {
	UserId []string `mapstructure:"user_id" json:"user_id" yaml:"user_id"`
	RequestPath []string `mapstructure:"request_path" json:"request_path" yaml:"request_path"`
}

2.5 Creating Global Global Variables Explained

Create a newglobal/ file, defines the Application structure, which is used to store some variables at the start of the project, so that they can be easily called.
For now, we'll put the viper structure and the Configuration structure in, and we'll add the rest of the configuration information later.

package global

import (
	"/spf13/viper"
	config "/config/model"
)

// Define a globalApplication
type Application struct {
	ConfigViper *
	Config
	Custom
}

// initializationApplication
var App = new(Application)

2.5 Key Steps: Structure Mapping Logic

The configuration file has to be mapped to a structure so that the configuration data can be extracted, this side creates thebootstrap/ file, which serves as a carrier for the core parsing code, is as follows (the explanation in the code is clear enough):

package bootstrap

import (
"fmt"

"/fsnotify/fsnotify"
"/spf13/viper"
"/global"
)

// configAssemble is a generic function that assembles the configuration file and returns the pointer
//
// Parameters:
//
// configPath string - The path of the configuration file.
// viperStruct T - the structure to receive the configuration file.
//
// Return value:
//
// * - pointer
func configAssemble[T any](configPath string, viperStruct T) * {
// Initialize viper
v := ()
// Configuration file address
(configPath)
// Configuration file type, yaml
("yaml")
if err := (); err ! = nil {
panic(("read config failed: %s \n", err))
}

// Listen to the config file
()
(func(in ) {
("config file changed:", )
// Reload the configuration &
if err := (viperStruct); err ! = nil {
(err)
}
})
// Assign the configuration to the global variable &
if err := (viperStruct); err ! = nil {
(err)
}

return v
}

// InitializeConfig initializes the configuration function
func InitializeConfig() {
// Global application file configuration path, this is the address of our specific global config file
config := "conf/files/"
configAssemble(config, &)

// User-defined configuration (loads different config files for different environments)
customConfig := ("%s%s%s", "conf/files/", , "/")
configAssemble(customConfig, &)

}

2.6 The overall document structure is as follows

image

2.7 Operational results

The code is as follows:

package main

import (
	"fmt"
	"/global"
)

// main Functions are entry points to programs
func main() {

    ()
    ("Traffic Service Started...!")

	var globalCong =
	("globalCong: %+v\n", globalCong)
	var customCong =
	("customCong: %+v\n", customCong)
}

The effect is as follows:
image

3 Summary

Viper is a powerful, concise, and easy-to-use Go configuration library that helps developers easily manage application configuration and provides flexible access to the