Go provides a very simple API for reading json and yaml files. We can easily convert a json or yaml file into a Go structure, but if you read the configuration file directly in the project, this method is not good enough. The disadvantages are as follows:
In actual development, the configuration values of configuration items are different in different environments.
The above problem can be determined by different configuration files to read which configuration file in which environment, but there is another problem that in actual development, some configuration items are the same, and some are different. If the configuration file has a main configuration file, which stores the same configuration items for different environments, and there is also a configuration file that follows the environment, which stores the configuration items for different environments. Then, after reading the two configuration files, make a merge, and the result is the total configuration item information.
Some configuration items are required, and some configuration items have special values, such as email, mobile phone number, IP information, etc.
Let's see how gonfig solves this problem
- Install gonfig
go get /xiao-ren-wu/gonfig
- Create a new configuration directory in the project, write the corresponding configuration file, and add a go file to read the configuration file in the directory of the same level as the configuration directory
The file contains a common configuration.
conf-{{active}}.yaml
Stores different configuration information for different environments.
conf |- |- |- |
- use
go:embed
Load the configuration file into memory and callRead configuration files
package config import ( "model" "/xiao-ren-wu/gonfig" "embed" ) //go:embed *.yaml var confDir // Configuration struct of our configuration filetype AppConf struct { AppName string `yaml:"app-name" json:"app-name"` DB DBConf `yaml:"db" json:"db"` } type DBConf struct { Username string `yaml:"username" json:"username"` Password string `yaml:"password" json:"password"` } var conf Conf func Init() { if err := (confDir, &conf); err != nil { panic(err) } } func GetConf() *Conf { return &conf }
This completes the reading of configuration files in the project. Isn’t it very simple? The configuration format read at this time isconf-{{profile}}.yaml
andThe sum of
conf-{{profile}}.yaml
The properties defined inThe same, then
conf-{{profile}}.yaml
Whichever
Agree
gonfig
The reason for the simplicity of the API is that there are many constraints behind it. Only configurations that meet the constraints can be successfully read. The specific constraints are as follows:
The file name will be read by default with a prefix
conf
FilesThrough environment variables
profile
As the environment name, if not configured, the default dev.The program will look for
As the main configuration file,
conf-{{profile}}.yaml
As an environment-specific configuration file, then merge the file contentsif
conf-{{profile}}.yaml
Properties andThe properties in the
conf-{{profile}}.yaml
Whichever is.
Customize configuration files according to the project
Function signature
func Unmarshal(confDir ReadFileDir, v interface{}, ops ...Option) error
Provide a lot of configuration items for users to customize their needs. The specific configuration information is as follows:
Change the configuration file name prefix
FilePrefix(prefix string)
Change the read configuration file type
UnmarshalWith(uType UnmarshalType)
Change the read environment variable name
ProfileUseEnv(envName, defaultProfile string)
Customize the profile
ProfileFunc(f func() string)
Principles
gonfig
The implementation is also very simple, the core source code is as follows:
func Unmarshal(confDir ReadFileDir, v interface{}, ops ...Option) error { if v != nil && (v).Kind() != { return gonfig_error.ErrNonPointerArgument } var cs = &confStruct{ confPrefix: "conf", envName: "profile", defaultEnvValue: "dev", unmarshalType: Yaml, } = func() string { return getActiveProfile(, ) } for _, op := range ops { op(cs) } = () if err := loadConf(confDir, cs); err != nil { return err } // copy val v1 := ((v).Elem()).Interface() if err := fileUnmarshal(, v1, ); err != nil { return err } if len() == 0 { return gonfig_error.MasterProfileConfNotSetError } if err := fileUnmarshal(, v, ); err != nil { return err } return (v, v1, ) }
The general principle is to copy a structure v1 sent to the function by the user, and structure v1 and v are used to receive it respectively.conf-{{profile}}.yaml
Properties andconfiguration information, and then call the three-party open source library
mergo
Make a merge for the properties of two structures.
This is aboutgonfig
All contents~~~
Github address is:/xiao-ren-wu/gonfig
This is the end of this article about how to read configuration files in Go projects. For more relevant contents of Go reading configuration files, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!