SoFunction
Updated on 2025-03-05

How to read configuration files in Go projects

Go provides a very simple API for reading json and yaml files. We can easily convert a json or yaml file into a Go structure, but if you read the configuration file directly in the project, this method is not good enough. The disadvantages are as follows:

In actual development, the configuration values ​​of configuration items are different in different environments.

The above problem can be determined by different configuration files to read which configuration file in which environment, but there is another problem that in actual development, some configuration items are the same, and some are different. If the configuration file has a main configuration file, which stores the same configuration items for different environments, and there is also a configuration file that follows the environment, which stores the configuration items for different environments. Then, after reading the two configuration files, make a merge, and the result is the total configuration item information.

Some configuration items are required, and some configuration items have special values, such as email, mobile phone number, IP information, etc.

Let's see how gonfig solves this problem

  • Install gonfig
go get /xiao-ren-wu/gonfig
  • Create a new configuration directory in the project, write the corresponding configuration file, and add a go file to read the configuration file in the directory of the same level as the configuration directory

The file contains a common configuration.conf-{{active}}.yamlStores different configuration information for different environments.

conf
   |-
   |-
   |-
   |
  • usego:embedLoad the configuration file into memory and callRead configuration files
package config

import (
   "model"
   "/xiao-ren-wu/gonfig"
   "embed"
)

//go:embed *.yaml
var confDir 

// Configuration struct of our configuration filetype AppConf struct {
	AppName string `yaml:"app-name" json:"app-name"`
	DB      DBConf `yaml:"db" json:"db"`
}

type DBConf struct {
	Username string `yaml:"username" json:"username"`
	Password string `yaml:"password" json:"password"`
}

var conf Conf

func Init() {
   if err := (confDir, &conf); err != nil {
      panic(err)
   }
}

func GetConf() *Conf {
   return &conf
}

This completes the reading of configuration files in the project. Isn’t it very simple? The configuration format read at this time isconf-{{profile}}.yamlandThe sum ofconf-{{profile}}.yamlThe properties defined inThe same, thenconf-{{profile}}.yamlWhichever

Agree

gonfigThe reason for the simplicity of the API is that there are many constraints behind it. Only configurations that meet the constraints can be successfully read. The specific constraints are as follows:

  • The file name will be read by default with a prefixconfFiles

  • Through environment variablesprofileAs the environment name, if not configured, the default dev.

  • The program will look forAs the main configuration file,conf-{{profile}}.yamlAs an environment-specific configuration file, then merge the file contents

  • ifconf-{{profile}}.yamlProperties andThe properties in theconf-{{profile}}.yamlWhichever is.

Customize configuration files according to the project

Function signaturefunc Unmarshal(confDir ReadFileDir, v interface{}, ops ...Option) error Provide a lot of configuration items for users to customize their needs. The specific configuration information is as follows:

  • Change the configuration file name prefixFilePrefix(prefix string)

  • Change the read configuration file typeUnmarshalWith(uType UnmarshalType)

  • Change the read environment variable nameProfileUseEnv(envName, defaultProfile string)

  • Customize the profileProfileFunc(f func() string)

Principles

gonfigThe implementation is also very simple, the core source code is as follows:

func Unmarshal(confDir ReadFileDir, v interface{}, ops ...Option) error {
	if v != nil && (v).Kind() !=  {
		return gonfig_error.ErrNonPointerArgument
	}

	var cs = &confStruct{
		confPrefix:      "conf",
		envName:         "profile",
		defaultEnvValue: "dev",
		unmarshalType:   Yaml,
	}
	 = func() string {
		return getActiveProfile(, )
	}

	for _, op := range ops {
		op(cs)
	}

	 = ()

	if err := loadConf(confDir, cs); err != nil {
		return err
	}

	// copy val
	v1 := ((v).Elem()).Interface()

	if err := fileUnmarshal(, v1, ); err != nil {
		return err
	}

	if len() == 0 {
		return gonfig_error.MasterProfileConfNotSetError
	}

	if err := fileUnmarshal(, v, ); err != nil {
		return err
	}

	return (v, v1, )
}

The general principle is to copy a structure v1 sent to the function by the user, and structure v1 and v are used to receive it respectively.conf-{{profile}}.yamlProperties andconfiguration information, and then call the three-party open source librarymergoMake a merge for the properties of two structures.

This is aboutgonfigAll contents~~~

Github address is:/xiao-ren-wu/gonfig

This is the end of this article about how to read configuration files in Go projects. For more relevant contents of Go reading configuration files, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!