conf

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Sep 10, 2025 License: MPL-2.0 Imports: 15 Imported by: 0

README ยถ

feconf

Go Version Go Report Card Test Coverage Build Status Documentation Code Size

A flexible, URI-based configuration management library for Go that supports multiple protocols, formats, and real-time configuration updates.

Features

  • ๐ŸŒ Multiple Protocols: Support for HTTP/HTTPS, WebSocket, Redis, and local files
  • ๐Ÿ“„ Multiple Formats: JSON, YAML, INI, TOML, and XML configuration formats
  • ๐Ÿ”„ Real-time Updates: Subscribe to configuration changes with automatic reloading
  • ๐Ÿšฉ Command-line Flags: Built-in support for reading configuration URI from flags
  • ๐Ÿ”Œ Extensible: Plugin-based architecture for custom readers and decoders
  • โšก Performance: Efficient parsing with connection pooling and retry mechanisms
  • ๐Ÿ”’ Security: TLS support with custom certificates and authentication
  • ๐Ÿ“‹ Type Safety: Strong typing with struct mapping using mapstructure
  • ๐ŸŽฃ Extensible Hooks: Built-in hook functions for type conversion and data processing

Installation

go get github.com/sower-proxy/feconf

Quick Start

package main

import (
    "fmt"
    "log"

    "github.com/sower-proxy/feconf"
    _ "github.com/sower-proxy/feconf/decoder/json"
    _ "github.com/sower-proxy/feconf/reader/file"
)

type Config struct {
    Host string `json:"host"`
    Port int    `json:"port"`
}

func main() {
    loader := conf.New[Config]("file://./config.json")
    defer loader.Close()

    config, err := loader.Load()
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Server: %s:%d\n", config.Host, config.Port)
}

For command-line flag support:

// Read config URI from -config flag, fallback to default if not provided
loader := conf.NewWithFlags[Config]("file://./default-config.json")

For real-time updates:

eventChan, _ := loader.Subscribe()
for event := range eventChan {
    if event.IsValid() {
        fmt.Printf("Config updated: %v\n", event.Config)
    }
}

Supported Protocols

File System
loader := conf.New[Config]("file:///path/to/config.json")
HTTP/HTTPS
loader := conf.New[Config]("https://api.example.com/config.yaml?timeout=30s")
WebSocket
loader := conf.New[Config]("wss://realtime.example.com/config?ping_interval=30s")
Redis
loader := conf.New[Config]("redis://localhost:6379/config-key?db=1&pool_size=10")

// For Redis hash fields
loader := conf.New[Config]("redis://localhost:6379/config-hash#field-name")
Kubernetes ConfigMap/Secret
// Read from a ConfigMap
loader := conf.New[Config]("k8s://configmap/default/app-config")

// Read a specific key from a ConfigMap
loader := conf.New[Config]("k8s://configmap/default/app-config/config.yaml")

// Read from a Secret
loader := conf.New[string]("k8s://secret/default/db-secret/password")

Supported Formats

The library automatically detects format from file extensions or can be specified via content-type parameter:

  • JSON: .json or content-type=application/json
  • YAML: .yaml, .yml or content-type=application/yaml
  • INI: .ini or content-type=text/ini
  • TOML: .toml or content-type=application/toml
  • XML: .xml or content-type=application/xml

Examples

The examples/ directory contains complete working examples:

  • File + JSON: Basic file-based configuration with JSON format
  • HTTP + YAML: HTTP-based configuration with YAML format and authentication
  • Redis + INI: Redis-based configuration with INI format
  • Redis + Hash: Redis hash field configuration with JSON format
  • WebSocket + XML: Real-time configuration updates via WebSocket with XML format
  • Kubernetes: Kubernetes ConfigMap/Secret configuration with YAML format
  • Flags: Command-line flag support for configuration URI specification
Running Examples
# File example
cd examples/file-json && go run .

# HTTP example (starts a demo server)
cd examples/http-yaml && go run .

# Redis example (requires Redis server)
cd examples/redis-ini && ./setup.sh && go run .

# Command-line flags example
cd examples/flags && go run . -config file://./prod-config.json

# WebSocket example (starts a demo WebSocket server)
cd examples/ws-xml && go run .

# Kubernetes example (requires Kubernetes cluster)
cd examples/k8s-yaml && ./setup.sh && go run .

Architecture

The library follows a modular plugin-based architecture:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Application   โ”‚    โ”‚   Configuration  โ”‚    โ”‚   Decoder       โ”‚
โ”‚                 โ”‚โ”€โ”€โ”€โ–ถโ”‚   Loader (conf)  โ”‚โ”€โ”€โ”€โ–ถโ”‚   (json/yaml/   โ”‚
โ”‚   Your Code     โ”‚    โ”‚                  โ”‚    โ”‚    ini/etc)     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                โ”‚
                                โ–ผ
                       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                       โ”‚   Reader         โ”‚
                       โ”‚   (file/http/    โ”‚
                       โ”‚   redis/ws)      โ”‚
                       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Best Practices

  1. Import required modules: Always import specific decoder and reader modules
  2. Handle errors: Always check and handle configuration loading errors
  3. Resource cleanup: Use defer loader.Close() to cleanup resources
  4. Use timeouts: Leverage context for request timeouts
  5. Validate configuration: Validate loaded configuration before use
  6. Use appropriate hook functions: Leverage built-in hook functions for common data transformations

Advanced Features

Custom Mapstructure Configuration
loader := conf.New[Config](uri)
loader.ParserConf.TagName = "config"  // Use 'config' tags instead of 'json'
loader.ParserConf.ErrorUnused = true  // Error on unused fields

// Custom hook functions can be added to the decode chain
customHook := mapstructure.ComposeDecodeHookFunc(
    conf.HookFuncDefault(),      // Default value handling
    conf.HookFuncEnvRender(),     // Environment variable rendering
    conf.HookFuncStringToBool(),  // String to boolean conversion
    conf.HookFuncStringToSlogLevel(), // String to log level conversion
    // Add your custom hooks here
)
loader.ParserConf.DecodeHook = customHook
Environment-specific Configuration
env := os.Getenv("APP_ENV")
if env == "" {
    env = "development"
}

uri := fmt.Sprintf("file://./config-%s.yaml", env)
loader := conf.New[Config](uri)

URI Query Parameters

Universal Parameters
Parameter Type Default Description Example
content-type string From file extension Specifies the MIME type to determine decoder format ?content-type=application/json
HTTP/HTTPS Parameters
Parameter Type Default Description Example
timeout duration 30s HTTP request timeout duration ?timeout=60s
retry_attempts integer 3 Number of retry attempts for failed requests ?retry_attempts=5
retry_delay duration 1s Delay between retry attempts ?retry_delay=2s
header_* string - Custom HTTP headers (format: header_<name>=<value>) ?header_Authorization=Bearer%20token
tls_insecure boolean false Skip TLS certificate verification ?tls_insecure=true
Redis Parameters
Parameter Type Default Description Example
db integer 0 Redis database number ?db=1
timeout duration 30s Redis operation timeout ?timeout=10s
pool_size integer 10 Redis connection pool size ?pool_size=20
tls_insecure boolean false Skip TLS certificate verification for REDISS ?tls_insecure=true

Hash Field Support: Use URI fragment (#field-name) to read from specific hash fields:

redis://localhost:6379/user:123?content-type=application/json#profile

License

This project is licensed under the Mozilla Public License Version 2.0 - see the LICENSE file for details.

Documentation ยถ

Index ยถ

Constants ยถ

This section is empty.

Variables ยถ

View Source
var DefaultParserConfig = mapstructure.DecoderConfig{
	DecodeHook: mapstructure.ComposeDecodeHookFunc(
		HookFuncDefault(),
		HookFuncEnvRender(),
		HookFuncStringToBool(),
		HookFuncStringToSlogLevel(),
		mapstructure.StringToTimeDurationHookFunc(),
		mapstructure.StringToSliceHookFunc(","),
		mapstructure.StringToBasicTypeHookFunc(),
	),
	TagName:          "json",
	WeaklyTypedInput: true,
	ErrorUnused:      false,
	ZeroFields:       false,
	MatchName: func(mapKey, fieldName string) bool {
		return strings.EqualFold(strings.ReplaceAll(mapKey, "_", ""), fieldName)
	},
}

DefaultParserConfig ้ป˜่ฎค่งฃๆžๅ™จ้…็ฝฎ

Functions ยถ

func HookFuncDefault ยถ

func HookFuncDefault() mapstructure.DecodeHookFuncType

HookFuncDefault ้ป˜่ฎคๅ€ผ้’ฉๅญ๏ผŒๅฝ“ๅ…ถไป–้’ฉๅญ้ƒฝๆ— ๆณ•ๅค„็†ๆ—ถๆไพ›้ป˜่ฎคๅ€ผ

func HookFuncEnvRender ยถ

func HookFuncEnvRender() mapstructure.DecodeHookFuncType

HookFuncEnvRender ็Žฏๅขƒๅ˜้‡ๆธฒๆŸ“้’ฉๅญ

func HookFuncStringToBool ยถ

func HookFuncStringToBool() mapstructure.DecodeHookFuncType

HookFuncStringToBool ๅญ—็ฌฆไธฒๅ’Œๆ•ฐๅญ—ๅˆฐๅธƒๅฐ”ๅ€ผ็š„้’ฉๅญ

func HookFuncStringToSlogLevel ยถ

func HookFuncStringToSlogLevel() mapstructure.DecodeHookFuncType

HookFuncStringToSlogLevel ๅญ—็ฌฆไธฒๅ’Œๆ•ฐๅญ—ๅˆฐslog.Level็š„้’ฉๅญ

func Load ยถ

func Load[T any](obj *T, uri string) error

Load loads configuration from URI and unmarshals it to the provided object

func LoadCtx ยถ

func LoadCtx[T any](ctx context.Context, obj *T, uri string) error

LoadCtx loads configuration from URI with context and unmarshals it to the provided object

func LoadFlags ยถ

func LoadFlags[T any](result *T) error

LoadFlags parses struct fields and adds command-line flags for fields with 'usage' tag, parses command-line flags, maps flag values to the struct, and modifies the provided struct pointer This is a public entry function for flag parsing functionality

func LoadFlagsCtx ยถ

func LoadFlagsCtx[T any](ctx context.Context, config *T) error

LoadFlagsCtx parses struct fields and adds command-line flags for fields with 'usage' tag with context support, parses command-line flags, maps flag values to the struct, and modifies the provided struct pointer The context can be used for cancellation or timeout during flag parsing

func LoadWithFlags ยถ

func LoadWithFlags[T any](obj *T, uriOrFlag string) error

LoadWithFlags loads configuration from URI or flag and unmarshals it to the provided object If uriOrFlag is a valid URI, it will be used as the configuration source If uriOrFlag is not a URI, it will be treated as a flag name for configuration It also parses the struct type T and adds flags for fields with 'usage' tag

func LoadWithFlagsCtx ยถ

func LoadWithFlagsCtx[T any](ctx context.Context, obj *T, uriOrFlag string) error

LoadWithFlagsCtx loads configuration from URI or flag with context and unmarshals it to the provided object If uriOrFlag is a valid URI, it will be used as the configuration source If uriOrFlag is not a URI, it will be treated as a flag name for configuration It also parses the struct type T and adds flags for fields with 'usage' tag The context can be used for cancellation or timeout during loading

Types ยถ

type ConfEvent ยถ

type ConfEvent[T any] struct {
	SourceURI string    `json:"source_uri"`
	Timestamp time.Time `json:"timestamp"`
	Error     error     `json:"error,omitempty"`
	Config    *T        `json:"config,omitempty"`
}

func (*ConfEvent[T]) IsValid ยถ

func (c *ConfEvent[T]) IsValid() bool

type ConfOpt ยถ

type ConfOpt[T any] struct {
	ParserConf mapstructure.DecoderConfig
	// contains filtered or unexported fields
}

func New ยถ

func New[T any](uri string) *ConfOpt[T]

func NewWithFlags ยถ

func NewWithFlags[T any](uriOrFlag string) *ConfOpt[T]

NewWithFlags creates a configuration loader that reads URI from command-line flags If uriOrFlag is a valid URI, it will be used as the configuration source If uriOrFlag is not a URI, it will be treated as a flag name for configuration It also parses the struct type T and adds flags for fields with 'usage' tag

func NewWithFlagsCtx ยถ

func NewWithFlagsCtx[T any](ctx context.Context, uriOrFlag string) *ConfOpt[T]

NewWithFlagsCtx creates a configuration loader that reads URI from command-line flags with context support If uriOrFlag is a valid URI, it will be used as the configuration source If uriOrFlag is not a URI, it will be treated as a flag name for configuration It also parses the struct type T and adds flags for fields with 'usage' tag The context can be used for cancellation or timeout during flag parsing

func (*ConfOpt[T]) Close ยถ

func (c *ConfOpt[T]) Close() error

func (*ConfOpt[T]) Load ยถ

func (c *ConfOpt[T]) Load(obj *T) error

Load loads configuration and unmarshals it to the provided object

func (*ConfOpt[T]) LoadCtx ยถ

func (c *ConfOpt[T]) LoadCtx(ctx context.Context, obj *T) error

LoadCtx loads configuration with context and unmarshals it to the provided object

func (*ConfOpt[T]) Parse ยถ

func (c *ConfOpt[T]) Parse() (*T, error)

func (*ConfOpt[T]) ParseCtx ยถ

func (c *ConfOpt[T]) ParseCtx(ctx context.Context) (*T, error)

func (*ConfOpt[T]) Subscribe ยถ

func (c *ConfOpt[T]) Subscribe() (<-chan *ConfEvent[T], error)

func (*ConfOpt[T]) SubscribeCtx ยถ

func (c *ConfOpt[T]) SubscribeCtx(ctx context.Context) (<-chan *ConfEvent[T], error)

Directories ยถ

Path Synopsis
ini
xml
k8s
Package k8s provides a configuration reader implementation for Kubernetes ConfigMaps and Secrets.
Package k8s provides a configuration reader implementation for Kubernetes ConfigMaps and Secrets.
ws

Jump to

Keyboard shortcuts

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