DEV Community

Cover image for Configuration with Viper in Go
Amit Shekhar
Amit Shekhar

Posted on • Edited on • Originally published at outcomeschool.com

Configuration with Viper in Go

Hi, I am Amit Shekhar, Co-Founder @ Outcome School • IIT 2010-14 • I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.

In this blog, we will learn how to load the configurations from the envfile in Golang using Viper in Go (Golang) projects.

This article was originally published at Outcome School.

About the viper package: Viper is used to find, load, and unmarshal a configuration file in JSON, TOML, YAML, HCL, INI, envfile, or Java properties formats.

So, let's start learning to use this viper package to load configuration from the envfile in Go.

I will be using the below-mentioned project for the implementation part. The project follows a clean architecture in Go Language. You can find the complete code for loading the configuration using the Viper package mentioned in the blog in the project itself.

Link to the project: Go Backend Clean Architecture.

As a first step, we should install the package:

go get github.com/spf13/viper 
Enter fullscreen mode Exit fullscreen mode

We have a .env file in our project as below:

APP_ENV=development SERVER_ADDRESS=:8080 PORT=8080 CONTEXT_TIMEOUT=2 DB_HOST=localhost DB_PORT=27017 DB_USER= DB_PASS= DB_NAME=go-backend-clean-architecture-db ACCESS_TOKEN_EXPIRY_HOUR = 2 REFRESH_TOKEN_EXPIRY_HOUR = 168 ACCESS_TOKEN_SECRET=access_token_secret REFRESH_TOKEN_SECRET=refresh_token_secret 
Enter fullscreen mode Exit fullscreen mode

And, we want to load the configuration from this .env file.

Now, we have to create a struct Env in the env.go file as below:

type Env struct { AppEnv string `mapstructure:"APP_ENV"` ServerAddress string `mapstructure:"SERVER_ADDRESS"` ContextTimeout int `mapstructure:"CONTEXT_TIMEOUT"` DBHost string `mapstructure:"DB_HOST"` DBPort string `mapstructure:"DB_PORT"` DBUser string `mapstructure:"DB_USER"` DBPass string `mapstructure:"DB_PASS"` DBName string `mapstructure:"DB_NAME"` AccessTokenExpiryHour int `mapstructure:"ACCESS_TOKEN_EXPIRY_HOUR"` RefreshTokenExpiryHour int `mapstructure:"REFRESH_TOKEN_EXPIRY_HOUR"` AccessTokenSecret string `mapstructure:"ACCESS_TOKEN_SECRET"` RefreshTokenSecret string `mapstructure:"REFRESH_TOKEN_SECRET"` } 
Enter fullscreen mode Exit fullscreen mode

Then, create a function in the same env.go file to load the .env file and unmarshal it into the above created Env struct.

func NewEnv() *Env { env := Env{} viper.SetConfigFile(".env") err := viper.ReadInConfig() if err != nil { log.Fatal("Can't find the file .env : ", err) } err = viper.Unmarshal(&env) if err != nil { log.Fatal("Environment can't be loaded: ", err) } if env.AppEnv == "development" { log.Println("The App is running in development env") } return &env } 
Enter fullscreen mode Exit fullscreen mode

Here, we can notice that we have provided the file .env to the viper using the SetConfigFile method, then read and finally unmarshal it into the Env struct.

The complete env.go file will be as below:

package bootstrap import ( "log" "github.com/spf13/viper" ) type Env struct { AppEnv string `mapstructure:"APP_ENV"` ServerAddress string `mapstructure:"SERVER_ADDRESS"` ContextTimeout int `mapstructure:"CONTEXT_TIMEOUT"` DBHost string `mapstructure:"DB_HOST"` DBPort string `mapstructure:"DB_PORT"` DBUser string `mapstructure:"DB_USER"` DBPass string `mapstructure:"DB_PASS"` DBName string `mapstructure:"DB_NAME"` AccessTokenExpiryHour int `mapstructure:"ACCESS_TOKEN_EXPIRY_HOUR"` RefreshTokenExpiryHour int `mapstructure:"REFRESH_TOKEN_EXPIRY_HOUR"` AccessTokenSecret string `mapstructure:"ACCESS_TOKEN_SECRET"` RefreshTokenSecret string `mapstructure:"REFRESH_TOKEN_SECRET"` } func NewEnv() *Env { env := Env{} viper.SetConfigFile(".env") err := viper.ReadInConfig() if err != nil { log.Fatal("Can't find the file .env : ", err) } err = viper.Unmarshal(&env) if err != nil { log.Fatal("Environment can't be loaded: ", err) } if env.AppEnv == "development" { log.Println("The App is running in development env") } return &env } 
Enter fullscreen mode Exit fullscreen mode

After that, we can just have the Env as below:

env := NewEnv() 
Enter fullscreen mode Exit fullscreen mode

Finally, we can just access the configuration as below:

dbName := env.DBName secret := env.AccessTokenSecret 
Enter fullscreen mode Exit fullscreen mode

So, this way we are able to access the configuration values.

I will highly recommend going through the project and checking the usage of viper to load the configuration.

Link to the project: Go Backend Clean Architecture.

This is how we can load the configurations from the envfile in Golang using Viper in Go (Golang) projects.

Prepare yourself for Machine Learning Interview: Machine Learning Interview Questions

That's it for now.

Thanks

Amit Shekhar

Co-Founder @ Outcome School

You can connect with me on:

Read all of our blogs here.

Top comments (0)