Im trying to setup a config struct to use through my application.
Currently I load a yaml file and decode it in my config struct.
config.yml
database_url: postgres://postgres:@localhost:5432/database_dev
config.go
import (
"os"
"gopkg.in/yaml.v2"
)
type AppConfig struct {
DatabaseUrl string `yaml:"database_url"`
}
func LoadConfig() *AppConfig {
appConfig := &AppConfig{}
file, _ := os.Open("config.yml")
defer f.Close()
decoder := yaml.NewDecoder(file)
decoder.Decode(config)
return appConfig
}
It works really fine, but now I need to setup different configuration according with the environment (test, local, production, etc.).
I thought that I could use a nested yaml file to declare the environments variables.
config.yml
dev:
database_url: postgres://postgres:@localhost:5432/database_dev
test:
database_url: postgres://postgres:@localhost:5432/database_test
I would like to receive the environment as a parameter in my LoadConfig
function, and get the correct configuration.
But I have no idea how to.
config.go
type configFile struct {
Dev struct { AppConfig }`yaml:"dev"`
Test struct { AppConfig }`yaml:"test"`
}
func LoadConfig(env string) *AppConfig {
appConfig := &AppConfig{}
configFile := &configFile{}
file, _ := os.Open("config.yml")
defer f.Close()
decoder := yaml.NewDecoder(file)
decoder.Decode(configFile)
// How to get the correct struct here ?
// config = configFile["env"]
// It doesn't works
// invalid operation: cannot index configFile (variable of type *configFile)
return appConfig
}
Any suggestion is welcome.
CodePudding user response:
If the list of environments is arbitrary, then you don't want a struct
for the top level; you want a map[string]AppConfig
. That would look something like this:
package main
import (
"fmt"
"os"
"gopkg.in/yaml.v2"
)
type (
AppConfig struct {
DatabaseUrl string `yaml:"database_url"`
}
ConfigFile map[string]*AppConfig
)
func LoadConfig(env string) (*AppConfig, error) {
configFile := ConfigFile{}
file, _ := os.Open("config.yml")
defer file.Close()
decoder := yaml.NewDecoder(file)
// Always check for errors!
if err := decoder.Decode(&configFile); err != nil {
return nil, err
}
appConfig, ok := configFile[env]
if !ok {
return nil, fmt.Errorf("no such environment: %s", env)
}
return appConfig, nil
}
func main() {
appConfig, err := LoadConfig(os.Args[1])
if err != nil {
panic(err)
}
fmt.Printf("config: % v\n", appConfig)
}
Assuming we have the config.yml
from your question, we can run the above example with different environments and see the desired output:
$ ./example test
config: &{DatabaseUrl:postgres://postgres:@localhost:5432/database_test}
$ ./example dev
config: &{DatabaseUrl:postgres://postgres:@localhost:5432/database_dev}
CodePudding user response:
I think furthermore setting up a config file ,you should create a YML file and put this the server port... Unfortunately I am inexperienced Therefore, I may not have given the correct answer.