config

package
v0.21.0 Latest Latest
Warning

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

Go to latest
Published: Jan 14, 2026 License: MIT Imports: 7 Imported by: 0

README

Contributions Welcome Release

Config Package

The config package provides a reusable and extensible configuration loader built on top of Viper. It is designed to simplify configuration management in Go applications by supporting multiple config sources, context propagation, and functional loading options.

Features

  • Environment-First Configuration: Automatically reads from environment variables.
  • YAML File Support: Load config from .yaml files (required or optional).
  • Injectable Defaults: Provide fallback values when env or file values are not present.
  • Context Integration: Easily inject and retrieve config via context.Context or *http.Request.

Installation

go get github.com/kittipat1413/go-common/framework/config

Documentation

Go Reference

For detailed API documentation, examples, and usage patterns, visit the Go Package Documentation.

Usage

This is the simplest way to get started using MustConfig with some defaults:

package main

import (
	"fmt"

	"github.com/kittipat1413/go-common/framework/config"
)

func main() {
	cfg := config.MustConfig(
        config.WithRequiredConfigPath("env.yaml"),
		config.WithDefaults(map[string]any{
			"SERVICE_NAME": "my-service",
			"SERVICE_PORT": ":8080",
			"ENV":          "development",
		}),
	)

	// Read config values
	serviceName := cfg.GetString("SERVICE_NAME")
	port := cfg.GetString("SERVICE_PORT")
	env := cfg.GetString("ENV")

	fmt.Println("=== Service Config ===")
	fmt.Printf("Service Name: %s\n", serviceName)
	fmt.Printf("Port:         %s\n", port)
	fmt.Printf("Environment:  %s\n", env)
}

With an optional env.yaml override:

SERVICE_NAME: "user-api"
SERVICE_PORT: ":9090"
ENV: "staging"
Examples

Functional Options

WithRequiredConfigPath(path string): Fails if the file does not exist or is unreadable.

config.WithRequiredConfigPath("env.yaml")

WithOptionalConfigPaths(path string): Tries each path in order and uses the first found file. Skips missing files.

config.WithOptionalConfigPaths("env.yaml")

WithDefaults(defaults map[string]any): Injects fallback values if the config key is not set in env or file.

config.WithDefaults(map[string]any{
    "SERVICE_NAME": "my-service",
    "SERVICE_PORT": ":8080",
    "ENV":          "development",
})

Accessing Values

cfg.Get("SERVICE_NAME")           // any type
cfg.GetString("SERVICE_NAME")     // string
cfg.GetInt("MAX_WORKERS")         // int
cfg.GetDuration("TIMEOUT")        // string, use time.ParseDuration
cfg.All()                         // map[string]interface{}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewContext

func NewContext(ctx context.Context, cfg *Config) context.Context

NewContext creates a new context.Context with the provided Config instance attached.

Example:

// Inject into root context
ctx := config.NewContext(context.Background(), appConfig)
// Use ctx in your application ...

func NewRequest

func NewRequest(r *http.Request, cfg *Config) *http.Request

NewRequest creates a new http.Request with the Config instance stored in its context.

Example:

// Inject config into request
r = config.NewRequest(r, cfg)
// Continue with enhanced request ...

Types

type Config

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

Config wraps a Viper instance to provide a simplified interface for configuration management. It offers type-safe methods for retrieving configuration values and handles the underlying Viper complexity.

func FromContext

func FromContext(ctx context.Context) *Config

FromContext retrieves a Config instance from the provided context.Context.

Example:

cfg := config.FromContext(ctx)

func FromRequest

func FromRequest(r *http.Request) *Config

FromRequest retrieves a Config instance from an http.Request's context.

Example:

cfg := config.FromRequest(r)

func MustConfig

func MustConfig(opts ...Option) *Config

MustConfig creates and returns a new Config instance using the provided options. It behaves like NewConfig but will terminate the program with log.Fatalln if any error occurs.

This function is typically used at application startup when configuration loading is critical and the application cannot continue without proper configuration.

Warning: This function calls log.Fatalln on error, which will terminate the program. Use NewConfig if you need error handling instead of program termination.

Example:

// Global config that must load or app fails to start
var AppConfig = config.MustConfig(
	config.WithRequiredConfigPath("env.yaml"),
	config.WithDefaults(map[string]any{
		"SERVICE_PORT": ":8080",
		"DEBUG_MODE":   false,
	}),
)

func main() {
	port := AppConfig.GetString("SERVICE_PORT")
	// ... rest of application
}

func NewConfig

func NewConfig(opts ...Option) (*Config, error)

NewConfig creates and returns a new Config instance using the provided options. It initializes Viper with automatic environment variable reading and applies all options in order.

Environment variable reading is automatically enabled, meaning any environment variable can be accessed using its name as a key.

Example:

config, err := NewConfig(
	WithOptionalConfigPaths("config.yaml"),
	WithDefaults(map[string]any{
		"SERVICE_PORT": ":8080",
	}),
)
if err != nil {
	log.Fatalf("Failed to load config: %v", err)
}

func (*Config) All

func (c *Config) All() map[string]interface{}

All returns a map containing all configuration key-value pairs. This includes values from all sources (defaults, config files, environment variables).

Keys are normalized to lowercase. This is useful for debugging configuration or when you need to iterate over all available configuration values.

func (*Config) Get

func (c *Config) Get(key string) any

Get retrieves the value associated with the key as an interface{}.

func (*Config) GetBool

func (c *Config) GetBool(key string) bool

GetBool retrieves the value associated with the key as a boolean.

func (*Config) GetDuration

func (c *Config) GetDuration(key string) time.Duration

GetDuration retrieves the value associated with the key as a time.Duration.

func (*Config) GetFloat64

func (c *Config) GetFloat64(key string) float64

GetFloat64 retrieves the value associated with the key as a float64.

func (*Config) GetInt

func (c *Config) GetInt(key string) int

GetInt retrieves the value associated with the key as an integer.

func (*Config) GetIntSlice

func (c *Config) GetIntSlice(key string) []int

GetIntSlice retrieves the value associated with the key as a slice of integers.

func (*Config) GetString

func (c *Config) GetString(key string) string

GetString retrieves the value associated with the key as a string.

func (*Config) GetStringMap

func (c *Config) GetStringMap(key string) map[string]any

GetStringMap retrieves the value associated with the key as a map[string]any.

func (*Config) GetStringMapString

func (c *Config) GetStringMapString(key string) map[string]string

GetStringMapString retrieves the value associated with the key as a map[string]string.

func (*Config) GetStringMapStringSlice

func (c *Config) GetStringMapStringSlice(key string) map[string][]string

GetStringMapStringSlice retrieves the value associated with the key as a map[string][]string.

func (*Config) GetStringSlice

func (c *Config) GetStringSlice(key string) []string

GetStringSlice retrieves the value associated with the key as a slice of strings.

func (*Config) GetTime

func (c *Config) GetTime(key string) time.Time

GetTime retrieves the value associated with the key as a time.Time.

type Option

type Option func(v *viper.Viper) error

Option is a function that configures the Viper instance during initialization. Options are applied in the order they are provided to NewConfig or MustConfig.

func WithDefaults

func WithDefaults(defaults map[string]any) Option

WithDefaults injects fallback configuration values into the Viper instance. These values are used when no value is found in config files or environment variables.

Default values should use the same key names as expected in config files and environment variables.

Example:

config := MustConfig(
	WithDefaults(map[string]any{
		"SERVICE_PORT": ":8080",
		"DEBUG_MODE":   false,
		"DATABASE.TIMEOUT": "30s",
		"REDIS.POOL_SIZE": 10,
	}),
)

func WithOptionalConfigPaths

func WithOptionalConfigPaths(paths ...string) Option

WithOptionalConfigPaths attempts to load the first configuration file found from the given list of paths. It will silently skip missing files but return an error if a file exists but cannot be read or parsed.

Example:

// Try local config first, then fallback to default location
config := MustConfig(
	WithOptionalConfigPaths(
		"./local.env.yaml",
		"./config/env.yaml",
		"/etc/myapp/config.yaml",
	),
)

func WithRequiredConfigPath

func WithRequiredConfigPath(path string) Option

WithRequiredConfigPath forces the specified configuration file to exist and be readable. If the file doesn't exist or cannot be read, an error is returned.

Example:

config := MustConfig(
	WithRequiredConfigPath("./config/production.yaml"),
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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