config

package
v0.0.0-...-d5bc55e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2023 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package config implements a model based config system for your app. It's based on Viper. Instead of using Viper's Get and Set, this package binds all config to a struct, and you can get values by codes like

fmt.Println(Config.Foo.Bar)

This structured config makes it easy and straightforward to get config values. And it's also avoiding viper's string problems:

  1. Get("typo"): it's annoying to debug typos in strings. Compiler do nothing to make sure you are getting a right value. You can only find those issues at runtime as unexpected empty value errors.

  2. We have no place (inside the project) to see what configs are required and what types they are. I heat writing codes with a sample config file aside.

You can use config.Init to read (and watch) config from file or environment variables and bind it to a struct.

This package also provides a BaseConfig struct, which is a base struct for common configs can be applied in a crud app. It's a good idea to embed it in your own config struct.

Example:

type MyConfig struct {
       BaseConfig `mapstructure:",squash"`
       Foo        string
       Bar        int
   }
   var config MyConfig

   err := Init(&config,
       FromFile("./test_config.yaml"),  // read config from file
       FromEnv("MYAPP"),  // read config from env with prefix MYAPP, for example MYAPP_FOO, MYAPP_DB_DSN
       WatchFileChange(func(oldConfig any, newConfig any) {  // only file changes are watched, env changes will not trigger.
           logger.WithField("oldConfig", oldConfig).
               WithField("newConfig", newConfig).
               Info("config changed")
       }),
   )
   if err != nil {
       logger.WithError(err).Fatal("failed to read config.")
   }

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrConfigNotPtrToStruct = errors.New("config must be a pointer to struct")

Functions

func Init

func Init(configModel any, options ...Option) error

Init reads configure, write values into given configModel

  • FromFile: read config from file
  • FromEnv: read config from environment variables
  • WatchFileChange: watch config file and reload config when changed
Example
type MyConfig struct {
	BaseConfig `mapstructure:",squash"`
	Foo        string
	Bar        int
}
var config MyConfig

err := Init(&config,
	FromFile("./test_config.yaml"),
	FromEnv("MYAPP"),
	WatchFileChange(func(oldConfig any, newConfig any) {
		logger.WithField("oldConfig", oldConfig).
			WithField("newConfig", newConfig).
			Info("config changed")
	}),
)
if err != nil {
	logger.WithError(err).Fatal("failed to read config.")
}
Output:

Types

type BaseConfig

type BaseConfig struct {
	DB       DBConfig   // database config
	HTTP     HTTPConfig // http listen config
	LogLevel string     // log level
}

BaseConfig includes common config for services

type DBConfig

type DBConfig struct {
	Driver string // db driver name: sqlite, mysql, postgres
	DSN    string // db connection string
}

DBConfig is the configurations for connecting database

type HTTPConfig

type HTTPConfig struct {
	Addr string // listen address: ":8080"

}

HTTPConfig is the configurations for HTTP server

type Option

type Option func(configModel any) error

func FromEnv

func FromEnv(prefix string) Option

FromEnv reads config from environment variables, and unmarshal to config prefix is the prefix of environment variables:

type MyConfig struct {
    Foo struct {
        Bar string
    }
}
config := MyConfig{}
config.Init(&config, FromEnv("MYAPP"))

will read `config.Foo.Bar` from env `MYAPP_FOO_BAR`.

func FromFile

func FromFile(path string) Option

FromFile reads config from file at path, and unmarshal to config. YAML, JSON, TOML, etc. files are supported. This is the recommended way to read config.

func WatchFileChange

func WatchFileChange(hook func(oldConfig any, newConfig any)) Option

WatchFileChange works with FromFile:

var config MyConfig
config.Init(&config, FromFile(path), WatchFileChange(hook))

WatchFileChange watch current viper config file, and reload config when changed.

Notice: you do not need to reset your `config` variable in the hook, we will do it for you. BUT THIS FEATURE MAKE THE `config` NOT THREAD-SAFE. It's to be fixed in the future.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL