preface
The configuration file is an essential part of every project. It is used to save basic application data and database configuration information to avoid the embarrassment of searching for a configuration item to modify. Here I use Viper as a configuration management solution, it supports JSON, TOML, YAML, HCL, ENvFile, Java Properties and other formats of configuration files, and can monitor the modification of configuration files, hot overload, detailed introduction you can go to the official document to view
The installation
go get -u github.com/spf13/viper
Copy the code
Writing configuration files
Create a new file in the project root directory, config.yaml, and put the basic configuration of the project first, we will add more configuration information later
app: Apply the basic configuration
env: local # environment name
port: 8888 Service monitor port number
app_name: gin-app # app name
app_url: http://localhost # Application domain name
Copy the code
Write configuration constructs
Create a folder config under the project root directory to store all configuration structures
Create the config.go file and define the Configuration structure, whose App property corresponds to App in config.yaml
package config
type Configuration struct {
App App `mapstructure:"app" json:"app" yaml:"app"`
}
Copy the code
Create the app.go file and define the app structure, and all its attributes correspond to all configurations of app in config.yaml
package config
type App struct {
Env string `mapstructure:"env" json:"env" yaml:"env"`
Port string `mapstructure:"port" json:"port" yaml:"port"`
AppName string `mapstructure:"app_name" json:"app_name" yaml:"app_name"`
AppUrl string `mapstructure:"app_url" json:"app_url" yaml:"app_url"`
}
Copy the code
Note: The mapStructure tag in the configuration structure should correspond to the configuration name in config.ymal. Viper will assign config.yaml data to the structure based on the tag value
The global variable
Create a new global/app.go file and define the Application structure, which is used to store some variables at the start of the project, so that it is easy to call. At present, the Viper structure and the Configuration structure are put in first, and other member attributes will be added later
package global
import (
"github.com/spf13/viper"
"jassue-gin/config"
)
type Application struct {
ConfigViper *viper.Viper
Config config.Configuration
}
var App = new(Application)
Copy the code
Load the configuration using Viper
Create the bootstrap/config.go file and write the code:
package bootstrap
import (
"fmt"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
"jassue-gin/global"
"os"
)
func InitializeConfig(a) *viper.Viper {
// Set the configuration file path
config := "config.yaml"
// The production environment can change the configuration file path by setting environment variables
if configEnv := os.Getenv("VIPER_CONFIG"); configEnv ! ="" {
config = configEnv
}
// Initialize viper
v := viper.New()
v.SetConfigFile(config)
v.SetConfigType("yaml")
iferr := v.ReadInConfig(); err ! =nil {
panic(fmt.Errorf("read config failed: %s \n", err))
}
// Listen for configuration files
v.WatchConfig()
v.OnConfigChange(func(in fsnotify.Event) {
fmt.Println("config file changed:", in.Name)
// Overload configuration
iferr := v.Unmarshal(&global.App.Config); err ! =nil {
fmt.Println(err)
}
})
// Assign the configuration to the global variable
iferr := v.Unmarshal(&global.App.Config); err ! =nil {
fmt.Println(err)
}
return v
}
Copy the code
Initial Configuration
Modify the main.go file
package main
import (
"github.com/gin-gonic/gin"
"jassue-gin/bootstrap"
"jassue-gin/global"
"net/http"
)
func main(a) {
// Initialize the configuration
bootstrap.InitializeConfig()
r := gin.Default()
// Test the route
r.GET("/ping".func(c *gin.Context) {
c.String(http.StatusOK, "pong")})// Start the server
r.Run(":" + global.App.Config.App.Port)
}
Copy the code
Run the go run main.go command to start the application. The port number that the server listens to is already specified in the configuration file