How to Use Viper for Configuration Management in Gorig
Gorig centralizes all configuration handling in the utils/cofigure package, a thin wrapper around Viper that automatically initializes environment-aware YAML loading and exposes type-safe getters like GetString() and GetBool().
Gorig leverages the popular Viper configuration library through a dedicated abstraction layer to simplify application settings management. According to the jom-io/gorig source code, the utils/cofigure package encapsulates Viper's complexity, providing a consistent API for reading YAML files and environment variables while supporting runtime mode detection.
Understanding the Viper Wrapper Architecture
The configuration system resides in utils/cofigure/cfg.go. This file contains both the initialization logic and the public getter API. The wrapper implements a lazy initialization pattern: Viper configuration is set up automatically when any getter function is invoked for the first time, ensuring the application code never needs to manually bootstrap the configuration engine.
Configuration Initialization Process
When the first configuration value is requested, the wrapper executes a seven-step initialization sequence defined in utils/cofigure/cfg.go:
- Environment Prefix Setup —
viper.SetEnvPrefix("gorig")at line 111 establishes that all environment variables must use theGORIG_prefix. - Automatic Environment Scanning —
viper.AutomaticEnv()at line 112 enables automatic lookup of matching environment variables without manual registration. - Key Normalization —
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))at line 113 converts dotted configuration keys (e.g.,sys.mode) to underscored environment names (SYS_MODE). - Config Path Registration — Lines 114-115 add
./_bin/and./as search paths usingviper.AddConfigPath(). - Runtime Mode Detection — Line 116 sets the config filename dynamically via
viper.SetConfigName(GetString("sys.mode", "local")), defaulting tolocal.yamlunless overridden. - Format Specification —
viper.SetConfigType("yaml")at line 117 forces YAML format for all configuration files. - File Loading —
viper.ReadInConfig()at line 118 loads the selected file and merges it with environment variables and defaults.
Accessing Configuration Values
After initialization, the codebase interacts with configuration through type-safe helper functions that delegate directly to Viper.
String Values with Fallbacks
The GetString(key, fallback) function at line 21 wraps viper.GetString(), returning the fallback value if the key is undefined:
import "github.com/jom-io/gorig/utils/cofigure"
func main() {
// Returns value of app.name or "gorig" if undefined
appName := cofigure.GetString("app.name", "gorig")
fmt.Println("Application:", appName)
}
Boolean and Numeric Types
For primitive types, the wrapper provides direct mappings:
GetBool(key)— Line 41 wrapsviper.GetBool()for boolean flags.GetInt(key)— Line 52 wrapsviper.GetInt()for signed integers.GetUint64(key)— Line 63 wrapsviper.GetUint64()for unsigned 64-bit values.GetDuration(key)— Line 74 wrapsviper.GetDuration()for time-based settings.
debug := cofigure.GetBool("log.debug")
if debug {
fmt.Println("Debug logging enabled")
}
timeout := cofigure.GetDuration("server.timeout")
Map Structures
For nested configuration blocks, GetStringMap(key) at line 15 returns a map of values:
dbConfig := cofigure.GetStringMap("database")
fmt.Printf("Host: %s\n", dbConfig["host"])
Environment Variable Integration
Gorig's Viper wrapper implements seamless environment variable override capabilities. The initialization establishes a GORIG_ prefix requirement and automatic key transformation.
To override a configuration value using environment variables:
export GORIG_SYS_MODE=production
export GORIG_LOG_DEBUG=true
go run ./cmd/server
The wrapper automatically maps GORIG_SYS_MODE to the sys.mode configuration key and GORIG_LOG_DEBUG to log.debug, overriding any YAML file values due to Viper's precedence rules.
Configuration File Structure
By default, Gorig expects configuration files named after the runtime mode:
local.yaml(default)production.yamldevelopment.yaml
Files are searched in ./_bin/ first, then the project root ./. The active mode is determined by the sys.mode key, which can be set via environment variable (GORIG_SYS_MODE) or command-line flag before initialization.
Summary
- Gorig encapsulates Viper in
utils/cofigure/cfg.go, providing a centralized configuration management system. - The wrapper initializes automatically on first use, configuring environment variable support with the
GORIG_prefix and YAML file loading. - Type-safe helpers (
GetString,GetBool,GetInt,GetUint64,GetDuration,GetStringMap) provide direct access to Viper functionality. - Environment variables automatically override YAML values using dot-to-underscore key mapping (e.g.,
database.hostbecomesGORIG_DATABASE_HOST). - Configuration filenames are determined by the
sys.modesetting, defaulting tolocal.yaml.
Frequently Asked Questions
How does Gorig determine which configuration file to load?
According to utils/cofigure/cfg.go line 116, Gorig calls viper.SetConfigName(GetString("sys.mode", "local")), which sets the filename based on the sys.mode configuration value. This defaults to local, causing the system to search for local.yaml. You can override this by setting the GORIG_SYS_MODE environment variable before startup.
Can I use JSON configuration files instead of YAML?
The current implementation in utils/cofigure/cfg.go line 117 explicitly calls viper.SetConfigType("yaml"), which forces YAML format for all configuration files. To use JSON, you would need to modify the wrapper source code to change the config type or extend the initialization logic to support multiple formats.
How do I access deeply nested configuration values?
Use the dot notation within the getter functions. For a structure like database.connections.primary.host, call cofigure.GetString("database.connections.primary.host", "localhost"). The wrapper passes these dotted keys directly to Viper's lookup mechanism, which traverses nested YAML maps automatically.
What happens if a configuration key is missing?
For GetString(), the second argument serves as a fallback default value. For other types like GetBool() or GetInt(), Viper returns the zero value for that type (false, 0, etc.) if the key is undefined. The wrapper does not panic on missing keys; it delegates Viper's default return behavior to the caller.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →