Skip to content

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/viper

Pengenalan

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:

  1. Nilai yang diatur secara eksplisit
  2. Flag command line
  3. Variabel lingkungan
  4. File konfigurasi
  5. Key-value store
  6. 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.

go
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.

go
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

go
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) : bool
  • GetFloat64(key string) : float64
  • GetInt(key string) : int
  • GetIntSlice(key string) : []int
  • GetString(key string) : string
  • GetStringMap(key string) : map[string]interface{}
  • GetStringMapString(key string) : map[string]string
  • GetStringSlice(key string) : []string
  • GetTime(key string) : time.Time
  • GetDuration(key string) : time.Duration
  • IsSet(key string) : bool
  • AllSettings() : map[string]interface{}

Saat mengakses konfigurasi bersarang akses melalui pemisah . misalnya:

{
  "server":{
    "database":{
      "url": "mysql...."
    }
  }
}

Dapat mengakses bersarang melalui GetString("server.database.url")

Viper menyediakan serangkaian fungsi untuk memudahkan developer menulis konfigurasi yang disimpan saat runtime ke dalam file konfigurasi.

go
// 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:

go
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.

go
func TestWatchingConfig(t *testing.T) {
  viper.OnConfigChange(func(e fsnotify.Event) {
    fmt.Println("File konfigurasi telah diubah:", e.Name)
  })
  viper.WatchConfig()
}

Alias

go
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:

yaml
cache:
  cache1:
    max-items: 100
    item-size: 64
  cache2:
    max-items: 200
    item-size: 80
go
cache1Config := 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:

go
viper.KeyDelimiter("/") // Mengatur pemisah menjadi /

Deserialisasi

Viper menyediakan dua fungsi untuk mendeserialisasi konfigurasi ke struktur atau map juga mendukung struktur bersarang:

  • Unmarshal(rawVal interface{}) : error
  • UnmarshalKey(key string, rawVal interface{}) : error
go
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)

go
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:

go
x := viper.New()
y := viper.New()

x.SetDefault("ContentDir", "content")
y.SetDefault("ContentDir", "foobar")

//...

Golang by www.golangdev.cn edit