I need to read data first of all from the fields inside the service, and only then look at the external fields.
There is a config of this type:
auth_service:
log_level: debug
port: 9999
mail_service:
log_level: debug
port: 9998
smtp:
host: localhost
port: 1025
username: ""
password: ""
email_from: "mailservice@test.test"
retries_count: 5
log_level: test
I tried to do it via viper.RegisterAlias("log_level", "auth_service.log_level")
, but in this form the external field is not read.
The code for getting the config:
type Config struct {
LogLevel string `mapstructure:"log_level"`
Port int `mapstructure:"port"`
SMTP SMTPConfig `mapstructure:"smtp"`
}
type SMTPConfig struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
EmailFrom string `mapstructure:"email_from"`
RetriesCount int `mapstructure:"retries_count"`
}
func LoadConfig(path string) (*Config, error) {
type ServiceConfig struct {
Cfg Config `mapstructure:"auth_service"`
}
viper.RegisterAlias("log_level","auth_service.log_level")
viper.AutomaticEnv()
if path != "" {
dir := p.Dir(path)
file := p.Base(path)
fileParts := strings.Split(file, ".")
if len(fileParts) != 2 {
return nil, fmt.Errorf("incorrect config file: %s", file)
}
viper.AddConfigPath(dir)
viper.SetConfigName(fileParts[0])
viper.SetConfigType(fileParts[1])
err := viper.ReadInConfig()
if err != nil {
return nil, err
}
}
fmt.Println(viper.AllKeys())
var config ServiceConfig
err := viper.Unmarshal(&config)
if err != nil {
return nil, err
}
return &config.Cfg, nil
}
ServiceConfig is needed so that you can get the value from service_name.field_name, because mapstructure:"service_name.field"
is not working.
After digging around, I realized that there is no native way for this and I had to make a fork and add some code. Now you can configure the viper so that the data from the keys is read first and only then the aliases are checked. The possibility of step-by-step verification of each level of aliases has also been added.
https://github.com/EwvwGeN/viper
Of course, you can do this using the reflect package by specifying, for example, your new tag alias: "field_one, field_two"
in the field, But it was more convenient for me to create a full-fledged fork
Thank you all for rate this question