The configuration module provides a flexible system for managing application configuration with support for YAML files, environment variable substitution, and configuration merging.
- YAML-based Configuration: Declarative configuration using YAML files
- Environment Variable Substitution: Automatic replacement of placeholders with environment values using
${ENV:"default_value"}syntax - Expression Engine: Dynamic configuration values using expressions similar to GitHub Actions workflow syntax (
$env.ENV) - Configuration Merging: Support for base and override configurations
- Hot Reloading: Dynamic configuration updates without application restart
go get github.com/pubgo/funk/v2/configimport "github.com/pubgo/funk/v2/config"
type ServerConfig struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
}
type AppConfig struct {
Server ServerConfig `yaml:"server"`
Debug bool `yaml:"debug"`
}
// Load configuration
cfg := config.Load[AppConfig]()
// Access configuration values
fmt.Printf("Server: %s:%d\n", cfg.T.Server.Host, cfg.T.Server.Port)
fmt.Printf("Debug mode: %t\n", cfg.T.Debug)Configuration files support environment variable substitution using the ${ENV:"default_value"} syntax:
# config.yaml
server:
host: ${SERVER_HOST:"localhost"}
port: ${SERVER_PORT:8080}
database:
url: postgres://${DB_USER}:${DB_PASS}@${DB_HOST}/${DB_NAME}Advanced configuration values can be computed using expressions similar to GitHub Actions workflow syntax:
# config.yaml
app:
version: ${{env.VERSION}}
build_time: ${{env.BUILD_TIME}}
config_dir: ${{config_dir()}}
cert_data: ${{embed("cert.pem")}}Available expression functions:
env.ENV_VAR: Access environment variables (similar to GitHub Actions syntax)config_dir(): Get the configuration directoryembed(filename): Embed file content as base64
type Resources struct {
Resources []string `yaml:"resources"`
PatchResources []string `yaml:"patch_resources"`
PatchEnvs []string `yaml:"patch_envs"`
}The module provides a generic Load[T]() function that loads and parses configuration files:
cfg := config.Load[AppConfig]()This function:
- Finds the configuration file in predefined locations
- Loads and parses the YAML content
- Processes environment variable substitutions using both
${ENV}and${env.ENV}syntax - Merges with additional configuration files if specified
- Returns a typed configuration structure
Environment variables can be used in configuration files with optional default values:
# Syntax: ${VAR_NAME:"default_value"}
setting1: ${SETTING_1:"default_value"}
setting2: ${REQUIRED_SETTING} # No default, will error if not setExpression syntax (GitHub Actions style):
# Syntax: ${env.VAR_NAME}
setting1: ${env.SETTING_1}
setting2: ${env.REQUIRED_SETTING}The module supports merging multiple configuration files:
# config.yaml
resources:
- configs/database.yaml
- configs/cache.yaml
patch_resources:
- configs/local-overrides.yamlAdvanced configuration values can be computed using expressions:
# config.yaml
app:
version: ${env.VERSION}
build_time: ${env.BUILD_TIME}
config_dir: ${config_dir()}
cert_data: ${embed("cert.pem")}// Set custom configuration path
config.SetConfigPath("/path/to/custom/config.yaml")
// Load configuration
cfg := config.Load[AppConfig]()cfg, err := config.LoadFromPath[AppConfig]("path/to/config.yaml")
if err != nil {
panic(err)
}
// typed config value
_ = cfg.T
// export fully merged YAML for inspection/debugging
merged, err := config.LoadMergedConfigData("path/to/config.yaml")
if err != nil {
panic(err)
}
fmt.Println(string(merged))type ValidatedConfig struct {
Port int `yaml:"port" validate:"min=1,max=65535"`
}
cfg := config.Load[ValidatedConfig]()
// Add custom validation logic here| Function | Description |
|---|---|
Load[T]() |
Load and parse configuration generically |
TryLoad[T]() |
Try load typed configuration (returns error) |
LoadFromPath[T](cfgPath string) |
Load typed configuration from specific path |
LoadMergedConfigData(cfgPath string) |
Load fully merged processed config content (YAML bytes) |
TryLoadMergedData() |
Try load merged processed config content via global path/discovery |
LoadMergedData() |
Load merged processed config content (panic on error) |
ValidateEnvReferences(cfgPath string) |
Manually validate env references against patch_envs |
SetConfigPath(path string) |
Set custom configuration file path |
GetConfigPath() |
Get current configuration file path |
| Structure | Description |
|---|---|
Cfg[T] |
Wrapper containing loaded configuration and metadata |
Resources |
Configuration for resource loading and merging |
Node |
YAML node wrapper for flexible access |
| Function | Description |
|---|---|
LoadEnvMap(cfgPath string) |
Load environment configuration map |
RegisterExpr(name string, expr any) |
Register custom expression functions |
- Use Struct Tags: Clearly define YAML mappings with struct tags
- Provide Defaults: Specify sensible default values for configuration options
- Validate Early: Implement configuration validation to catch errors early
- Environment Overrides: Use environment variables for deployment-specific settings
- Modular Configs: Split large configurations into logical modules
- Documentation: Document configuration options and their purposes
import (
"github.com/pubgo/funk/v2/config"
"github.com/pubgo/funk/v2/features"
)
type AppConfig struct {
Debug bool `yaml:"debug"`
}
cfg := config.Load[AppConfig]()
debugMode := features.Bool("debug", cfg.T.Debug, "Enable debug mode")import (
"github.com/pubgo/funk/v2/config"
"github.com/pubgo/funk/v2/log"
)
type LogConfig struct {
Level string `yaml:"level"`
}
cfg := config.Load[LogConfig]()
logger := log.GetLogger("app")
logger.Info().Str("config_level", cfg.T.Level).Msg("Configuration loaded")