Viper 将环境变量映射到结构成员

mah*_*dra 3 go viper-go

这是我的config.yaml文件

server:
  port: 5000
Run Code Online (Sandbox Code Playgroud)

这是我使用 viper 解组的逻辑

type Configurations struct {
    Server ServerConfig
}

type ServerConfig struct {
    Port int
}

// LoadConfig reads configuration from file or environment variables.
func LoadConfig(path string) (config Configurations, err error) {
    viper.AddConfigPath(path)
    viper.SetConfigName("config")
    viper.SetConfigType("yaml")

    viper.AutomaticEnv()

    err = viper.ReadInConfig()
    if err != nil {
        return
    }

    err = viper.Unmarshal(&config)
    return
}
Run Code Online (Sandbox Code Playgroud)

我已经设置了 env 变量export PORT=9000,现在我的问题是如何将环境变量映射PORTConfigurations.ServerConfig.Port. 我想要一个带有开发默认值的配置文件,并且希望我的应用程序从生产环境变量中读取/覆盖配置,我如何使用 viper 来实现这一点。

我看到以下选项

  1. 设置SERVER_PORT然后使用替换器如下所示将其解组为结构
replacer := strings.NewReplacer(".", "_")
viper.SetEnvKeyReplacer(replacer)
Run Code Online (Sandbox Code Playgroud)
  1. Go viper .yaml 值环境变量覆盖

但我想将变量映射PORT到结构成员,可能是因为我的托管服务提供商设置了PORTenv 变量,并且我无法使用第二点,因为我希望使用 yaml 作为默认值。

psc*_*eid 6

您可以使用viper.BindEnv(string...) error将特定环境变量绑定到配置。

来自使用环境变量

BindEnv 接受一个或多个参数。第一个参数是键名,其余参数是绑定到该键的环境变量的名称。如果提供了多个,则它们将按指定的顺序优先。

这里端口的配置键是server.port,环境变量PORT应该绑定到它。

...
viper.AutomaticEnv()


err = viper.BindEnv("server.port", "PORT")
if err != nil {
    return
}


err = viper.ReadInConfig()
...
Run Code Online (Sandbox Code Playgroud)

完成此更改后,将进行诸如PORT=9999 ./yourbinary拾取PORT并将其写入之类的调用server.port。从那里,它将被解组到您的结构中。