Use Viper to load configuration in Golang application

Viewed 38

I am new to golang, and coming from java background. I am looking for some best practices for configuring the application.

  1. I can simply load the configuration to viper and then just import to any packages and access the value using viper.Get, as the lib uses the pointer to viper so that It will always be accessing the same instance.

  2. An alternative is to create a new viper instance cfg:=viper.New() and load the configuration then pass the cfg to all the package that needs it.

I found it cumbersome to pass the config to all the dependencies. I also have the same question for logrus, can i use the same pattern or I need to create a new instance and pass it along to all the dependencies.

Here are the code to illustrate my questions (viper seems to have all the configuration value across the packages)

  1. main.go ($PROJECTHOME/cmd/main.go)
       func main() {
         loadConfig()
         fmt.Printf("in main package %s", viper.Get("clientConfig"))
         r := chi.NewRouter()
         r.Use(middleware.RequestID)
         r.Use(middleware.RealIP)
         r.Use(middleware.Logger)
         r.Use(middleware.Recoverer)
         routes.AddUserResource(r, cfg)
         http.ListenAndServe(":"+port, r)
        }
        func loadConfig() {
         viper.SetConfigType("yaml")
         viper.SetConfigName("config.local")
         viper.AddConfigPath("config")
         viper.AddConfigPath("../config")
         err := viper.ReadInConfig()
         if err != nil {
            panic(fmt.Errorf("fatal error config file: %w", err))
         }
       }
  1. other package ($PROJECTHOME/api/client/userClient.go)
package client
....
func RetrieveUser(config domain.ServicConfig, id string) (domain.User, bool) {
    fmt.Printf("in http client package %s", viper.Get("clientConfig"))
    for _, user := range users {
        if user.Id == id {
            return user, true
        }
    }
    return domain.User{}, false
}
0 Answers
Related