golang中有多种使用环境变量和文件的方法
在创建生产级应用程序时,实际上是在应用程序中使用环境变量。
为什么要使用环境变量?
假设您的应用程序具有许多功能,并且每个功能都需要访问数据库。 您已在每个功能中配置了所有数据库信息,例如DBURL,DBNAME,USERNAME和PASSWORD。
这种方法有几个主要的缺点,可能有很多。
安全问题:
· 您正在输入代码中的所有信息。 现在,所有未经授权的人也可以访问数据库。
· 如果您使用的是git之类的代码版本控制工具,则在您推送代码后,数据库的详细信息就会公开。
代码管理:
· 如果要更改单个变量,则必须更改所有功能。 您很可能会错过一两个。
· 您可以对环境变量进行分类,例如PROD,DEV或TEST。 只需在变量前面加上环境即可。
刚开始时,它看起来可能需要做一些额外的工作,但这将在您的项目中收获很多。
现在该采取行动了。
我们将在本教程中做什么?
在本教程中,我们将以3种不同的方式访问环境变量。
您可以根据需要使用。
- os 包
- godotenv 包
- viper 包
建立专案
在$ Go PATH外部创建一个项目。
初始化模块
在项目根目录中打开终端,然后运行以下命令。
go mod init go-env-ways
该模块将记录项目中使用的所有 软件包 及其版本。 它类似于nodejs中的package.json。
让我们从最简单的一个开始,使用os包。
os 软件包
Golang提供os软件包,这是一种配置和访问环境变量的简便方法。
要设置环境变量,
os.Setenv(key, value)
要获取环境变量,
value := os.Getenv(key)
在项目内部创建一个新文件main.go。
package main
import (
"fmt"
"os"
)
// use os package to get the env variable which is already set
func 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 directory
godotenv.Load()
// or
godotenv.Load(".env")
加载方法可以一次加载多个环境文件。 这也支持yaml。 有关更多信息,请查阅文档。
在项目根目录中创建一个新的.env文件。
STRONGEST_AVENGER=Thor
更新main.go。
package main
import (
...
// Import godotenv
"github.com/joho/godotenv"
)
// use godot package to load/read the .env file and
// return the value of the key
func 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 \n", "STRONGEST_AVENGER", dotenv)
}
打开终端并运行main.go。
go run main.go
// Output
os package: name = gopher
godotenv : 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 key
func 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 \n", "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 key
func 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 \n", "I_AM_INEVITABLE", viperconfig)
}
打开终端并运行main.go
go run main.go
// Output
os package: name = gopher
godotenv : STRONGEST_AVENGER = Thor
viper : STRONGEST_AVENGER = Thor
viper config : I_AM_INEVITABLE = I am Iron Man
结论
就是这样,现在您可以探索他们的更多秘密。 如果您发现值得分享的东西,请不要犹豫。
(本文翻译自Shubham Chadokar的文章《Use Environment Variable in your next Golang Project》,参考: