config

package
v1.0.14 Latest Latest
Warning

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

Go to latest
Published: Jan 3, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

README

ResolveSpec Configuration System

A centralized configuration system with support for multiple configuration sources: config files (YAML, TOML, JSON), environment variables, and programmatic configuration.

Features

  • Multiple Config Sources: Config files, environment variables, and code
  • Priority Order: Environment variables > Config file > Defaults
  • Multiple Formats: YAML, TOML, JSON supported
  • Type Safety: Strongly-typed configuration structs
  • Sensible Defaults: Works out of the box with reasonable defaults

Quick Start

Basic Usage
import "github.com/heinhel/ResolveSpec/pkg/config"

// Create a new config manager
mgr := config.NewManager()

// Load configuration from file and environment
if err := mgr.Load(); err != nil {
    log.Fatal(err)
}

// Get the complete configuration
cfg, err := mgr.GetConfig()
if err != nil {
    log.Fatal(err)
}

// Use the configuration
fmt.Println("Server address:", cfg.Server.Addr)
Custom Configuration Paths
mgr := config.NewManagerWithOptions(
    config.WithConfigFile("/path/to/config.yaml"),
    config.WithEnvPrefix("MYAPP"),
)

Configuration Sources

1. Config Files

Place a config.yaml file in one of these locations:

  • Current directory (.)
  • ./config/
  • /etc/resolvespec/
  • $HOME/.resolvespec/

Example config.yaml:

server:
  addr: ":8080"
  shutdown_timeout: 30s

tracing:
  enabled: true
  service_name: "my-service"

cache:
  provider: "redis"
  redis:
    host: "localhost"
    port: 6379
2. Environment Variables

All configuration can be set via environment variables with the RESOLVESPEC_ prefix:

export RESOLVESPEC_SERVER_ADDR=":9090"
export RESOLVESPEC_TRACING_ENABLED=true
export RESOLVESPEC_CACHE_PROVIDER=redis
export RESOLVESPEC_CACHE_REDIS_HOST=localhost

Nested configuration uses underscores:

  • server.addrRESOLVESPEC_SERVER_ADDR
  • cache.redis.hostRESOLVESPEC_CACHE_REDIS_HOST
3. Programmatic Configuration
mgr := config.NewManager()
mgr.Set("server.addr", ":9090")
mgr.Set("tracing.enabled", true)

cfg, _ := mgr.GetConfig()

Configuration Options

Server Configuration
server:
  addr: ":8080"              # Server address
  shutdown_timeout: 30s       # Graceful shutdown timeout
  drain_timeout: 25s          # Connection drain timeout
  read_timeout: 10s           # HTTP read timeout
  write_timeout: 10s          # HTTP write timeout
  idle_timeout: 120s          # HTTP idle timeout
Tracing Configuration
tracing:
  enabled: false                                  # Enable/disable tracing
  service_name: "resolvespec"                     # Service name
  service_version: "1.0.0"                        # Service version
  endpoint: "http://localhost:4318/v1/traces"     # OTLP endpoint
Cache Configuration
cache:
  provider: "memory"  # Options: memory, redis, memcache

  redis:
    host: "localhost"
    port: 6379
    password: ""
    db: 0

  memcache:
    servers:
      - "localhost:11211"
    max_idle_conns: 10
    timeout: 100ms
Logger Configuration
logger:
  dev: false    # Development mode (human-readable output)
  path: ""      # Log file path (empty = stdout)
Middleware Configuration
middleware:
  rate_limit_rps: 100.0       # Requests per second
  rate_limit_burst: 200        # Burst size
  max_request_size: 10485760   # Max request size in bytes (10MB)
CORS Configuration
cors:
  allowed_origins:
    - "*"
  allowed_methods:
    - "GET"
    - "POST"
    - "PUT"
    - "DELETE"
    - "OPTIONS"
  allowed_headers:
    - "*"
  max_age: 3600
Database Configuration
database:
  url: "host=localhost user=postgres password=postgres dbname=mydb port=5432 sslmode=disable"

Priority and Overrides

Configuration sources are applied in this order (highest priority first):

  1. Environment Variables (highest priority)
  2. Config File
  3. Defaults (lowest priority)

This allows you to:

  • Set defaults in code
  • Override with a config file
  • Override specific values with environment variables

Examples

Production Setup
# config.yaml
server:
  addr: ":8080"

tracing:
  enabled: true
  service_name: "myapi"
  endpoint: "http://jaeger:4318/v1/traces"

cache:
  provider: "redis"
  redis:
    host: "redis"
    port: 6379
    password: "${REDIS_PASSWORD}"

logger:
  dev: false
  path: "/var/log/myapi/app.log"
Development Setup
# Use environment variables for development
export RESOLVESPEC_LOGGER_DEV=true
export RESOLVESPEC_TRACING_ENABLED=false
export RESOLVESPEC_CACHE_PROVIDER=memory
Testing Setup
// Override config for tests
mgr := config.NewManager()
mgr.Set("cache.provider", "memory")
mgr.Set("database.url", testDBURL)

cfg, _ := mgr.GetConfig()

Best Practices

  1. Use config files for base configuration - Define your standard settings
  2. Use environment variables for secrets - Never commit passwords/tokens
  3. Use environment variables for deployment-specific values - Different per environment
  4. Keep defaults sensible - Application should work with minimal configuration
  5. Document your configuration - Comment your config.yaml files

Integration with ResolveSpec Components

The configuration system integrates seamlessly with ResolveSpec components:

cfg, _ := config.NewManager().Load().GetConfig()

// Server
srv := server.NewGracefulServer(server.Config{
    Addr:            cfg.Server.Addr,
    ShutdownTimeout: cfg.Server.ShutdownTimeout,
    // ... other fields
})

// Tracing
if cfg.Tracing.Enabled {
    tracer := tracing.Init(tracing.Config{
        ServiceName:    cfg.Tracing.ServiceName,
        ServiceVersion: cfg.Tracing.ServiceVersion,
        Endpoint:       cfg.Tracing.Endpoint,
    })
    defer tracer.Shutdown(context.Background())
}

// Cache
var cacheProvider cache.Provider
switch cfg.Cache.Provider {
case "redis":
    cacheProvider = cache.NewRedisProvider(cfg.Cache.Redis.Host, cfg.Cache.Redis.Port, ...)
case "memcache":
    cacheProvider = cache.NewMemcacheProvider(cfg.Cache.Memcache.Servers, ...)
default:
    cacheProvider = cache.NewMemoryProvider()
}

// Logger
logger.Init(cfg.Logger.Dev)
if cfg.Logger.Path != "" {
    logger.UpdateLoggerPath(cfg.Logger.Path, cfg.Logger.Dev)
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CORSConfig

type CORSConfig struct {
	AllowedOrigins []string `mapstructure:"allowed_origins"`
	AllowedMethods []string `mapstructure:"allowed_methods"`
	AllowedHeaders []string `mapstructure:"allowed_headers"`
	MaxAge         int      `mapstructure:"max_age"`
}

CORSConfig holds CORS configuration

type CacheConfig

type CacheConfig struct {
	Provider string         `mapstructure:"provider"` // memory, redis, memcache
	Redis    RedisConfig    `mapstructure:"redis"`
	Memcache MemcacheConfig `mapstructure:"memcache"`
}

CacheConfig holds cache provider configuration

type Config

type Config struct {
	Servers       ServersConfig          `mapstructure:"servers"`
	Tracing       TracingConfig          `mapstructure:"tracing"`
	Cache         CacheConfig            `mapstructure:"cache"`
	Logger        LoggerConfig           `mapstructure:"logger"`
	ErrorTracking ErrorTrackingConfig    `mapstructure:"error_tracking"`
	Middleware    MiddlewareConfig       `mapstructure:"middleware"`
	CORS          CORSConfig             `mapstructure:"cors"`
	EventBroker   EventBrokerConfig      `mapstructure:"event_broker"`
	DBManager     DBManagerConfig        `mapstructure:"dbmanager"`
	Paths         PathsConfig            `mapstructure:"paths"`
	Extensions    map[string]interface{} `mapstructure:"extensions"`
}

Config represents the complete application configuration

type DBConnectionConfig added in v1.0.6

type DBConnectionConfig struct {
	// Name is the unique name of this connection
	Name string `mapstructure:"name"`

	// Type is the database type (postgres, sqlite, mssql, mongodb)
	Type string `mapstructure:"type"`

	// DSN is the complete Data Source Name / connection string
	// If provided, this takes precedence over individual connection parameters
	DSN string `mapstructure:"dsn"`

	// Connection parameters (used if DSN is not provided)
	Host     string `mapstructure:"host"`
	Port     int    `mapstructure:"port"`
	User     string `mapstructure:"user"`
	Password string `mapstructure:"password"`
	Database string `mapstructure:"database"`

	// PostgreSQL/MSSQL specific
	SSLMode string `mapstructure:"sslmode"` // disable, require, verify-ca, verify-full
	Schema  string `mapstructure:"schema"`  // Default schema

	// SQLite specific
	FilePath string `mapstructure:"filepath"`

	// MongoDB specific
	AuthSource     string `mapstructure:"auth_source"`
	ReplicaSet     string `mapstructure:"replica_set"`
	ReadPreference string `mapstructure:"read_preference"` // primary, secondary, etc.

	// Connection pool settings (overrides global defaults)
	MaxOpenConns    *int           `mapstructure:"max_open_conns"`
	MaxIdleConns    *int           `mapstructure:"max_idle_conns"`
	ConnMaxLifetime *time.Duration `mapstructure:"conn_max_lifetime"`
	ConnMaxIdleTime *time.Duration `mapstructure:"conn_max_idle_time"`

	// Timeouts
	ConnectTimeout time.Duration `mapstructure:"connect_timeout"`
	QueryTimeout   time.Duration `mapstructure:"query_timeout"`

	// Features
	EnableTracing bool `mapstructure:"enable_tracing"`
	EnableMetrics bool `mapstructure:"enable_metrics"`
	EnableLogging bool `mapstructure:"enable_logging"`

	// DefaultORM specifies which ORM to use for the Database() method
	// Options: "bun", "gorm", "native"
	DefaultORM string `mapstructure:"default_orm"`

	// Tags for organization and filtering
	Tags map[string]string `mapstructure:"tags"`
}

DBConnectionConfig defines configuration for a single database connection

func (*DBConnectionConfig) PopulateFromDSN added in v1.0.10

func (cc *DBConnectionConfig) PopulateFromDSN() error

PopulateFromDSN parses a DSN and populates the connection fields

type DBManagerConfig added in v1.0.6

type DBManagerConfig struct {
	// DefaultConnection is the name of the default connection to use
	DefaultConnection string `mapstructure:"default_connection"`

	// Connections is a map of connection name to connection configuration
	Connections map[string]DBConnectionConfig `mapstructure:"connections"`

	// Global connection pool defaults
	MaxOpenConns    int           `mapstructure:"max_open_conns"`
	MaxIdleConns    int           `mapstructure:"max_idle_conns"`
	ConnMaxLifetime time.Duration `mapstructure:"conn_max_lifetime"`
	ConnMaxIdleTime time.Duration `mapstructure:"conn_max_idle_time"`

	// Retry policy
	RetryAttempts int           `mapstructure:"retry_attempts"`
	RetryDelay    time.Duration `mapstructure:"retry_delay"`
	RetryMaxDelay time.Duration `mapstructure:"retry_max_delay"`

	// Health checks
	HealthCheckInterval time.Duration `mapstructure:"health_check_interval"`
	EnableAutoReconnect bool          `mapstructure:"enable_auto_reconnect"`
}

DBManagerConfig contains configuration for the database connection manager

func (*DBManagerConfig) ToManagerConfig added in v1.0.6

func (c *DBManagerConfig) ToManagerConfig() interface{}

ToManagerConfig converts config.DBManagerConfig to dbmanager.ManagerConfig This is used to avoid circular dependencies

func (*DBManagerConfig) Validate added in v1.0.6

func (c *DBManagerConfig) Validate() error

Validate validates the DBManager configuration

type ErrorTrackingConfig added in v0.0.98

type ErrorTrackingConfig struct {
	Enabled          bool    `mapstructure:"enabled"`
	Provider         string  `mapstructure:"provider"`           // sentry, noop
	DSN              string  `mapstructure:"dsn"`                // Sentry DSN
	Environment      string  `mapstructure:"environment"`        // e.g., production, staging, development
	Release          string  `mapstructure:"release"`            // Application version/release
	Debug            bool    `mapstructure:"debug"`              // Enable debug mode
	SampleRate       float64 `mapstructure:"sample_rate"`        // Error sample rate (0.0-1.0)
	TracesSampleRate float64 `mapstructure:"traces_sample_rate"` // Traces sample rate (0.0-1.0)
}

ErrorTrackingConfig holds error tracking configuration

type EventBrokerConfig added in v0.0.107

type EventBrokerConfig struct {
	Enabled     bool                         `mapstructure:"enabled"`
	Provider    string                       `mapstructure:"provider"` // memory, redis, nats, database
	Mode        string                       `mapstructure:"mode"`     // sync, async
	WorkerCount int                          `mapstructure:"worker_count"`
	BufferSize  int                          `mapstructure:"buffer_size"`
	InstanceID  string                       `mapstructure:"instance_id"`
	Redis       EventBrokerRedisConfig       `mapstructure:"redis"`
	NATS        EventBrokerNATSConfig        `mapstructure:"nats"`
	Database    EventBrokerDatabaseConfig    `mapstructure:"database"`
	RetryPolicy EventBrokerRetryPolicyConfig `mapstructure:"retry_policy"`
}

EventBrokerConfig contains configuration for the event broker

type EventBrokerDatabaseConfig added in v0.0.107

type EventBrokerDatabaseConfig struct {
	TableName    string        `mapstructure:"table_name"`
	Channel      string        `mapstructure:"channel"` // PostgreSQL NOTIFY channel name
	PollInterval time.Duration `mapstructure:"poll_interval"`
}

EventBrokerDatabaseConfig contains database provider configuration

type EventBrokerNATSConfig added in v0.0.107

type EventBrokerNATSConfig struct {
	URL        string        `mapstructure:"url"`
	StreamName string        `mapstructure:"stream_name"`
	Subjects   []string      `mapstructure:"subjects"`
	Storage    string        `mapstructure:"storage"` // file, memory
	MaxAge     time.Duration `mapstructure:"max_age"`
}

EventBrokerNATSConfig contains NATS-specific configuration

type EventBrokerRedisConfig added in v0.0.107

type EventBrokerRedisConfig struct {
	StreamName    string `mapstructure:"stream_name"`
	ConsumerGroup string `mapstructure:"consumer_group"`
	MaxLen        int64  `mapstructure:"max_len"`
	Host          string `mapstructure:"host"`
	Port          int    `mapstructure:"port"`
	Password      string `mapstructure:"password"`
	DB            int    `mapstructure:"db"`
}

EventBrokerRedisConfig contains Redis-specific configuration

type EventBrokerRetryPolicyConfig added in v0.0.107

type EventBrokerRetryPolicyConfig struct {
	MaxRetries    int           `mapstructure:"max_retries"`
	InitialDelay  time.Duration `mapstructure:"initial_delay"`
	MaxDelay      time.Duration `mapstructure:"max_delay"`
	BackoffFactor float64       `mapstructure:"backoff_factor"`
}

EventBrokerRetryPolicyConfig contains retry policy configuration

type LoggerConfig

type LoggerConfig struct {
	Dev  bool   `mapstructure:"dev"`
	Path string `mapstructure:"path"`
}

LoggerConfig holds logger configuration

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager handles configuration loading from multiple sources

func NewManager

func NewManager() *Manager

NewManager creates a new configuration manager with defaults

func NewManagerWithOptions

func NewManagerWithOptions(opts ...Option) *Manager

NewManagerWithOptions creates a new configuration manager with custom options

func (*Manager) Get

func (m *Manager) Get(key string) interface{}

Get returns a configuration value by key

func (*Manager) GetBool

func (m *Manager) GetBool(key string) bool

GetBool returns a bool configuration value

func (*Manager) GetConfig

func (m *Manager) GetConfig() (*Config, error)

GetConfig returns the complete configuration

func (*Manager) GetInt

func (m *Manager) GetInt(key string) int

GetInt returns an int configuration value

func (*Manager) GetString

func (m *Manager) GetString(key string) string

GetString returns a string configuration value

func (*Manager) Load

func (m *Manager) Load() error

Load attempts to load configuration from file and environment

func (*Manager) SaveConfig added in v1.0.8

func (m *Manager) SaveConfig(path string) error

SaveConfig writes the current configuration to the specified path

func (*Manager) Set

func (m *Manager) Set(key string, value interface{})

Set sets a configuration value

func (*Manager) SetConfig added in v1.0.10

func (m *Manager) SetConfig(cfg *Config) error

SetConfig sets the complete configuration

type MemcacheConfig

type MemcacheConfig struct {
	Servers      []string      `mapstructure:"servers"`
	MaxIdleConns int           `mapstructure:"max_idle_conns"`
	Timeout      time.Duration `mapstructure:"timeout"`
}

MemcacheConfig holds Memcache-specific configuration

type MiddlewareConfig

type MiddlewareConfig struct {
	RateLimitRPS   float64 `mapstructure:"rate_limit_rps"`
	RateLimitBurst int     `mapstructure:"rate_limit_burst"`
	MaxRequestSize int64   `mapstructure:"max_request_size"`
}

MiddlewareConfig holds middleware configuration

type Option

type Option func(*Manager)

Option is a functional option for configuring the Manager

func WithConfigFile

func WithConfigFile(path string) Option

WithConfigFile sets a specific config file path

func WithConfigName

func WithConfigName(name string) Option

WithConfigName sets the config file name (without extension)

func WithConfigPath

func WithConfigPath(path string) Option

WithConfigPath adds a path to search for config files

func WithEnvPrefix

func WithEnvPrefix(prefix string) Option

WithEnvPrefix sets the environment variable prefix

type PathsConfig added in v1.0.11

type PathsConfig map[string]string

PathsConfig contains configuration for named file system paths This is a map of path name to file system path Example: "data_dir": "/var/lib/myapp/data"

func (PathsConfig) AbsPath added in v1.0.11

func (pc PathsConfig) AbsPath(name string) (string, error)

AbsPath returns the absolute path for a named path

func (PathsConfig) EnsureDir added in v1.0.11

func (pc PathsConfig) EnsureDir(name string, perm os.FileMode) error

EnsureDir ensures a directory exists at the specified path name Creates the directory if it doesn't exist with the given permissions

func (PathsConfig) Get added in v1.0.11

func (pc PathsConfig) Get(name string) (string, error)

Get retrieves a path by name

func (PathsConfig) GetOrDefault added in v1.0.11

func (pc PathsConfig) GetOrDefault(name, defaultPath string) string

GetOrDefault retrieves a path by name, returning defaultPath if not found

func (PathsConfig) Has added in v1.0.11

func (pc PathsConfig) Has(name string) bool

Has checks if a path exists by name

func (PathsConfig) Join added in v1.0.11

func (pc PathsConfig) Join(name string, elem ...string) (string, error)

Join joins path segments with a named base path

func (PathsConfig) List added in v1.0.11

func (pc PathsConfig) List() []string

List returns all configured path names

func (PathsConfig) Set added in v1.0.11

func (pc PathsConfig) Set(name, path string)

Set sets a path by name

type RedisConfig

type RedisConfig struct {
	Host     string `mapstructure:"host"`
	Port     int    `mapstructure:"port"`
	Password string `mapstructure:"password"`
	DB       int    `mapstructure:"db"`
}

RedisConfig holds Redis-specific configuration

type ServerInstanceConfig added in v1.0.11

type ServerInstanceConfig struct {
	// Name is the unique name of this server instance
	Name string `mapstructure:"name"`

	// Host is the host to bind to (e.g., "localhost", "0.0.0.0", "")
	Host string `mapstructure:"host"`

	// Port is the port number to listen on
	Port int `mapstructure:"port"`

	// Description is a human-readable description of this server
	Description string `mapstructure:"description"`

	// GZIP enables GZIP compression middleware
	GZIP bool `mapstructure:"gzip"`

	// TLS/HTTPS configuration options (mutually exclusive)
	// Option 1: Provide certificate and key files directly
	SSLCert string `mapstructure:"ssl_cert"`
	SSLKey  string `mapstructure:"ssl_key"`

	// Option 2: Use self-signed certificate (for development/testing)
	SelfSignedSSL bool `mapstructure:"self_signed_ssl"`

	// Option 3: Use Let's Encrypt / AutoTLS
	AutoTLS         bool     `mapstructure:"auto_tls"`
	AutoTLSDomains  []string `mapstructure:"auto_tls_domains"`
	AutoTLSCacheDir string   `mapstructure:"auto_tls_cache_dir"`
	AutoTLSEmail    string   `mapstructure:"auto_tls_email"`

	// Timeout configurations (overrides global defaults)
	ShutdownTimeout *time.Duration `mapstructure:"shutdown_timeout"`
	DrainTimeout    *time.Duration `mapstructure:"drain_timeout"`
	ReadTimeout     *time.Duration `mapstructure:"read_timeout"`
	WriteTimeout    *time.Duration `mapstructure:"write_timeout"`
	IdleTimeout     *time.Duration `mapstructure:"idle_timeout"`

	// Tags for organization and filtering
	Tags map[string]string `mapstructure:"tags"`
}

ServerInstanceConfig defines configuration for a single server instance

func (*ServerInstanceConfig) ApplyGlobalDefaults added in v1.0.11

func (sic *ServerInstanceConfig) ApplyGlobalDefaults(globals ServersConfig)

ApplyGlobalDefaults applies global server defaults to this instance Called for instances that don't specify their own timeout values

func (*ServerInstanceConfig) Validate added in v1.0.11

func (sic *ServerInstanceConfig) Validate() error

Validate validates the ServerInstanceConfig

type ServersConfig added in v1.0.11

type ServersConfig struct {
	// DefaultServer is the name of the default server to use
	DefaultServer string `mapstructure:"default_server"`

	// Instances is a map of server name to server configuration
	Instances map[string]ServerInstanceConfig `mapstructure:"instances"`

	// Global timeout defaults (can be overridden per instance)
	ShutdownTimeout time.Duration `mapstructure:"shutdown_timeout"`
	DrainTimeout    time.Duration `mapstructure:"drain_timeout"`
	ReadTimeout     time.Duration `mapstructure:"read_timeout"`
	WriteTimeout    time.Duration `mapstructure:"write_timeout"`
	IdleTimeout     time.Duration `mapstructure:"idle_timeout"`
}

ServersConfig contains configuration for the server manager

func (*ServersConfig) GetDefault added in v1.0.11

func (sc *ServersConfig) GetDefault() (*ServerInstanceConfig, error)

GetDefault returns the default server instance configuration

func (*ServersConfig) Validate added in v1.0.11

func (sc *ServersConfig) Validate() error

Validate validates the ServersConfig

type TracingConfig

type TracingConfig struct {
	Enabled        bool   `mapstructure:"enabled"`
	ServiceName    string `mapstructure:"service_name"`
	ServiceVersion string `mapstructure:"service_version"`
	Endpoint       string `mapstructure:"endpoint"`
}

TracingConfig holds OpenTelemetry tracing configuration

Jump to

Keyboard shortcuts

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