web-dev-qa-db-ja.com

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は、特にSetEnvPrefixと組み合わせると強力なヘルパーです。呼び出されると、Viperはviper.Get要求が行われるたびに環境変数をチェックします。以下のルールが適用されます。設定されている場合は、大文字のキーに一致し、EnvPrefixが前に付いた名前の環境変数をチェックします。

では、なぜ環境変数を読み取らないのでしょうか?

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}_

7

私の質問のコードは実際に私が解決しようとしていたことを示していませんでした。何が問題だったかを理解した後、私は、ここのコードは私の開発環境でローカルに実行されたと思います

Viperのドキュメントによると:

AutomaticEnvは、特にSetEnvPrefixと組み合わせると強力なヘルパーになります。呼び出されると、Viperはviper.Get要求が行われるたびに環境変数をチェックします。以下のルールが適用されます。設定されている場合は、大文字のキーに一致し、EnvPrefixが前に付いた名前の環境変数をチェックします。

ここのこの行はそれをすべて言います:

設定されている場合、大文字のキーに一致し、EnvPrefixが前に付いたキーと一致する名前の環境変数をチェックします

v.SetEnvPrefix("restful")で設定されたプレフィックスは、次のキー値を持つ.yamlを想定しています。

App.yamlの例:

dsn: RESTFUL_DSN

DSNが小文字のキーであり、RESTFUL_DSNSuffixとして使用されていることに注意してください。

私の状況では、代わりにこれを行っていました:

App.yamlの例:

dsn: RESTFUL_APP_DSN

つまり、私の環境ではRESTFUL_DSNではなくRESTFUL_APP_DSNをチェックしていました。

8