text
- Golang uses viper without setting mapstruct tag automatically back to structure according to configuration file suffix
- Solve the problem of unsuccessful analysis of underlined fields in structure
viper loads configuration files normally
golang viper where it can be used to find, load and deserialize JSON, TOML, YAML, HCL, INI, envfile and format configuration files
Configuration file test_toml.toml
http_addr = ":8082" grpc_addr = ":8083" jaeger_url= "http://localhost:14268/api/traces" tracing= true
golang code
type ConfigTest struct { HttpAddr string `json:"http_addr" toml:"http_addr" yaml:"http_addr"` GrpcAddr string `json:"grpc_addr" toml:"grpc_addr" yaml:"grpc_addr"` JaegerUrl string `json:"jaeger_url" toml:"jaeger_url" yaml:"jaeger_url" mapstructure:"jaeger_url"` Tracing bool `toml:"tracing" json:"tracing" yaml:"tracing" ` // opentelemetry tracing } // jaeger loads configuration filefunc TestSourceFile_Unmarshal(t *) { filePath := "./test_toml.toml" (filePath) if err := (); err != nil { (err) } c := &ConfigTest{} if err := (c); err != nil { (err) } ("Unmarshal file sucess", "v", c) }
Print back serialization configuration structure
{"level":"info","ts":"2023-08-27T21:35:27.041+0800","caller":"config/source_file_test.go:31","msg":"Unmarshal file sucess","v":{"http_addr":"","grpc_addr":"","jaeger_url":"http://localhost:14268/api/traces","tracing":true}}
You can see underlined fields, without mapstructure tags, and will not be deserialized
Automatic deserialization without adding mapstructure tags
View viper Unmarshal code
func (v *Viper) Unmarshal(rawVal interface{}, opts ...DecoderConfigOption) error { return decode((), defaultDecoderConfig(rawVal, opts...)) } func decode(input interface{}, config *) error { decoder, err := (config) if err != nil { return err } return (input) } func NewDecoder(config *DecoderConfig) (*Decoder, error) { if == "" { = "mapstructure" } // ... }
- From the code, Viper uses /mitchellh/maplanture to parse the value
- mapstructure is used to decode the common map[string]interface{} into the corresponding Go structure
- By default, mapstructure uses the names of fields in the structure to make this mapping, which is case-insensitive. For example, the Name field can be mapped to name, NAME, NaMe, etc.
- If tagName is not specified, the default is mapstructure, which is why underlined fields cannot be parsed without mapstructure tags
- The second parameter of Unmarshal in viper is that you can specify DecoderConfigOption, so you can specify tagName
Viper automatically decodes to structure according to file type
- Read file suffix such as toml
- Set tagName according to the suffix
- Call Analysis
func TestSourceFile_Unmarshal1(t *) { filePath := "./test_toml.toml" c := &ConfigTest{} if err := viperUnmarshal(c, filePath); err != nil { (err) } ("Unmarshal file sucess", "v", c) } func viperUnmarshal(v interface{}, configPath string) error { var tagName string ext := (configPath) if len(ext) > 1 { tagName = ext[1:] } // set decode tag_name, default is mapstructure decoderConfigOption := func(c *) { = tagName } cViper := () (configPath) if err := (); err != nil { return err } return (v, decoderConfigOption) }
result:
{"level":"info","ts":"2023-08-27T21:35:34.553+0800","caller":"config/source_file_test.go:40","msg":"Unmarshal file sucess","v":{"http_addr":":8082","grpc_addr":":8083","jaeger_url":"http://localhost:14268/api/traces","tracing":true}}
I have integrated the viper loading configuration into my project, and the complete example code can be viewedsource_file_test.go
The above is the detailed content of golang using viper to load configuration files and automatically deserialize to structures. For more information about golang viper loading configuration files and automatically deserialize to structures, please pay attention to my other related articles!