Kalan's Blog

Kalan 頭像照片,在淡水拍攝,淺藍背景

四零二曜日電子報上線啦!訂閱訂起來

Software Engineer / Taiwanese / Life in Fukuoka
This blog supports RSS feed (all content), you can click RSS icon or setup through third-party service. If there are special styles such as code syntax in the technical article, it is still recommended to browse to the original website for the best experience.

Current Theme light

我會把一些不成文的筆記或是最近的生活雜感放在短筆記,如果有興趣的話可以來看看唷!

Please notice that currenly most of posts are translated by AI automatically and might contain lots of confusion. I'll gradually translate the post ASAP

Setting Environment Variables for a Project - VIPER

A few months ago, I wrote an article about how to set environment variables in golang. It is important to set environment variables elegantly, so I created a simple function to do that.

The initial consideration was simple: if a corresponding config file is provided, use os.Setenv to set the key/value pairs inside. Then, throughout the entire app, the values can be directly accessed using os.Getenv.

However, when it comes to formal deployment, several issues may arise:

  • The configuration file may not necessarily be in YAML format; it could be in another format.
  • Sometimes, it is desirable to inject environment variables through external services like Consul or etcd, but the current implementation uses os.Getenv.
  • The configuration file may need to be read from different paths.
  • Variables can be set through the command line.
  • And more unexpected issues.

For small projects, this approach actually solves my problems. However, it is not sufficient when more flexible configuration methods are required.

Fortunately, there is a mature solution in golang for all these issues called Viper.

VIPER

Viper is a powerful package for managing environment variables. It supports the following features:

  • Default values
  • Support for different configuration file formats (JSON, TOML, YAML)
  • Ability to watch for changes in the configuration file (no need to restart the server!)
  • Ability to fetch variables from remote servers (e.g., Consul or etcd)
  • Ability to retrieve variables using command line flags
  • Ability to retrieve variables from a reader, which means you can configure variables from different sources.

Basic Usage

First, use go get or go mod to download Viper.

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 named config.yml, we just need to specify config. Why don't we need to specify the type? Viper automatically handles it for us.
  • AddConfigPath: Can set multiple directories
  • ReadInConfig: Must be called to actually read the configuration
  • AutomaticEnv: Automatically syncs environment variables to Viper

Viper also provides many other functions for convenient configuration.

Retrieving Variables

After setting the variables, we can use viper.Get to retrieve them. Get returns an interface{}, but Viper also provides type conversion functions such as viper.GetString, viper.GetDuration, viper.GetStringMap, and so on.

func main() {
	fmt.Println(viper.GetString("AWS_ACCESS_TOKEN"))
	fmt.Println(viper.GetUint32("YOUR_INT"))
	fmt.Println(viper.GetTime("YOUR_TIME"))
}

Conclusion

Setting variables can be challenging and complex, with more considerations than one might imagine. However, Viper handles many common use cases for us.

One important reminder is that when setting things like access tokens or secret keys, always remember to add them to .gitignore to avoid accidentally pushing them to GitHub and causing regrets.

Prev

Implementing the pin to bottom component via overflow-anchor

Next

EMS

If you found this article helpful, please consider buy me a drink ☕️ It'll make my ordinary day shine✨

Buy me a coffee