» Go: Build a REST API with Gin » 2. Development » 2.7 Config File

Config File

func main() {
	c := &config.Config{
		App: config.ApplicationConfig{
			Port: 8080,
		},
		DB: config.DBConfig{
			FileName: "test.db",
			DSN:      "test_user:test_pass@tcp(127.0.0.1:3306)/lr_book?charset=utf8mb4&parseTime=True&loc=Local",
		},
	}
	...
}

As you may have noticed, hard-coded config items are potential security breaches. And they're hard to change and control after being built and deployed.

That's why you need a separate config file.

Add config.yml:

app:
  port: 8080
db:
  file_name: "test.db"
  dsn: "test_user:test_pass@tcp(127.0.0.1:3306)/lr_book?charset=utf8mb4&parseTime=True&loc=Local"

Add yaml dependency:

go get -u gopkg.in/yaml.v3

Add Parse func in infrastructure/config/config.go:

 package config
 
+import (
+       "fmt"
+       "os"
+
+       "gopkg.in/yaml.v3"
+)
+
 type Config struct {
        App ApplicationConfig `json:"app" yaml:"app"`
        DB  DBConfig          `json:"db" yaml:"db"`
@@ -13,3 +20,17 @@ type DBConfig struct {
 type ApplicationConfig struct {
        Port int `json:"port" yaml:"port"`
 }
+
+// Parse parses config file and returns a Config.
+func Parse(filename string) (*Config, error) {
+       buf, err := os.ReadFile(filename)
+       if err != nil {
+               return nil, err
+       }
+       c := &Config{}
+       err = yaml.Unmarshal(buf, c)
+       if err != nil {
+               return nil, fmt.Errorf("failed to parse file %s: %v", filename, err)
+       }
+       return c, nil
+}

Use config.Parse in main.go:

@@ -8,16 +8,15 @@ import (
        "literank.com/rest-books/infrastructure/config"
 )
 
+const configFileName = "config.yml"
+
 func main() {
-       c := &config.Config{
-               App: config.ApplicationConfig{
-                       Port: 8080,
-               },
-               DB: config.DBConfig{
-                       FileName: "test.db",
-                       DSN:      "test_user:test_pass@tcp(127.0.0.1:3306)/lr_book?charset=utf8mb4&parseTime=True&loc=Local",
-               },
+       // Read the config
+       c, err := config.Parse(configFileName)
+       if err != nil {
+               panic(err)
        }
+
        // Prepare dependencies
        wireHelper, err := application.NewWireHelper(c)
        if err != nil {

Hard-coded config items are moved into config.yml. Nice!

Caution: Do not directly track your config.yaml file with Git, as this could potentially leak sensitive data. If necessary, only track the template of the configuration file.
e.g.

app:
  port: 8080
db:
  file_name: ""
  dsn: ""
PrevNext