Skip to content

Instantly share code, notes, and snippets.

@chazcheadle
Created June 7, 2017 04:32
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save chazcheadle/45bf85b793dea2b71bd05ebaa3c28644 to your computer and use it in GitHub Desktop.
Save chazcheadle/45bf85b793dea2b71bd05ebaa3c28644 to your computer and use it in GitHub Desktop.
Golang Viper config read into struct
package main
import (
"fmt"
"github.com/spf13/viper"
)
// Create private data struct to hold config options.
type config struct {
Hostname string `yaml:"hostname"`
Port string `yaml:"port"`
}
// Create a new config instance.
var (
conf *config
)
// Read the config file from the current directory and marshal
// into the conf config struct.
func getConf() *config {
viper.AddConfigPath(".")
viper.SetConfigName("config")
err := viper.ReadInConfig()
if err != nil {
fmt.Printf("%v", err)
}
conf := &config{}
err = viper.Unmarshal(conf)
if err != nil {
fmt.Printf("unable to decode into config struct, %v", err)
}
return conf
}
// Initialization routine.
func init() {
// Retrieve config options.
conf = getConf()
}
// Main program.
func main() {
// Print the config options from the new conf struct instance.
fmt.Printf("Hostname: %v\n", conf.Hostname)
fmt.Printf("Port: %v\n", conf.Port)
}
hostname: "localhost"
port: "9001"
@sjames-iberis
Copy link

Just to clarify one point (I wasted some time because of it).
In the example, I don't think the yaml field tags have any effect.
My understanding is that they only come into play if yaml is being loaded directly into a struct; in this case, the yaml is first loaded into a viper map (by the ReadInConfig() call), and subsequently unmarshalled into the struct (by the Unmarshal() call).

@gtors
Copy link

gtors commented Apr 3, 2019

I have replaced yaml tag to mapstructure and code become workable

@maxiride
Copy link

Why on line 31 you used a pointer to the config struct?
What's the reasoning behind it?

@adampetrovic
Copy link

@maxiride because Unmarshal mutates the members of the Config struct, which can only be done if you pass a reference to the object.

@kunKun-tx
Copy link

Just to clarify one point (I wasted some time because of it).
In the example, I don't think the yaml field tags have any effect.
My understanding is that they only come into play if yaml is being loaded directly into a struct; in this case, the yaml is first loaded into a viper map (by the ReadInConfig() call), and subsequently unmarshalled into the struct (by the Unmarshal() call).

Can confirm. I can load them w/o any issue on .toml file w/o struct tags.

@pegahcarter
Copy link

pegahcarter commented May 24, 2020

Kind of interesting, you don't actually need double quotes within your config struct. This would also work:

// Create private data struct to hold config options.
type config struct {
	Hostname string `yaml:hostname`
	Port     string `yaml:port`
}

@andorus911
Copy link

andorus911 commented Oct 7, 2020

Hmm. It didn't work. Maybe because I'd used snake_case

upd
Yeah, I was right: spf13/viper#125

@SubashMourougayane
Copy link

How to make this work for TOML file?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment