/config

Simple and lightweight yet powerful and modulable configuration package

Primary LanguageGoMIT LicenseMIT

config

godoc Licence Latest version

Build Status Code quality Code coverage

A simple yet powerful configuration package.

Motivation

On any project I've made personnally or for a company, except if the project was really (really) small, I always needed at some point to be able to configure a component in the project (the http listening port, the database credentials, a business configuration, ...). I've been using viper for some times now, but I was not really happy about it for some reasons (usage of strings keys to get configuration, globally defined configuration which are a p.i.t.a. in big project to understand what's used where, and to concurently use and modify in test, ...). I also used confita from which this project was inspired.

From my point of view a configuration package should:

  • have a priorization of "sources" (for example file < env < cli args)
  • be strongly typed (it should never use string keys to get a value, or return interface{} left for the call to cast)
  • be modulable (add a new "source" to retrieve configuration from vauld or consul for example)
  • handle defaults values (without string keys, and as close as the configuration definition)
  • have a clear and easy to use API
  • be light
  • encourage and follow the best practices

That's what I tried to do in this configuration package which is made of 4 components:

  • the default setter which handles defaults
  • the sources (anything that implements one of the two sources interfaces) responsible for the retrieval of the configuration
  • the "loader" which is responsible to set the default if any and to call each sources
  • additionally, a validation can be made to make sure configuration is valid

Usage / examples

// let's define a structure that hold our http configuration, for example
type HTTPConfig struct {
    Debug          bool
    ListenAddress  string
    RequestTimeout time.Duration 
    MACSecret      []byte
}

// SetDefault sets sane default for http config.
func (c *HTTPConfig) SetDefault() {
    c.ListenAddress = ":8080"
    c.RequestTimeout = 3 * time.Second
}

// Validate checks whenever the config is properly set.
func (c *HTTPConfig) Validate() error {
    if c.RequestTimeout < time.Second {
        return errors.New("request timeout is too short (min 1s)")
    }
}

func main() {
    // export PREFIX_DEBUG="true"
    // export PREFIX_MACSECRET="secret"
    // echo "{ "listen-address": ":8082" }" > ./conf.json

    var cfg HTTPConfig

    if err := config.Load(&cfg, config.WithSources(config.Source{
        sourcefile.New("./conf.json"),
        sourceenv.New("prefix"),
    })); err != nil {
        panic(err)
    }

    if err := config.Validate(&cfg); err != nil {
        panic(err)
    }

    // cfg.Debug          = "true"
    // cfg.ListenAddress  = ":8082"
    // cfg.RequestTimeout = "3s"
    // cfg.MACSecret      = "secret"
}

More doc and examples in the config's godoc

License

This project is under the MIT licence, please see the LICENCE file.