feconf

package module
v0.5.2 Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2026 License: MPL-2.0 Imports: 16 Imported by: 0

README

feconf

Go Version Build Status Test Coverage Go Report Card Documentation

A flexible and comfortable, URI-based configuration management library for Go with real-time updates.

Features

  • Multi-protocol: File, HTTP, WebSocket, Redis, Kubernetes
  • Multi-format: JSON, YAML, INI, TOML, XML
  • Real-time updates: Subscribe to configuration changes
  • Type-safe: Strong struct mapping with mapstructure
  • Extensible: Plugin-based architecture
  • Production-ready: TLS, retries, connection pooling

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 := feconf.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)
}

Supported Protocols

// File system
loader := feconf.New[Config]("file:///path/to/config.yaml")

// HTTP/HTTPS
loader := feconf.New[Config]("https://api.example.com/config.json")

// Redis
loader := feconf.New[Config]("redis://localhost:6379/config-key")

// WebSocket
loader := feconf.New[Config]("wss://realtime.example.com/config")

// Kubernetes
loader := feconf.New[Config]("k8s://configmap/default/app-config")

Supported Formats

  • 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

Real-time Updates

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

Command-line Flags

// Read from -config flag with fallback
loader := feconf.NewWithFlags[Config]("file://./default-config.json")

Architecture

The library follows a modular plugin-based architecture:

┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   Application   │    │   Configuration  │    │   Decoder       │
│                 │───▶│   Loader (feconf)│───▶│   (json/yaml/   │
│   Your Code     │    │                  │    │    ini/etc)     │
└─────────────────┘    └──────────────────┘    └─────────────────┘
                                │
                                ▼
                       ┌──────────────────┐
                       │   Reader         │
                       │   (file/http/    │
                       │   redis/ws)      │
                       └──────────────────┘

See ARCHITECTURE.md for system boundaries, layer ownership, data flow, and design decisions.

Examples

See the examples/ directory for complete working examples:

  • file-json/ - Basic file-based configuration
  • http-yaml/ - HTTP with authentication
  • redis-ini/ - Redis configuration
  • flags/ - Command-line flag integration
  • ws-xml/ - WebSocket real-time updates
  • k8s-yaml/ - Kubernetes ConfigMap/Secret

Run examples:

cd examples/file-json && go run .
cd examples/http-yaml && go run .

Advanced Configuration

loader := feconf.New[Config](uri)

// Custom parser settings
loader.ParserConf.TagName = "config"
loader.ParserConf.ErrorUnused = true

// Custom decode hooks
loader.ParserConf.DecodeHook = mapstructure.ComposeDecodeHookFunc(
    feconf.HookFuncDefault(),
    feconf.HookFuncEnvRender(),
    feconf.HookFuncStringToSlice(),
    feconf.HookFuncStringToBool(),
)

HookFuncStringToSlice() allows env-rendered string values to be decoded into slice fields from either JSON/YAML flow sequences such as ["a","b"] / [a, b]. Existing comma-separated string decoding remains available through the fallback CSV hook in DefaultParserConfig.

URI Parameters

Common parameters:

  • content-type - Override format detection
  • timeout - Request/operation timeout
  • retry_attempts - Number of retries

Protocol-specific parameters available for HTTP, Redis, and WebSocket connections.

Installation

go get github.com/sower-proxy/feconf

License

Mozilla Public License 2.0 - See LICENSE for details.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DefaultParserConfig = mapstructure.DecoderConfig{
	DecodeHook: mapstructure.ComposeDecodeHookFunc(
		HookFuncDefault(),
		HookFuncEnvRender(),
		HookFuncStringToSlice(),
		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 HookFuncStringToSlice added in v0.5.2

func HookFuncStringToSlice() mapstructure.DecodeHookFuncType

HookFuncStringToSlice supports structured slice literals such as JSON/YAML flow sequences while preserving the existing CSV fallback hook behavior.

func HookFuncStringToSlogLevel

func HookFuncStringToSlogLevel() mapstructure.DecodeHookFuncType

HookFuncStringToSlogLevel 字符串和数字到slog.Level的钩子

func Load

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

func LoadCtx

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

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](flag string, uris ...string) *ConfOpt[T]

func (*ConfOpt[T]) Close

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

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.

Jump to

Keyboard shortcuts

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