# Go 語言之 Viper 的使用 ## Viper 介紹 [Viper](https://github.com/spf13/viper): ### 安裝 ```bash go get github.com/spf13/viper ``` ### Viper 是什麼? Viper 是一個針對 Go ...
Go 語言之 Viper 的使用
Viper 介紹
Viper:https://github.com/spf13/viper
安裝
go get github.com/spf13/viper
Viper 是什麼?
Viper 是一個針對 Go 應用程式的完整配置解決方案,包括12-Factor 應用程式。它可以在應用程式中工作,並且可以處理所有類型的配置需求和格式。它支持:
Viper is a complete configuration solution for Go applications including 12-Factor apps. It is designed to work within an application, and can handle all types of configuration needs and formats. It supports:
- setting defaults
- reading from JSON, TOML, YAML, HCL, envfile and Java properties config files
- live watching and re-reading of config files (optional)
- reading from environment variables
- reading from remote config systems (etcd or Consul), and watching changes
- reading from command line flags
- reading from buffer
- setting explicit values
Viper can be thought of as a registry for all of your applications configuration needs.
Viper 可以被認為是滿足所有應用程式配置需求的註冊表。
為什麼使用 Viper?
在構建現代應用程式時,您不需要擔心配置文件格式; 您需要專註於構建令人滿意的軟體。Viper 就是為此而生的。
Viper 可以為你做以下事情:
- Find, load, and unmarshal a configuration file in JSON, TOML, YAML, HCL, INI, envfile or Java properties formats.
- Provide a mechanism to set default values for your different configuration options.
- Provide a mechanism to set override values for options specified through command line flags.
- Provide an alias system to easily rename parameters without breaking existing code.
- Make it easy to tell the difference between when a user has provided a command line or config file which is the same as the default.
Viper uses the following precedence order. Each item takes precedence over the item below it:
- explicit call to
Set
- flag
- env
- config
- key/value store
- default
Important: Viper configuration keys are case insensitive. There are ongoing discussions about making that optional.
重要提示: Viper 配置鍵是不區分大小寫的。目前正在討論是否將其設置為可選的。
Viper 實操 Putting Values into Viper
建立預設值
一個好的配置系統將支持預設值。密鑰不需要預設值,但如果沒有通過配置文件、環境變數、遠程配置或標誌設置密鑰,則預設值非常有用。
Examples:
viper.SetDefault("ContentDir", "content")
viper.SetDefault("LayoutDir", "layouts")
viper.SetDefault("Taxonomies", map[string]string{"tag": "tags", "category": "categories"})
讀取配置文件
Viper 需要最小的配置,這樣它就知道在哪裡查找配置文件。Viper 支持 JSON、 TOML、 YAML、 HCL、 INI、 envfile 和 JavaProperties 文件。Viper 可以搜索多個路徑,但目前單個 Viper 實例只支持單個配置文件。Viper 不預設任何配置搜索路徑,將預設決策留給應用程式。
下麵是如何使用 Viper 搜索和讀取配置文件的示例。不需要任何特定的路徑,但至少應該在需要配置文件的地方提供一個路徑。
viper.SetConfigName("config") // name of config file (without extension)
viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name
viper.AddConfigPath("/etc/appname/") // path to look for the config file in
viper.AddConfigPath("$HOME/.appname") // call multiple times to add many search paths
viper.AddConfigPath(".") // optionally look for config in the working directory
err := viper.ReadInConfig() // Find and read the config file
if err != nil { // Handle errors reading the config file
panic(fmt.Errorf("fatal error config file: %w", err))
}
您可以處理沒有如下配置文件的特定情況:
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// Config file not found; ignore error if desired
} else {
// Config file was found but another error was produced
}
}
// Config file found and successfully parsed
寫入配置文件
從配置文件中讀取是有用的,但有時您希望存儲在運行時所做的所有修改。為此,提供了一系列命令,每個命令都有自己的用途:
- WriteConfig-將當前 viper 配置寫入預定義的路徑(如果存在)。如果沒有預定義的路徑就會出錯。將覆蓋當前配置文件(如果存在)。
- SafeWriteConfig-將當前 viper 配置寫入預定義的路徑。如果沒有預定義的路徑就會出錯。不會覆蓋當前配置文件(如果存在)。
- WriteConfigAs-將當前 viper 配置寫入給定的文件路徑。將覆蓋給定的文件(如果存在)。
- SafeWriteConfigAs-將當前 viper 配置寫入給定的文件路徑。不會覆蓋給定的文件(如果存在)。
As a rule of the thumb, everything marked with safe won't overwrite any file, but just create if not existent, whilst the default behavior is to create or truncate.
根據經驗,所有標記為 safe 的文件都不會覆蓋任何文件,只是創建(如果不存在的話) ,而預設行為是創建或截斷。
A small examples section:
viper.WriteConfig() // writes current config to predefined path set by 'viper.AddConfigPath()' and 'viper.SetConfigName'
viper.SafeWriteConfig()
viper.WriteConfigAs("/path/to/my/.config")
viper.SafeWriteConfigAs("/path/to/my/.config") // will error since it has already been written
viper.SafeWriteConfigAs("/path/to/my/.other_config")
監視和重新讀取配置文件
Viper 支持讓應用程式在運行時實時讀取配置文件的能力。
需要重新啟動伺服器才能使配置生效的日子已經一去不復返了,使用 viper 的應用程式可以在運行時讀取配置文件的更新,而且不會錯過任何一次更新。
只需告訴 viper 實例監視 Config。您還可以為 Viper 提供一個函數,以便在每次發生更改時運行該函數。
確保在調用 WatchConfig ()之前添加了所有的 configPath
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("Config file changed:", e.Name)
})
viper.WatchConfig()
配置文件實時載入實操
package main
import (
"fmt"
"net/http"
"github.com/fsnotify/fsnotify"
"github.com/gin-gonic/gin"
"github.com/spf13/viper"
)
func main() {
// 設置預設值
viper.SetDefault("fileDir", "./")
// 讀取配置文件
viper.SetConfigFile("./config.yaml") // 指定配置文件路徑
viper.SetConfigName("config") // 配置文件名稱(無擴展名)
viper.SetConfigType("yaml") // 如果配置文件的名稱中沒有擴展名,則需要配置此項
viper.AddConfigPath("/etc/appname/") // 查找配置文件所在的路徑
viper.AddConfigPath("$HOME/.appname") // 多次調用以添加多個搜索路徑
viper.AddConfigPath(".") // 還可以在工作目錄中查找配置
err := viper.ReadInConfig() // 查找並讀取配置文件
if err != nil { // 處理讀取配置文件的錯誤
panic(fmt.Errorf("Fatal error config file: %s \n", err))
}
// 實時監控配置文件的變化 WatchConfig 開始監視配置文件的更改。
viper.WatchConfig()
// OnConfigChange設置配置文件更改時調用的事件處理程式。
// 當配置文件變化之後調用的一個回調函數
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("Config file changed:", e.Name)
})
r := gin.Default()
r.GET("/version", func(c *gin.Context) {
// GetString以字元串的形式返回與鍵相關的值。
c.String(http.StatusOK, viper.GetString("version"))
})
r.Run()
}
運行並訪問:http://127.0.0.1:8080/version
Code/go/viper_demo via