If you have any questions or feedback, pleasefill out this form
Table of Contents
This post is translated by ChatGPT and originally written in Mandarin, so there may be some inaccuracies or mistakes.
Several months ago, I wrote an article on how to set environment variables in Golang. Elegantly configuring environment variables is quite important, so I created a simple function to handle this task.
The initial idea was straightforward: if a corresponding config
file is provided, the key/value pairs within it can be set using os.Setenv
. This way, throughout the entire app, we can directly retrieve values using os.Getenv
.
However, once it comes time for a formal deployment, several issues inevitably arise:
- The configuration file may not necessarily be in YAML format; it could be in other formats as well.
- Sometimes, we may want to inject environment variables through external services (like Consul, etcd, etc.), but the current method relies on
os.Getenv
. - Configuration files can be read from different paths.
- Variables can be set through the command line.
- There are many more unexpected problems.
In smaller projects, this approach may resolve my issues, but when more flexible configuration methods are needed, this alone is insufficient.
Fortunately, Golang already has a mature solution for these problems called Viper.
VIPER
Viper is a powerful library for environment variable configuration. It supports the following features:
- Default values
- Support for different formats of configuration files (
json
,toml
,yaml
) - Ability to watch for changes in configuration files (no need to restart the server!)
- Capability to fetch variables from remote servers (like
Consul
oretcd
) - Use of
flag
to retrieve variables - Ability to read variables from a
reader
, allowing for variable configuration from different sources.
Basic Usage
First, download Viper using go get or go mod.
go get github.com/spf13/viper
func main() {
viper.SetDefault("AWS_ACCESS_TOKEN", "AWS123456789") // Set default value
viper.SetConfigName("config") // Specify the config file name
viper.AddConfigPath("./config")
viper.ReadInConfig()
viper.AutomaticEnv()
}
SetDefault(key, value)
: Set default value.SetConfigName(name)
: Set the config file name; for example, if our config file is calledconfig.yml
, we simply useconfig
. Why not specify the type? Viper handles that for us automatically.AddConfigPath
: Allows specifying multiple directories.ReadInConfig
: Remember to call this to actually read the configuration.AutomaticEnv
: Automatically syncs environment variables into Viper.
Viper also provides many functions for convenient configuration.
Retrieving Variables
After setting variables, we can read them using viper.Get
. The Get
function returns an interface{}
, but Viper also provides numerous type conversion functions, such as viper.GetString
, viper.GetDuration
, and viper.GetStringMap
.
func main() {
fmt.Println(viper.GetString("AWS_ACCESS_TOKEN"))
fmt.Println(viper.GetUint32("YOUR_INT"))
fmt.Println(viper.GetTime("YOUR_TIME"))
}
Conclusion
Setting variables is not as simple as it seems; there are more considerations than one might think, and Viper helps us handle many common use cases.
Additionally, it’s crucial to remember to include sensitive information, like access tokens or secret keys, in .gitignore
to prevent accidental commits to GitHub, which could lead to unfortunate consequences.
If you found this article helpful, please consider buying me a coffee ☕ It'll make my ordinary day shine ✨
☕Buy me a coffee