Go环境变量实用指南

哈Ha! 我向您介绍了Enda Phelan撰写的有关Go中环境变量的精读指南

环境变量是存储应用程序配置的最佳方法,因为它们可以在系统级别设置。 这是十二要素应用程序方法的原理之一,它使您可以将应用程序与运行它们的系统分开(配置在部署之间可能会有很大差异,代码不应有所不同)。

使用环境变量


与环境变量进行交互所需的全部都在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结构中,因为现有解决方案仅支持字符串类型,这对于大型应用程序而言不是很合理。

为布尔,切片和整数类型创建处理程序:

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

做完了!


是的,有些软件包提供了用于配置您的应用程序的交钥匙解决方案,但是如果您自己轻松地做到这一点,它们需要多少呢?

以及如何管理应用程序中的配置?

Source: https://habr.com/ru/post/zh-CN446468/


All Articles