golang中有多种使用环境变量和文件的方法
在创建生产级应用程序时,实际上是在应用程序中使用环境变量。
为什么要使用环境变量?
假设您的应用程序具有许多功能,并且每个功能都需要访问数据库。 您已在每个功能中配置了所有数据库信息,例如DBURL,DBNAME,USERNAME和PASSWORD。
这种方法有几个主要的缺点,可能有很多。
安全问题:
· 您正在输入代码中的所有信息。 现在,所有未经授权的人也可以访问数据库。
· 如果您使用的是git之类的代码版本控制工具,则在您推送代码后,数据库的详细信息就会公开。
代码管理:
· 如果要更改单个变量,则必须更改所有功能。 您很可能会错过一两个。
· 您可以对环境变量进行分类,例如PROD,DEV或TEST。 只需在变量前面加上环境即可。
刚开始时,它看起来可能需要做一些额外的工作,但这将在您的项目中收获很多。
只是不要忘记在.gitignore中包含您的环境文件
现在该采取行动了。
我们将在本教程中做什么?
在本教程中,我们将以3种不同的方式访问环境变量。
您可以根据需要使用。
- os 包
- godotenv 包
- viper 包
建立专案
在$ GOPATH外部创建一个项目。
初始化模块
在项目根目录中打开终端,然后运行以下命令。
go mod init go-env-ways
该模块将记录项目中使用的所有软件包及其版本。 它类似于nodejs中的package.json。
让我们从最简单的一个开始,使用os包。
os 软件包
Golang提供os软件包,这是一种配置和访问环境变量的简便方法。
要设置环境变量,
os.Setenv(key, value)
要获取环境变量,
value := os.Getenv(key)
在项目内部创建一个新文件main.go。
package mainimport ( "fmt" "os")// use os package to get the env variable which is already setfunc envVariable(key string) string { // set env variable using os package os.Setenv(key, "gopher") // return the env variable using os package return os.Getenv(key)}
运行以下命令进行检查。
go run main.go// Outputos package: name = gopher
GoDotEnv 软件包
加载.env文件的最简单方法是使用godotenv软件包。
安装
在项目根目录中打开终端。
go get github.com/joho/godotenv
godotenv提供了一种Load方法来加载环境文件。
// Load the .env file in the current directorygodotenv.Load()// orgodotenv.Load(".env")
加载方法可以一次加载多个环境文件。 这也支持yaml。 有关更多信息,请查阅文档。
在项目根目录中创建一个新的.env文件。
STRONGEST_AVENGER=Thor
更新main.go。
package mainimport ( ... // Import godotenv "github.com/joho/godotenv")// use godot package to load/read the .env file and// return the value of the keyfunc goDotEnvVariable(key string) string { // load .env file err := godotenv.Load(".env") if err != nil { log.Fatalf("Error loading .env file") } return os.Getenv(key)}func main() { // os package ... // godotenv package dotenv := goDotEnvVariable("STRONGEST_AVENGER") fmt.Printf("godotenv : %s = %s ", "STRONGEST_AVENGER", dotenv)}
打开终端并运行main.go。
go run main.go// Outputos package: name = gophergodotenv : STRONGEST_AVENGER = Thor
只需在main函数的os包的末尾添加代码。
Viper包装
Viper是golang社区中最受欢迎的软件包之一。 许多Go项目都是使用Viper构建的,包括Hugo,Docker Notary,Mercury。
Viper是适用于Go应用程序(包括12-Factor应用程序)的完整配置解决方案。 它旨在在应用程序中工作,并且可以处理所有类型的配置需求和格式。 从JSON,TOML,YAML,HCL,envfile和Java属性配置文件中读取
有关更多信息,请阅读毒蛇的官方文档。
安装
在项目根目录中打开终端。
go get github.com/spf13/viper
设置配置文件和路径
viper.SetConfigFile(".env")
读取配置文件
viper.ReadInConfig()
使用key从配置文件中获取值
viper.Get(key)
更新main.go。
import ( "fmt" "log" "os" "github.com/joho/godotenv" "github.com/spf13/viper")// use viper package to read .env file// return the value of the keyfunc viperEnvVariable(key string) string { // SetConfigFile explicitly defines the path, name and extension of the config file. // Viper will use this and not check any of the config paths. // .env - It will search for the .env file in the current directory viper.SetConfigFile(".env") // Find and read the config file err := viper.ReadInConfig() if err != nil { log.Fatalf("Error while reading config file %s", err) } // viper.Get() returns an empty interface{} // to get the underlying type of the key, // we have to do the type assertion, we know the underlying value is string // if we type assert to other type it will throw an error value, ok := viper.Get(key).(string) // If the type is a string then ok will be true // ok will make sure the program not break if !ok { log.Fatalf("Invalid type assertion") } return value}func main() { // os package ... // godotenv package ... // viper package read .env viperenv := viperEnvVariable("STRONGEST_AVENGER") fmt.Printf("viper : %s = %s ", "STRONGEST_AVENGER", viperenv)}
打开终端并运行main.go。
Viper不仅限于.env文件。
它支持:
- · 设置默认值
- · 从JSON,TOML,YAML,HCL,envfile和Java属性配置文件中读取
- · 实时观看和重新读取配置文件(可选)
- · 从环境变量中读取
- · 从远程配置系统(etcd或Consul)中读取,并观察更改
- · 从命令行标志读取
- · 从缓冲区读取
- · 设置显式值
可以将Viper视为满足您所有应用程序配置需求的注册表。
让我们尝试一下:
在项目根目录中创建一个新的config.yaml文件。
I_AM_INEVITABLE: "I am Iron Man"
设置配置文件名
viper.SetConfigName("config")
设置配置文件路径
// Look in the current working directory viper.AddConfigPath(".")
读取配置文件
viper.ReadInConfig()
更新main.go
// use viper package to load/read the config file or .env file and// return the value of the keyfunc viperConfigVariable(key string) string { // name of config file (without extension) viper.SetConfigName("config") // look for config in the working directory viper.AddConfigPath(".") // Find and read the config file err := viper.ReadInConfig() if err != nil { log.Fatalf("Error while reading config file %s", err) } // viper.Get() returns an empty interface{} // to get the underlying type of the key, // we have to do the type assertion, we know the underlying value is string // if we type assert to other type it will throw an error value, ok := viper.Get(key).(string) // If the type is a string then ok will be true // ok will make sure the program not break if !ok { log.Fatalf("Invalid type assertion") } return value}func main() { // os package ... // godotenv package ... // viper package read .env ... // viper package read config file viperconfig := viperConfigVariable("I_AM_INEVITABLE") fmt.Printf("viper config : %s = %s ", "I_AM_INEVITABLE", viperconfig) }
打开终端并运行main.go
go run main.go// Outputos package: name = gophergodotenv : STRONGEST_AVENGER = Thorviper : STRONGEST_AVENGER = Thorviper config : I_AM_INEVITABLE = I am Iron Man
结论
就是这样,现在您可以探索他们的更多秘密。 如果您发现值得分享的东西,请不要犹豫。
(本文翻译自Shubham Chadokar的文章《Use Environment Variable in your next Golang Project》,参考:https://towardsdatascience.com/use-environment-variable-in-your-next-golang-project-39e17c3aaa66)