SoFunction
Updated on 2025-03-03

golang uses viper to load configuration files to achieve automatic deserialization to structure

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!