Viper
Alamat Repositori: spf13/viper: Go configuration with fangs (github.com)
Alamat Dokumentasi: spf13/viper: Go configuration with fangs (github.com)
TIP
Saat ini sedang dalam diskusi transisi ke Viper2 yang tertarik dapat mengetahui: Viper2
Instalasi
go get github.com/spf13/viperPengenalan
Viper adalah solusi file konfigurasi lengkap untuk aplikasi go dapat menangani hampir semua jenis kebutuhan dan format konfigurasi memudahkan pengelolaan file konfigurasi proyek dan memiliki fitur berikut:
- Pengaturan nilai default
- Mendukung format JSON TOML YAML HCL envfile Java properties
- Mendukung pemantauan dan reload ulang file konfigurasi secara real-time
- Mendukung pembacaan dari variabel lingkungan
- Mendukung pembacaan dari sistem konfigurasi remote dan pemantauan perubahan
- Mendukung pembacaan flag command line
- Mendukung pembacaan buffer
- Mendukung pengaturan nilai eksplisit
Resmi menyatakan Viper dapat memenuhi semua kebutuhan konfigurasi aplikasi developer hanya perlu fokus pada pembangunan aplikasi biarkan Viper yang menangani manajemen konfigurasi banyak proyek terkenal menggunakan Viper
DANGER
Viper tidak bertanggung jawab untuk enkripsi dan dekripsi file konfigurasi artinya tidak akan melakukan pemrosesan keamanan apa pun pada file konfigurasi.
Urutan Pembacaan
Viper menggunakan prioritas berikut untuk membaca konfigurasi:
- Nilai yang diatur secara eksplisit
- Flag command line
- Variabel lingkungan
- File konfigurasi
- Key-value store
- Nilai default
TIP
Kunci dalam konfigurasi Viper tidak case-sensitive diskusi selanjutnya mungkin akan menjadikannya opsional.
Nilai Default
Sistem konfigurasi yang baik harus mendukung pengaturan nilai default meskipun terkadang tidak selalu diperlukan tetapi akan sangat berguna ketika file konfigurasi belum diatur berikut adalah contoh.
viper.SetDefault("filePath","./dir/img/usr")
viper.SetDefault("root","123456")Membaca File Konfigurasi
Viper hanya memerlukan sedikit konfigurasi untuk mengetahui di mana mencari file konfigurasi. Viper mendukung JSON TOML YAML HCL INI envfile dan file JavaProperties. Viper dapat mencari beberapa path secara bersamaan tetapi saat ini satu instance Viper hanya mendukung satu file konfigurasi. Viper tidak mengkonfigurasi path pencarian secara default menyerahkan keputusan default kepada aplikasi.
Berikut adalah contoh menggunakan Viper untuk membaca file konfigurasi tidak perlu menentukan path lengkap tetapi setidaknya harus menyediakan satu file konfigurasi saat digunakan.
func TestReadConfigFile(t *testing.T) {
viper.SetConfigName("config.yml") // Membaca file konfigurasi bernama config tanpa menentukan ekstensi file tertentu
viper.SetConfigType("yaml") // Harus menentukan jenis file ketika tidak menentukan ekstensi file tertentu
viper.AddConfigPath("./") // Mencari di folder saat ini
viper.AddConfigPath("$HOME/") // Menggunakan variabel
viper.AddConfigPath(".") // Mencari di direktori kerja
err := viper.ReadInConfig() // Membaca konfigurasi
if err != nil {
log.Fatalln(err)
}
}Juga dapat menangani kasus file konfigurasi tidak ditemukan secara terpisah
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
// File konfigurasi tidak ditemukan
} else {
// Jenis error lainnya
}
}Berikut adalah semua fungsi untuk mengakses konfigurasi
Get(key string) : interface{}GetBool(key string) : boolGetFloat64(key string) : float64GetInt(key string) : intGetIntSlice(key string) : []intGetString(key string) : stringGetStringMap(key string) : map[string]interface{}GetStringMapString(key string) : map[string]stringGetStringSlice(key string) : []stringGetTime(key string) : time.TimeGetDuration(key string) : time.DurationIsSet(key string) : boolAllSettings() : map[string]interface{}
Saat mengakses konfigurasi bersarang akses melalui pemisah . misalnya:
{
"server":{
"database":{
"url": "mysql...."
}
}
}Dapat mengakses bersarang melalui GetString("server.database.url")
Menulis File Konfigurasi
Viper menyediakan serangkaian fungsi untuk memudahkan developer menulis konfigurasi yang disimpan saat runtime ke dalam file konfigurasi.
// WriteConfig menulis konfigurasi ke file konfigurasi asli akan error jika tidak ada akan menimpa jika ada
func WriteConfig() error { return v.WriteConfig() }
// SafeWriteConfig menulis konfigurasi dengan aman ke file konfigurasi asli akan menulis jika tidak ada tidak akan menimpa jika ada
func SafeWriteConfig() error { return v.SafeWriteConfig() }
// WriteConfigAs menulis konfigurasi saat ini ke file yang ditentukan akan mengembalikan error jika file tidak ada akan menimpa konfigurasi asli jika ada
func WriteConfigAs(filename string) error { return v.WriteConfigAs(filename) }
// SafeWriteConfigAs jika file yang ditentukan ada tidak akan menimpa file konfigurasi asli akan mengembalikan error jika file ada
func SafeWriteConfigAs(filename string) error { return v.SafeWriteConfigAs(filename) }Berikut adalah beberapa contoh:
func TestWritingConfig(t *testing.T) {
viper.WriteConfig() // Menulis konfigurasi ke file konfigurasi asli file konfigurasi ini harus didefinisikan sebelumnya dengan 'viper.AddConfigPath()' dan 'viper.SetConfigName'
viper.SafeWriteConfig()
viper.WriteConfigAs("/path/to/my/.config")
viper.SafeWriteConfigAs("/path/to/my/.config") // Karena file yang ditentukan ada akan mengembalikan error
viper.SafeWriteConfigAs("/path/to/my/.other_config")
}Memantau dan Reload Konfigurasi
Viper memungkinkan aplikasi membaca file konfigurasi secara dinamis saat runtime yaitu konfigurasi yang diperbarui dapat berlaku tanpa perlu me-restart aplikasi dan tidak akan melewatkan setiap detail perubahan. Cukup beri tahu instance Viper untuk memantau perubahan konfigurasi atau dapat menyediakan fungsi ke viper agar menjalankan fungsi tersebut setiap kali terjadi perubahan.
func TestWatchingConfig(t *testing.T) {
viper.OnConfigChange(func(e fsnotify.Event) {
fmt.Println("File konfigurasi telah diubah:", e.Name)
})
viper.WatchConfig()
}Alias
func TestAliases(t *testing.T) {
viper.RegisterAlias("a", "b")
viper.Set("a", 1)
viper.Set("b", 2) // Akan menimpa konfigurasi a
fmt.Println(viper.GetInt("a"))
}Mengekstrak Substruktur
Sebelumnya disebutkan mengakses konfigurasi bersarang melalui pemisah . sebenarnya juga dapat mengekstrak substruktur melalui fungsi viper.Sub() nilai kembalian adalah instance Viper seperti contoh berikut:
cache:
cache1:
max-items: 100
item-size: 64
cache2:
max-items: 200
item-size: 80cache1Config := viper.Sub("cache.cache1")
if cache1Config == nil { // Mengembalikan nil jika tidak ada
panic("Konfigurasi cache1 tidak ada")
}Mengatur Pemisah Bersarang
Ketika ingin key yang ditentukan mengandung . harus menentukan pemisah lain secara manual untuk menghindari parsing yang salah misalnya:
viper.KeyDelimiter("/") // Mengatur pemisah menjadi /Deserialisasi
Viper menyediakan dua fungsi untuk mendeserialisasi konfigurasi ke struktur atau map juga mendukung struktur bersarang:
Unmarshal(rawVal interface{}) : errorUnmarshalKey(key string, rawVal interface{}) : error
type config struct {
Port int
Name string
PathMap string `mapstructure:"path_map"`
}
var C config
err := viper.Unmarshal(&C)
if err != nil {
t.Fatalf("Tidak dapat deserialisasi ke struktur, %v", err)
}Serialisasi
Menserialisasi konfigurasi saat ini ke string dalam format tertentu untuk disimpan dalam file konfigurasi biasanya mendukung JSON TOML YAML HCL envfile Java properties
TIP
Viper juga mendukung format serialisasi kustom Decoding custom formats with Viper - Márk Sági-Kazár (sagikazarmark.hu)
import (
yaml "gopkg.in/yaml.v2"
// ...
)
func yamlStringSettings() string {
c := viper.AllSettings()
bs, err := yaml.Marshal(c)
if err != nil {
log.Fatalf("Tidak dapat serialisasi konfigurasi ke YAML: %v", err)
}
return string(bs)
}Beberapa Instance
Biasanya menggunakan instance global yang disediakan Viper sudah cukup digunakan tetapi karena satu instance hanya dapat memetakan satu file konfigurasi dapat membuat beberapa instance sendiri untuk melakukan lebih banyak operasi misalnya:
x := viper.New()
y := viper.New()
x.SetDefault("ContentDir", "content")
y.SetDefault("ContentDir", "foobar")
//...