Documentation
¶
Overview ¶
Package config provides environment-based configuration management with validation.
The package offers a type-safe way to parse configuration from environment variables using the Validator interface. It includes a ServerConfig implementation for common HTTP server settings (port, timeouts, environment) with built-in validation.
Example usage:
cfg := config.ParseConfig[config.ServerConfig]()
fmt.Printf("Server running on port %d in %s environment\n", cfg.Port, cfg.Environment)
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ParseConfig ¶
ParseConfig parses environment variables into a configuration struct of type C and validates the result. The type parameter C must implement the Validator interface. Returns an error if parsing or validation fails, allowing the caller to decide how to handle it.
Example:
cfg, err := ParseConfig[ServerConfig]()
if err != nil {
log.Fatal(err)
}
Example ¶
ExampleParseConfig demonstrates parsing configuration from environment variables with the generic ParseConfig function.
package main
import (
"fmt"
"log"
"os"
"github.com/harrydayexe/GoWebUtilities/config"
)
func main() {
// Set environment variables for the example
os.Setenv("ENVIRONMENT", "production")
os.Setenv("PORT", "3000")
os.Setenv("VERBOSE", "true")
cfg, err := config.ParseConfig[config.ServerConfig]()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Environment: %s\n", cfg.Environment)
fmt.Printf("Port: %d\n", cfg.Port)
fmt.Printf("Verbose: %t\n", cfg.VerboseMode)
}
Output: Environment: production Port: 3000 Verbose: true
Example (CustomConfig) ¶
ExampleParseConfig_customConfig demonstrates using ParseConfig with a custom configuration type that implements Validator.
package main
import (
"fmt"
"log"
)
// CustomConfig demonstrates implementing a custom configuration type
// with the Validator interface.
type CustomConfig struct {
APIKey string `env:"API_KEY"`
MaxRequests int `env:"MAX_REQUESTS" envDefault:"100"`
}
// Validate implements the config.Validator interface.
func (c CustomConfig) Validate() error {
if c.APIKey == "" {
return fmt.Errorf("API_KEY is required")
}
if c.MaxRequests < 1 {
return fmt.Errorf("MAX_REQUESTS must be positive")
}
return nil
}
func main() {
// Example of a custom config type
customCfg := CustomConfig{
APIKey: "secret-key-123",
MaxRequests: 100,
}
if err := customCfg.Validate(); err != nil {
log.Fatal(err)
}
fmt.Printf("API Key set: %t\n", customCfg.APIKey != "")
fmt.Printf("Max Requests: %d\n", customCfg.MaxRequests)
}
Output: API Key set: true Max Requests: 100
Example (ErrorHandling) ¶
ExampleParseConfig_errorHandling demonstrates custom error handling instead of using log.Fatal.
package main
import (
"fmt"
"os"
"github.com/harrydayexe/GoWebUtilities/config"
)
func main() {
// Set an invalid environment value
os.Setenv("ENVIRONMENT", "staging")
cfg, err := config.ParseConfig[config.ServerConfig]()
if err != nil {
// Custom error handling - you decide what to do
fmt.Printf("Configuration error: %v\n", err)
fmt.Println("Using fallback configuration")
// Could use default config, retry, etc.
return
}
// This won't be reached in this example
fmt.Printf("Loaded config: %v\n", cfg.Environment)
}
Output: Configuration error: config validation failed: invalid environment: staging (must be local, test or production) Using fallback configuration
Types ¶
type Environment ¶
type Environment string
Environment defines which environment the application is running in. Valid values are Local, Test, and Production.
Example ¶
ExampleEnvironment demonstrates the Environment type and its constants.
package main
import (
"fmt"
"github.com/harrydayexe/GoWebUtilities/config"
)
func main() {
environments := []config.Environment{
config.Local,
config.Test,
config.Production,
}
for _, env := range environments {
fmt.Printf("Environment: %s\n", env.String())
}
}
Output: Environment: local Environment: test Environment: production
const ( // Local represents a local development environment. Local Environment = "local" // Test represents a testing environment. Test Environment = "test" // Production represents a production environment. Production Environment = "production" )
func (Environment) String ¶
func (e Environment) String() string
String returns the string representation of the Environment.
type ServerConfig ¶
type ServerConfig struct {
// Environment specifies the runtime environment (local, test, or production).
// Defaults to "local" if ENVIRONMENT is not set.
Environment Environment `env:"ENVIRONMENT" envDefault:"local"`
// VerboseMode enables verbose logging when true.
// Defaults to false if VERBOSE is not set.
VerboseMode bool `env:"VERBOSE" envDefault:"false"`
// Port is the HTTP server port number.
// Defaults to 8080 if PORT is not set.
Port int `env:"PORT" envDefault:"8080"`
// ReadTimeout is the maximum duration in seconds for reading the entire request.
// Defaults to 15 seconds if READ_TIMEOUT is not set.
ReadTimeout int `env:"READ_TIMEOUT" envDefault:"15"`
// WriteTimeout is the maximum duration in seconds for writing the response.
// Defaults to 15 seconds if WRITE_TIMEOUT is not set.
WriteTimeout int `env:"WRITE_TIMEOUT" envDefault:"15"`
// IdleTimeout is the maximum duration in seconds to wait for the next request
// when keep-alives are enabled. Defaults to 60 seconds if IDLE_TIMEOUT is not set.
IdleTimeout int `env:"IDLE_TIMEOUT" envDefault:"60"`
}
ServerConfig holds the configuration for an HTTP server. All fields are populated from environment variables with sensible defaults.
Example ¶
ExampleServerConfig demonstrates creating and validating a ServerConfig with default values.
package main
import (
"fmt"
"log"
"github.com/harrydayexe/GoWebUtilities/config"
)
func main() {
cfg := config.ServerConfig{
Environment: config.Local,
VerboseMode: false,
Port: 8080,
ReadTimeout: 15,
WriteTimeout: 15,
IdleTimeout: 60,
}
if err := cfg.Validate(); err != nil {
log.Fatal(err)
}
fmt.Printf("Environment: %s\n", cfg.Environment)
fmt.Printf("Port: %d\n", cfg.Port)
fmt.Printf("Verbose: %t\n", cfg.VerboseMode)
}
Output: Environment: local Port: 8080 Verbose: false
func (ServerConfig) Validate ¶
func (c ServerConfig) Validate() error
Validate checks that the ServerConfig has valid values. Currently validates that Environment is one of Local, Test, or Production. Returns an error if validation fails, nil otherwise.
Example ¶
ExampleServerConfig_Validate demonstrates validation of different environment values.
package main
import (
"fmt"
"github.com/harrydayexe/GoWebUtilities/config"
)
func main() {
validConfig := config.ServerConfig{
Environment: config.Production,
}
invalidConfig := config.ServerConfig{
Environment: config.Environment("staging"),
}
// Valid configuration
if err := validConfig.Validate(); err != nil {
fmt.Printf("Valid config error: %v\n", err)
} else {
fmt.Println("Production config is valid")
}
// Invalid configuration
if err := invalidConfig.Validate(); err != nil {
fmt.Printf("Invalid config error: %v\n", err)
}
}
Output: Production config is valid Invalid config error: invalid environment: staging (must be local, test or production)
type Validator ¶
type Validator interface {
// Validate checks the configuration for invalid values or inconsistencies.
// It returns an error describing what is invalid, or nil if the configuration is valid.
Validate() error
}
Validator is an interface for configuration types that support validation. Configuration structs should implement this interface to enable validation of their fields after parsing from environment variables.
Example ¶
ExampleValidator demonstrates the Validator interface usage.
package main
import (
"fmt"
"github.com/harrydayexe/GoWebUtilities/config"
)
// CustomConfig demonstrates implementing a custom configuration type
// with the Validator interface.
type CustomConfig struct {
APIKey string `env:"API_KEY"`
MaxRequests int `env:"MAX_REQUESTS" envDefault:"100"`
}
// Validate implements the config.Validator interface.
func (c CustomConfig) Validate() error {
if c.APIKey == "" {
return fmt.Errorf("API_KEY is required")
}
if c.MaxRequests < 1 {
return fmt.Errorf("MAX_REQUESTS must be positive")
}
return nil
}
func main() {
// Any type implementing Validator can be used with ParseConfig
var _ config.Validator = config.ServerConfig{}
var _ config.Validator = CustomConfig{}
fmt.Println("Both ServerConfig and CustomConfig implement Validator")
}
Output: Both ServerConfig and CustomConfig implement Validator