preface

This is the second day of my participation in the challenge, hello everyone, I am the composer Of the sun in the last post, we learned the basic directory design and basic technology selection, and also showed you to do a Gin helloWorld program. This post will show you how to use Viper to process YAML configuration files and integrate them into the GIN framework

1. Introduction

Viper is a complete configuration solution for Go applications. It is designed to work within applications and can handle all types of configuration requirements and formats. It supports the following features:

  1. • Set default values
  2. • Read configuration information from configuration files in JSON, TOML, YAML, HCL, ENvFile, and Java Properties formats
  3. • Real-time monitoring and re-reading of configuration files (optional)
  4. • Read from environment variables
  5. • Read and monitor configuration changes from a remote configuration system (ETCD or Consul)
  6. • Read configuration from command line arguments
  7. • Read configuration from buffer
  8. • Explicitly configured values

Viper official address

2. Install

go get github.com/spf13/viper
Copy the code

2. Requirements analysis

Think about it. What configuration does a service need?

  1. Directory where logs are stored (logAddress)
  2. Service Name (Name)
  3. Service Port Number (Port)
  4. Mysql > host; mysql > host;

Ps: We write so much for the moment, and we will add the configuration later

3. Data flow diagram

Before writing the code, we need to understand the settings-dev.yaml to viper recognition, and then in the various files, how the process is a picture, you will understand

3. Write the Settings – dev. Yaml

# settings-dev.yaml
name: "go-gin"
port: 8022
logsAddress: "./logs/"

mysql:
 name: "root"
 host: "120.XX.XX.XX"
 port: 3306
 password: "XXXXXXXX"
 dbName: "test"
 
redis:
 host: "120.XX.XX.XX"
 port: 6379
Copy the code

4. Define the struct for the configuration

Write several constructs in config/config

Viper will send yamL data to the corresponding structure

package config

type ServerConfig struct {
   Name        string      `mapstructure:"name"`
   Port        int         `mapstructure:"port"`
   Mysqlinfo   MysqlConfig `mapstructure:"mysql"`
   RedisInfo   RedisConfig `mapstructure:"redis"`
   LogsAddress string      `mapstructure:"logsAddress"`
}

type MysqlConfig struct {
   Host string `mapstructure:"host"`
   Port int    `mapstructure:"port"`
   Name string    `mapstructure:"name"`
   Password string    `mapstructure:"password"`
   DBName string    `mapstructure:"dbName"`
}

type RedisConfig struct {
   Host string `mapstructure:"host"`
   Port int    `mapstructure:"port"`
}
Copy the code

Note that settings-dev.yaml each field name corresponds to the tag of the structure.

5. Write global data

The global data is mainly the parsed data store of Viper, so that each GO file already references the configuration data in GLBAL. Written in global/ globalvar.go

package global
import (
	"go.uber.org/zap"
	"go_gin/config"
)

var (
    Settings config.ServerConfig
)
Copy the code

6. Use Viper to configure YAML

In Initialize /config, write

package initialize

import (
	"github.com/fatih/color"
	"github.com/spf13/viper"
	"go_gin/config"
	"go_gin/global"
)

func InitConfig(a) {
	// instantiate viper
	v := viper.New()
	// How to set the file path
	v.SetConfigFile("./settings-dev.yaml")
	iferr := v.ReadInConfig(); err ! =nil {
		panic(err)
	}
	serverConfig := config.ServerConfig{}
	// Give the initial value to serverConfig
	iferr := v.Unmarshal(&serverConfig); err ! =nil {
		panic(err)
	}
	// pass to the global variable
	global.Settings = serverConfig
	color.Blue("11111111", global.Settings.LogsAddress)
}

Copy the code

7. Use configuration variables

In the main. Go

package main

import (
   "fmt"
   "github.com/fatih/color"
   "go.uber.org/zap"
   "go_gin/global"
   "go_gin/initialize"   
   "go_gin/utils"
)

func main(a) {
   //1. Initialize yamL configuration
      initialize.InitConfig()

      r := gin.Default()
      r.GET("/ping".func(c *gin.Context) {
   	c.JSON(200, gin.H{
   		"message": "pong",
   	})
   })
   r.Run(fmt.Sprintf(":%d", global.Settings.Port))
}
Copy the code

Finally – verification of results

Start main.go. When you find that you have configured the port number in settings-dev.yaml and printed it on the console, you are successful

thinking

How do you distinguish the configuration of the online environment from the development environment?