Goの環境変数の実用ガイド

こんにちは、Habr! Go by Enda Phelanの環境変数に関するナンセンスガイドの翻訳を紹介します。



環境変数は、システムレベルで設定できるため、アプリケーション構成を保存する最適な方法です。 これは、 Twelve-Factor App方法論の原則の1つであり、実行中のシステムからアプリケーションを分離することができます(構成は展開ごとに大幅に異なる可能性があり、コードは変わらないはずです)。



環境変数を使用する



環境変数と対話するために必要なものはすべて、 os標準ライブラリにあります。 これは、PATH環境変数の値を取得する方法です。



package main import ( "fmt" "os" ) func main() { // Store the PATH environment variable in a variable path, exists := os.LookupEnv("PATH") if exists { // Print the value of the environment variable fmt.Print(path) } }
      
      





そして-変数の値を設定します:



 package main import ( "fmt" "os" ) func main() { // Set the USERNAME environment variable to "MattDaemon" os.Setenv("USERNAME", "MattDaemon") // Get the USERNAME environment variable username := os.Getenv("USERNAME") // Prints out username environment variable fmt.Print(username) }
      
      





.envファイルから環境変数をロードする



多くのプロジェクトがすぐに起動される開発マシンでは、変数環境にパラメーターを保存することが必ずしも便利ではありません。 envファイルを使用してプロジェクト間で分割する方が論理的です。 これは、たとえばgodotenvを使用して実行できます。これはGo Rubyライブラリに移植されたdotenvです。 これにより、アプリケーションに必要な環境変数を.envファイルから設定できます。



パッケージをインストールするには、次を実行します。



 go get github.com/joho/godotenv
      
      





プロジェクトのルートにある.envファイルに設定を追加します。



 GITHUB_USERNAME=craicoverflow GITHUB_API_KEY=TCtQrZizM1xeo1v92lsVfLOHDsF7TfT5lMvwSno
      
      





これで、アプリケーションでこれらの値を使用できます。



 package main import ( "log" "github.com/joho/godotenv" "fmt" "os" ) // init is invoked before main() func init() { // loads values from .env into the system if err := godotenv.Load(); err != nil { log.Print("No .env file found") } } func main() { // Get the GITHUB_USERNAME environment variable githubUsername, exists := os.LookupEnv("GITHUB_USERNAME") if exists { fmt.Println(githubUsername) } // Get the GITHUB_API_KEY environment variable githubAPIKey, exists := os.LookupEnv("GITHUB_API_KEY") if exists { fmt.Println(githubAPIKey) } }
      
      





環境変数の値がシステムレベルで設定されている場合、Goはenvファイルで指定された値の代わりにこの値を使用することに注意してください。



構成モジュールで環境変数をラップします



もちろん、上記のように環境変数に直接アクセスできるのはいいことですが、そのような解決策を維持することはかなり問題があるようです。 変数名は文字列であり、変更する場合は、アプリケーション全体で変数参照を更新するプロセスにつながる頭痛の種を想像してください。



この問題を解決するために、環境変数をより集中的かつサポートされた方法で操作するための構成モジュールを作成します。



以下は、 Config構造体で構成パラメーターを返す簡単な構成モジュールです(システムに環境変数がない場合、デフォルトのパラメーター値も設定します)。



 package config import ( "os" ) type GitHubConfig struct { Username string APIKey string } type Config struct { GitHub GitHubConfig } // New returns a new Config struct func New() *Config { return &Config{ GitHub: GitHubConfig{ Username: getEnv("GITHUB_USERNAME", ""), APIKey: getEnv("GITHUB_API_KEY", ""), }, } } // Simple helper function to read an environment or return a default value func getEnv(key string, defaultVal string) string { if value, exists := os.LookupEnv(key); exists { return value } return defaultVal }
      
      





次に、既存のソリューションは文字列型のみをサポートするため、 Config構造体に型を追加します。これは大規模なアプリケーションにはあまり適していません。



bool、slice、integer型のハンドラーを作成します。



 package config import ( "os" "strconv" "strings" ) type GitHubConfig struct { Username string APIKey string } type Config struct { GitHub GitHubConfig DebugMode bool UserRoles []string MaxUsers int } // New returns a new Config struct func New() *Config { return &Config{ GitHub: GitHubConfig{ Username: getEnv("GITHUB_USERNAME", ""), APIKey: getEnv("GITHUB_API_KEY", ""), }, DebugMode: getEnvAsBool("DEBUG_MODE", true), UserRoles: getEnvAsSlice("USER_ROLES", []string{"admin"}, ","), MaxUsers: getEnvAsInt("MAX_USERS", 1), } } // Simple helper function to read an environment or return a default value func getEnv(key string, defaultVal string) string { if value, exists := os.LookupEnv(key); exists { return value } return defaultVal } // Simple helper function to read an environment variable into integer or return a default value func getEnvAsInt(name string, defaultVal int) int { valueStr := getEnv(name, "") if value, err := strconv.Atoi(valueStr); err == nil { return value } return defaultVal } // Helper to read an environment variable into a bool or return default value func getEnvAsBool(name string, defaultVal bool) bool { valStr := getEnv(name, "") if val, err := strconv.ParseBool(valStr); err == nil { return val } return defaultVal } // Helper to read an environment variable into a string slice or return default value func getEnvAsSlice(name string, defaultVal []string, sep string) []string { valStr := getEnv(name, "") if valStr == "" { return defaultVal } val := strings.Split(valStr, sep) return val }
      
      





envファイルに新しい環境変数を追加します。



 GITHUB_USERNAME=craicoverflow GITHUB_API_KEY=TCtQrZizM1xeo1v92lsVfLOHDsF7TfT5lMvwSno MAX_USERS=10 USER_ROLES=admin,super_admin,guest DEBUG_MODE=false
      
      





これで、アプリケーションの任意の場所でそれらを使用できます。



 package main import ( "fmt" "log" "github.com/craicoverflow/go-environment-variables-example/config" "github.com/joho/godotenv" ) // init is invoked before main() func init() { // loads values from .env into the system if err := godotenv.Load(); err != nil { log.Print("No .env file found") } } func main() { conf := config.New() // Print out environment variables fmt.Println(conf.GitHub.Username) fmt.Println(conf.GitHub.APIKey) fmt.Println(conf.DebugMode) fmt.Println(conf.MaxUsers) // Print out each role for _, role := range conf.UserRoles { fmt.Println(role) } }
      
      





できた!



はい、アプリケーションを構成するためのターンキーソリューションを提供するパッケージがありますが、自分で簡単に実行できる場合はどれくらい必要ですか?



また、アプリケーションの構成をどのように管理しますか?



All Articles