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

Viper mapping environment variable to struct member

这是我的 config.yaml 文件

server:
  port: 5000

这是我使用 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
}

我已经设置了环境变量export PORT=9000,现在我的问题是如何将环境变量PORT映射到Configurations.ServerConfig.Port。 我想要 dev 的配置文件具有默认值,并希望我的应用程序在生产环境中从 env 变量进行 read/override 配置,如何使用 viper 实现此目的。

我看到以下选项

  1. 设置SERVER_PORT,然后像下面这样使用替换器将其解组为结构
replacer := strings.NewReplacer(".", "_")
viper.SetEnvKeyReplacer(replacer)
  1. Go viper .yaml values environment variables override

但我想将变量 PORT 映射到结构成员,可能是因为我的托管服务提供商设置了 PORT env 变量,我不能使用第二点,因为我想要 yaml默认值。

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

来自Working with Environment Variables

BindEnv takes one or more parameters. The first parameter is the key name, the rest are the name of the environment variables to bind to this key. If more than one are provided, they will take precedence in the specified order.

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

...
viper.AutomaticEnv()


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


err = viper.ReadInConfig()
...

有了这个改变,像 PORT=9999 ./yourbinary 这样的调用接收 PORT 并将其写入 server.port。从那里,它将被解组到您的结构中。