Introduction

When building applications in Go, managing configuration can become cumbersome without the right tools. The viper library is a powerful solution for handling configuration files efficiently. It supports multiple formats, remote key:value stores, and is fully customizable.

Installation

To use viper in your Go application, you need to first install it:

go get github.com/spf13/viper

Basic Usage

To get started with viper, you can follow these steps to read from a configuration file:


package main

import (
    "fmt"
    "github.com/spf13/viper"
)

func main() {
    viper.SetConfigName("config") // name of config file (without extension)
    viper.SetConfigType("json")   // REQUIRED if the config file does not have the extension in the name
    viper.AddConfigPath(".")       // optionally look for config in the working directory

    if err := viper.ReadInConfig(); err != nil { // Find and read the config file
        panic(fmt.Errorf("Fatal error config file: %w \n", err))
    }

    // Read values from the config file
    fmt.Println("App Name:", viper.GetString("app_name"))
}

This will read a config.json file located in the root directory. You can use formats such as JSON, YAML, TOML, or INI. Below is an example of how config.json might look:


{
    "app_name": "MyApp",
    "port": 8080
}

Setting Default Values

Viper allows you to set default values for configuration options. This can be particularly useful to make your application more robust:


viper.SetDefault("app_name", "DefaultApp")
viper.SetDefault("port", 3000)

Changing Configuration Sources

Viper makes it easy to switch between different configuration sources. For instance, you might start with file-based configuration but later decide to move to a remote key:value store. Here’s how you can easily transition:


viper.SetConfigType("yaml")
viper.ReadConfig(strings.NewReader(`
app_name: MyYAMLApp
port: 9090
`))

fmt.Println("App Name from YAML:", viper.GetString("app_name"))

Environment Variables

You can also configure environment variable overrides with viper. This is useful in production, allowing you to integrate environment-specific settings:


viper.AutomaticEnv() // automatically override keys from environment variables

If you prefix your configuration keys with a specific sequence, you can make use of that to structure variables across different environments:


viper.SetEnvPrefix("myapp")
// Assuming env variable is: MYAPP_PORT=5000
port := viper.GetInt("port") // Will retrieve 5000 if the environment variable is set.

Conclusion

The viper library provides robust solutions for managing configurations in your Go applications. It supports various configuration file formats, environment variables, and even remote configuration systems, making it a compelling choice for flexible configuration management.