使用 Viper Go 读取环境变量
Reading in environmental Variable Using Viper Go
我试图让 Viper 读取我的环境变量,但它不起作用。这是我的配置:
# app.yaml
dsn: RESTFUL_APP_DSN
jwt_verification_key: RESTFUL_APP_JWT_VERIFICATION_KEY
jwt_signing_key: RESTFUL_APP_JWT_SIGNING_KEY
jwt_signing_method: "HS256"
还有我的 config.go
文件:
package config
import (
"fmt"
"strings"
"github.com/go-ozzo/ozzo-validation"
"github.com/spf13/viper"
)
// Config stores the application-wide configurations
var Config appConfig
type appConfig struct {
// the path to the error message file. Defaults to "config/errors.yaml"
ErrorFile string `mapstructure:"error_file"`
// the server port. Defaults to 8080
ServerPort int `mapstructure:"server_port"`
// the data source name (DSN) for connecting to the database. required.
DSN string `mapstructure:"dsn"`
// the signing method for JWT. Defaults to "HS256"
JWTSigningMethod string `mapstructure:"jwt_signing_method"`
// JWT signing key. required.
JWTSigningKey string `mapstructure:"jwt_signing_key"`
// JWT verification key. required.
JWTVerificationKey string `mapstructure:"jwt_verification_key"`
}
func (config appConfig) Validate() error {
return validation.ValidateStruct(&config,
validation.Field(&config.DSN, validation.Required),
validation.Field(&config.JWTSigningKey, validation.Required),
validation.Field(&config.JWTVerificationKey, validation.Required),
)
}
func LoadConfig(configpaths ...string) error {
v := viper.New()
v.SetConfigName("app")
v.SetConfigType("yaml")
v.SetEnvPrefix("restful")
v.AutomaticEnv()
v.SetDefault("error_file", "config/errors.yaml")
v.SetDefault("server_port", 1530)
v.SetDefault("jwt_signing_method", "HS256")
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
for _, path := range configpaths {
v.AddConfigPath(path)
}
if err := v.ReadInConfig(); err != nil {
return fmt.Errorf("Failed to read the configuration file: %s", err)
}
if err := v.Unmarshal(&Config); err != nil {
return err
}
// Checking with this line. This is what I get:
// RESTFUL_JWT_SIGNING_KEY
fmt.Println("Sign Key: ", v.GetString("jwt_signing_key"))
return Config.Validate()
}
这一行 fmt.Println("Sign Key: ", v.GetString("jwt_signing_key"))
仅向我提供了在 yaml 文件 RESTFUL_JWT_SIGNING_KEY
中传递的密钥。我不知道我做错了什么。
根据文档:
AutomaticEnv is a powerful helper especially when combined with
SetEnvPrefix. When called, Viper will check for an environment
variable any time a viper.Get request is made. It will apply the
following rules. It will check for a environment variable with a name
matching the key uppercased and prefixed with the EnvPrefix if set.
那么,为什么它不读取环境变量?
使用JSON
{
"dsn": "RESTFUL_APP_DSN",
"jwt_verification_key": "RESTFUL_APP_JWT_VERIFICATION_KEY",
"jwt_signing_key": "RESTFUL_APP_JWT_SIGNING_KEY",
"jwt_signing_method": "HS256"
}
我的解析器看起来像这样:
// LoadConfigEnv loads configuration from the given list of paths and populates it into the Config variable.
// Environment variables with the prefix "RESTFUL_" in their names are also read automatically.
func LoadConfigEnv(environment string, configpaths ...string) error {
v := viper.New()
v.SetConfigName(environment)
v.SetConfigType("json")
v.SetEnvPrefix("restful")
v.AutomaticEnv()
v.SetDefault("jwt_signing_method", "HS256")
v.SetDefault("error_file", "config/errors.yaml")
v.SetDefault("server_port", 1530)
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
for _, path := range configpaths {
v.AddConfigPath(path)
}
if err := v.ReadInConfig(); err != nil {
return fmt.Errorf("Failed to read the configuration file: %s", err)
}
if err := v.Unmarshal(&Config); err != nil {
return err
}
return Config.Validate()
}
在 Validate
函数中,我决定检查 Config
结构,这就是我得到的:
Config: {config/errors.yaml 1530 RESTFUL_APP_DSN HS256 RESTFUL_APP_JWT_SIGNING_KEY RESTFUL_APP_JWT_VERIFICATION_KEY}
我问题中的代码实际上并没有显示我试图解决的问题。在理解了错误之后,我相信,这里的代码会在我的 开发环境中本地 运行。
AutomaticEnv is a powerful helper especially when combined with SetEnvPrefix. When called, Viper will check for an environment variable any time a viper.Get request is made. It will apply the following rules. It will check for an environment variable with a name matching the key uppercased and prefixed with the EnvPrefix if set.
这里的这一行说明了一切:
如果设置
,它将检查名称与大写键匹配并以 EnvPrefix 为前缀的环境变量
使用 v.SetEnvPrefix("restful")
设置的前缀需要 .yaml
键值为:
示例app.yaml:
dsn: RESTFUL_DSN
注意 DSN 是 小写的密钥,它被用作 RESTFUL_DSN
的 Suffix
在我的情况下,我是这样做的:
示例app.yaml:
dsn: RESTFUL_APP_DSN
因此,它在我的环境中检查 RESTFUL_DSN
而不是 RESTFUL_APP_DSN
我试图让 Viper 读取我的环境变量,但它不起作用。这是我的配置:
# app.yaml
dsn: RESTFUL_APP_DSN
jwt_verification_key: RESTFUL_APP_JWT_VERIFICATION_KEY
jwt_signing_key: RESTFUL_APP_JWT_SIGNING_KEY
jwt_signing_method: "HS256"
还有我的 config.go
文件:
package config
import (
"fmt"
"strings"
"github.com/go-ozzo/ozzo-validation"
"github.com/spf13/viper"
)
// Config stores the application-wide configurations
var Config appConfig
type appConfig struct {
// the path to the error message file. Defaults to "config/errors.yaml"
ErrorFile string `mapstructure:"error_file"`
// the server port. Defaults to 8080
ServerPort int `mapstructure:"server_port"`
// the data source name (DSN) for connecting to the database. required.
DSN string `mapstructure:"dsn"`
// the signing method for JWT. Defaults to "HS256"
JWTSigningMethod string `mapstructure:"jwt_signing_method"`
// JWT signing key. required.
JWTSigningKey string `mapstructure:"jwt_signing_key"`
// JWT verification key. required.
JWTVerificationKey string `mapstructure:"jwt_verification_key"`
}
func (config appConfig) Validate() error {
return validation.ValidateStruct(&config,
validation.Field(&config.DSN, validation.Required),
validation.Field(&config.JWTSigningKey, validation.Required),
validation.Field(&config.JWTVerificationKey, validation.Required),
)
}
func LoadConfig(configpaths ...string) error {
v := viper.New()
v.SetConfigName("app")
v.SetConfigType("yaml")
v.SetEnvPrefix("restful")
v.AutomaticEnv()
v.SetDefault("error_file", "config/errors.yaml")
v.SetDefault("server_port", 1530)
v.SetDefault("jwt_signing_method", "HS256")
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
for _, path := range configpaths {
v.AddConfigPath(path)
}
if err := v.ReadInConfig(); err != nil {
return fmt.Errorf("Failed to read the configuration file: %s", err)
}
if err := v.Unmarshal(&Config); err != nil {
return err
}
// Checking with this line. This is what I get:
// RESTFUL_JWT_SIGNING_KEY
fmt.Println("Sign Key: ", v.GetString("jwt_signing_key"))
return Config.Validate()
}
这一行 fmt.Println("Sign Key: ", v.GetString("jwt_signing_key"))
仅向我提供了在 yaml 文件 RESTFUL_JWT_SIGNING_KEY
中传递的密钥。我不知道我做错了什么。
根据文档:
AutomaticEnv is a powerful helper especially when combined with SetEnvPrefix. When called, Viper will check for an environment variable any time a viper.Get request is made. It will apply the following rules. It will check for a environment variable with a name matching the key uppercased and prefixed with the EnvPrefix if set.
那么,为什么它不读取环境变量?
使用JSON
{
"dsn": "RESTFUL_APP_DSN",
"jwt_verification_key": "RESTFUL_APP_JWT_VERIFICATION_KEY",
"jwt_signing_key": "RESTFUL_APP_JWT_SIGNING_KEY",
"jwt_signing_method": "HS256"
}
我的解析器看起来像这样:
// LoadConfigEnv loads configuration from the given list of paths and populates it into the Config variable.
// Environment variables with the prefix "RESTFUL_" in their names are also read automatically.
func LoadConfigEnv(environment string, configpaths ...string) error {
v := viper.New()
v.SetConfigName(environment)
v.SetConfigType("json")
v.SetEnvPrefix("restful")
v.AutomaticEnv()
v.SetDefault("jwt_signing_method", "HS256")
v.SetDefault("error_file", "config/errors.yaml")
v.SetDefault("server_port", 1530)
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
for _, path := range configpaths {
v.AddConfigPath(path)
}
if err := v.ReadInConfig(); err != nil {
return fmt.Errorf("Failed to read the configuration file: %s", err)
}
if err := v.Unmarshal(&Config); err != nil {
return err
}
return Config.Validate()
}
在 Validate
函数中,我决定检查 Config
结构,这就是我得到的:
Config: {config/errors.yaml 1530 RESTFUL_APP_DSN HS256 RESTFUL_APP_JWT_SIGNING_KEY RESTFUL_APP_JWT_VERIFICATION_KEY}
我问题中的代码实际上并没有显示我试图解决的问题。在理解了错误之后,我相信,这里的代码会在我的 开发环境中本地 运行。
AutomaticEnv is a powerful helper especially when combined with SetEnvPrefix. When called, Viper will check for an environment variable any time a viper.Get request is made. It will apply the following rules. It will check for an environment variable with a name matching the key uppercased and prefixed with the EnvPrefix if set.
这里的这一行说明了一切:
如果设置
,它将检查名称与大写键匹配并以 EnvPrefix 为前缀的环境变量使用 v.SetEnvPrefix("restful")
设置的前缀需要 .yaml
键值为:
示例app.yaml:
dsn: RESTFUL_DSN
注意 DSN 是 小写的密钥,它被用作 RESTFUL_DSN
Suffix
在我的情况下,我是这样做的:
示例app.yaml:
dsn: RESTFUL_APP_DSN
因此,它在我的环境中检查 RESTFUL_DSN
而不是 RESTFUL_APP_DSN