Documentation
¶
Overview ¶
Package konf provides a general-purpose configuration API and abstract interfaces to back that API. Packages in the Go ecosystem can depend on this package, while callers can load configuration from whatever source is appropriate.
It defines a type, Config, which provides a method Config.Unmarshal for loading configuration under the given path into the given object.
Each Config is associated with multiple Loader(s), Which load configuration from a source, such as file, environment variables etc. There is a default Config accessible through top-level functions (such as Unmarshal and Get) that call the corresponding Config methods.
Configuration is hierarchical, and the path is a sequence of keys that separated by delimiter. The default delimiter is `.`, which makes configuration path like `parent.child.key`.
Load Configuration ¶
After creating a Config, you can load configuration from multiple Loader(s) using Config.Load. Each loader takes precedence over the loaders before it. As long as the configuration has been loaded, it can be used in following code to get or unmarshal configuration, even for loading configuration from another source. For example, it can read config file path from environment variables, and then use the file path to load configuration from file system.
Watch Changes ¶
Config.Watch watches and updates configuration when it changes, which leads Config.Unmarshal always returns latest configuration. You may use Config.OnChange to register a callback if the value of any path have been changed. It could push the change into application objects instead pulling the configuration periodically.
Field Tags ¶
When decoding to a struct, konf will use the field name by default to perform the mapping. For example, if a struct has a field "Username" then konf will look for a key in the source value of "username" (case insensitive).
type User struct { Username string }
You can change the behavior of konf by using struct tags. The default struct tag that konf looks for is "konf" but you can customize it using DecoderConfig.
Renaming Fields ¶
To rename the key that konf looks for, use the "konf" tag and set a value directly. For example, to change the "username" example above to "user":
type User struct { Username string `konf:"user"` }
Embedded Structs and Squashing ¶
Embedded structs are treated as if they're another field with that name. By default, the two structs below are equivalent when decoding with konf:
type Person struct { Name string } type Friend struct { Person } type Friend struct { Person Person }
This would require an input that looks like below:
map[string]interface{}{ "person": map[string]interface{}{"name": "alice"}, }
If your "person" value is NOT nested, then you can append ",squash" to your tag value and konf will treat it as if the embedded struct were part of the struct directly. Example:
type Friend struct { Person `konf:",squash"` }
Now the following input would be accepted:
map[string]interface{}{ "name": "alice", }
Unexported fields ¶
Since unexported (private) struct fields cannot be set outside the package where they are defined, the decoder will simply skip them.
For this output type definition:
type Exported struct { private string // this unexported field will be skipped Public string }
Using this map as input:
map[string]interface{}{ "private": "I will be ignored", "Public": "I made it through!", }
The following struct will be decoded:
type Exported struct { private: "" // field is left with an empty string (zero value) Public: "I made it through!" }
Index ¶
- func Explain(path string) string
- func Get[T any](path string) T
- func OnChange(onChange func(), paths ...string)
- func SetDefault(config *Config)
- func Unmarshal(path string, target any) error
- type Config
- func (c *Config) Exists(path []string) bool
- func (c *Config) Explain(path string) string
- func (c *Config) Load(loader Loader) error
- func (c *Config) OnChange(onChange func(*Config), paths ...string)
- func (c *Config) Unmarshal(path string, target any) error
- func (c *Config) Watch(ctx context.Context) error
- type Loader
- type Option
- func WithCaseSensitive() Option
- func WithDecodeHook[F, T any, FN func(F) (T, error) | func(F, T) error](hook FN) Option
- func WithDelimiter(delimiter string) Option
- func WithLogHandler(handler slog.Handler) Option
- func WithMapKeyCaseSensitive() Option
- func WithOnStatus(onStatus func(loader Loader, changed bool, err error)) Option
- func WithTagName(tagName string) Option
- type Statuser
- type Watcher
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Explain ¶ added in v0.7.0
Explain provides information about how default Config resolve each value from loaders for the given path. It blur sensitive information. The path is case-insensitive unless konf.WithCaseSensitive is set.
func Get ¶
Get retrieves the value under the given path from the default Config. It returns the zero value of the expected type if there is an error. The path is case-insensitive unless konf.WithCaseSensitive is set.
Example ¶
package main import ( "embed" "fmt" "github.com/nil-go/konf" "github.com/nil-go/konf/provider/env" kfs "github.com/nil-go/konf/provider/fs" ) func main() { ExampleSetDefault() fmt.Print(konf.Get[string]("server.host")) } //go:embed testdata var testdata embed.FS func ExampleSetDefault() { var config konf.Config if err := config.Load(kfs.New(testdata, "testdata/config.json")); err != nil { panic(err) } if err := config.Load(env.New(env.WithPrefix("server"))); err != nil { panic(err) } konf.SetDefault(&config) }
Output: example.com
func OnChange ¶
func OnChange(onChange func(), paths ...string)
OnChange registers a callback function that is executed when the value of any given path in the default Config changes. The paths are case-insensitive unless konf.WithCaseSensitive is set.
The register function must be non-blocking and usually completes instantly. If it requires a long time to complete, it should be executed in a separate goroutine.
This method is concurrent-safe.
func SetDefault ¶
func SetDefault(config *Config)
SetDefault sets the given Config as the default Config. After this call, the konf package's top functions (e.g. konf.Get) will interact with the given Config.
Example ¶
package main import ( "embed" "github.com/nil-go/konf" "github.com/nil-go/konf/provider/env" kfs "github.com/nil-go/konf/provider/fs" ) //go:embed testdata var testdata embed.FS func main() { var config konf.Config if err := config.Load(kfs.New(testdata, "testdata/config.json")); err != nil { // Handle error here. panic(err) } if err := config.Load(env.New(env.WithPrefix("server"))); err != nil { // Handle error here. panic(err) } konf.SetDefault(&config) }
Output:
func Unmarshal ¶
Unmarshal reads configuration under the given path from the default Config and decodes it into the given object pointed to by target. The path is case-insensitive unless konf.WithCaseSensitive is set.
Example ¶
package main import ( "embed" "fmt" "github.com/nil-go/konf" "github.com/nil-go/konf/provider/env" kfs "github.com/nil-go/konf/provider/fs" ) func main() { ExampleSetDefault() cfg := struct { Host string Port int }{ Host: "localhost", Port: 8080, } if err := konf.Unmarshal("server", &cfg); err != nil { // Handle error here. panic(err) } fmt.Printf("%s:%d\n", cfg.Host, cfg.Port) } //go:embed testdata var testdata embed.FS func ExampleSetDefault() { var config konf.Config if err := config.Load(kfs.New(testdata, "testdata/config.json")); err != nil { panic(err) } if err := config.Load(env.New(env.WithPrefix("server"))); err != nil { panic(err) } konf.SetDefault(&config) }
Output: example.com:8080
Types ¶
type Config ¶
type Config struct {
// contains filtered or unexported fields
}
Config reads configuration from appropriate sources.
To create a new Config, call New.
func (*Config) Exists ¶
Exists tests if the given path exist in the configuration.
It's used by the loader to check if the configuration has been set by other loaders.
func (*Config) Explain ¶
Explain provides information about how Config resolve each value from loaders for the given path. It blur sensitive information. The path is case-insensitive unless konf.WithCaseSensitive is set.
func (*Config) Load ¶
Load loads configuration from the given loader. Each loader takes precedence over the loaders before it.
This method is concurrent-safe.
func (*Config) OnChange ¶
OnChange registers a callback function that is executed when the value of any given path in the Config changes. It requires Config.Watch has been called first. The paths are case-insensitive unless konf.WithCaseSensitive is set.
The register function must be non-blocking and usually completes instantly. If it requires a long time to complete, it should be executed in a separate goroutine.
This method is concurrent-safe.
type Loader ¶
Loader is the interface that wraps the Load method.
Load loads the latest configuration and returns it as a nested map[string]any. The keys should be nested like `{parent: {child: {key: 1}}}`.
type Option ¶
type Option func(*options)
Option configures a Config with specific options.
func WithCaseSensitive ¶ added in v0.9.0
func WithCaseSensitive() Option
WithCaseSensitive enables the case sensitivity of the configuration keys.
func WithDecodeHook ¶
WithDecodeHook provides the decode hook for decoding. The decode hook is a function that can customize how configuration are decoded.
It can be either `func(F) (T, error)` which returns the converted value, or `func(F, T) error` which sets the converted value inline.
By default, it composes string to time.Duration, string to []string split by `,` and string to encoding.TextUnmarshaler.
func WithDelimiter ¶
WithDelimiter provides the delimiter used when specifying config paths. The delimiter is used to separate keys in the path.
For example, with the default delimiter `.`, a config path might look like `parent.child.key`.
func WithLogHandler ¶
WithLogHandler provides the slog.Handler for logs from watch.
By default, it uses handler from slog.Default().
func WithMapKeyCaseSensitive ¶ added in v1.2.0
func WithMapKeyCaseSensitive() Option
WithMapKeyCaseSensitive enables the case sensitivity of the map keys.
func WithOnStatus ¶ added in v0.8.0
WithOnStatus provides the callback for monitoring status of configuration loading/watching.
func WithTagName ¶
WithTagName provides the tag name that reads for field names. The tag name is used when decoding configuration into structs.
For example, with the default tag name `konf`, it would look for `konf` tags on struct fields.
type Statuser ¶ added in v0.8.0
Statuser is the interface that wraps the Status method.
Status enables providers report the status of configuration watching.
Directories
¶
Path | Synopsis |
---|---|
notifier
|
|
azservicebus
Module
|
|
pubsub
Module
|
|
sns
Module
|
|
provider
|
|
env
Package env loads configuration from environment variables.
|
Package env loads configuration from environment variables. |
flag
Package flag loads configuration from flags defined by flag.
|
Package flag loads configuration from flags defined by flag. |
fs
Package fs loads configuration from file system.
|
Package fs loads configuration from file system. |
appconfig
Module
|
|
azappconfig
Module
|
|
azblob
Module
|
|
file
Module
|
|
gcs
Module
|
|
parameterstore
Module
|
|
pflag
Module
|
|
s3
Module
|
|
secretmanager
Module
|