Skip to content

Viper

Depo Adresi: spf13/viper: Go configuration with fangs (github.com)

Dokümantasyon Adresi: spf13/viper: Go configuration with fangs (github.com)

TIP

Resmi olarak Viper2 geçişi tartışılıyor. İlgilenenler için: Viper2

Kurulum

go get github.com/spf13/viper

Giriş

Viper Go uygulamaları için eksiksiz bir yapılandırma dosyası çözümüdür. Neredeyse tüm türdeki yapılandırma ihtiyaçlarını ve formatlarını işleyebilir. Proje yapılandırma dosyalarını yönetmeyi kolaylaştırır ve aşağıdaki özelliklere sahiptir:

  • Varsayılan değer ayarlama
  • JSON, TOML, YAML, HCL, envfile, Java properties formatlarını destekler
  • Yapılandırma dosyalarının gerçek zamanlı izlenmesini ve yeniden yüklenmesini destekler
  • Ortam değişkenlerinden okumayı destekler
  • Uzaktan yapılandırma sisteminden yapılandırma okumayı ve değişiklikleri izlemeyi destekler
  • Komut satırı bayraklarını okumayı destekler
  • Buffer'dan okumayı destekler
  • Açıkça ayarlanmış değerleri destekler

Resmi olarak Viper tüm uygulama yapılandırma ihtiyaçlarını karşılayabilir. Geliştiriciler yalnızca uygulama oluşturmaya odaklanır. Viper yapılandırma yönetimini üstlenir. Birçok ünlü proje Viper kullanır:

DANGER

Viper yapılandırma dosyalarının şifrelenmesi ve şifresinin çözülmesinden sorumlu değildir. Yani yapılandırma dosyalarına herhangi bir güvenlik işlemi uygulamaz.

Okuma Sırası

Viper yapılandırmayı okumak için aşağıdaki önceliği kullanır:

  1. Açıkça ayarlanmış değer
  2. Komut satırı bayrağı
  3. Ortam değişkenleri
  4. Yapılandırma dosyası
  5. Anahtar-değer deposu
  6. Varsayılan değerler

TIP

Viper yapılandırmasındaki anahtarlar büyük/küçük harf duyarlı değildir. Gelecekteki tartışmalarda bu isteğe bağlı hale getirilebilir.

Varsayılan Değerler

İyi bir yapılandırma sistemi varsayılan değer ayarlamayı desteklemelidir. Her zaman gerekli olmasa da yapılandırma dosyası ayarlanmadığında çok kullanışlıdır. Aşağıda bir örnek verilmiştir:

go
viper.SetDefault("filePath","./dir/img/usr")
viper.SetDefault("root","123456")

Yapılandırma Dosyasını Okuma

Viper çok az yapılandırma ile yapılandırma dosyasının nerede bulunacağını bilir. Viper JSON, TOML, YAML, HCL, INI, envfile ve JavaProperties dosyalarını destekler. Viper birden fazla yolu aynı anda arayabilir ancak şu anda tek bir Viper örneği yalnızca tek bir yapılandırma dosyasını destekler. Viper varsayılan olarak arama yollarını yapılandırmaz. Varsayılan kararı uygulamaya bırakır.

Aşağıda Viper ile yapılandırma dosyası okuma örneği verilmiştir. Tam bir yol belirtmenize gerek yoktur ancak kullanırken en azından bir yapılandırma dosyası sağlamalısınız:

go
func TestReadConfigFile(t *testing.T) {
   viper.SetConfigName("config.yml") // config adında yapılandırma dosyası oku. Belirli bir dosya uzantısı ayarlanmamış
   viper.SetConfigType("yaml")       // Belirli bir dosya uzantısı ayarlanmadığında dosya türünü belirtmek gerekir
   viper.AddConfigPath("./")         // Geçerli dizinde ara
   viper.AddConfigPath("$HOME/")     // Değişken kullan
   viper.AddConfigPath(".")          // Çalışma dizininde ara
   err := viper.ReadInConfig() // Yapılandırmayı oku
   if err != nil {
      log.Fatalln(err)
   }
}

Yapılandırma dosyası bulunamadı durumunu ayrı olarak işleyebilirsiniz:

go
if err := viper.ReadInConfig(); err != nil {
  if _, ok := err.(viper.ConfigFileNotFoundError); ok {
    // Yapılandırma dosyası bulunamadı
  } else {
    // Diğer hata türleri
  }
}

Yapılandırmaya erişmek için tüm fonksiyonlar:

  • 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{}

İç içe geçmiş yapılandırmalara erişirken . ayırıcı kullanılır. Örneğin:

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

GetString("server.database.url") ile iç içe erişim yapılabilir.

Yapılandırma Dosyasına Yazma

Viper geliştiricilerin çalışma zamanında depolanan yapılandırmayı yapılandırma dosyasına yazmasını kolaylaştıran bir dizi fonksiyon sağlar:

go
// WriteConfig yapılandırmayı orijinal yapılandırma dosyasına yazar. Dosya yoksa hata verir. Varsa üzerine yazar.
func WriteConfig() error { return v.WriteConfig() }

// SafeWriteConfig yapılandırmayı güvenli şekilde orijinal yapılandırma dosyasına yazar. Dosya yoksa yazar. Varsa üzerine yazmaz.
func SafeWriteConfig() error { return v.SafeWriteConfig() }

// WriteConfigAs geçerli yapılandırmayı belirtilen dosyaya yazar. Dosya yoksa hata döner. Varsa üzerine yazar.
func WriteConfigAs(filename string) error { return v.WriteConfigAs(filename) }

// SafeWriteConfigAs belirtilen dosya varsa orijinal yapılandırma dosyasına yazmaz. Dosya varsa hata döner.
func SafeWriteConfigAs(filename string) error { return v.SafeWriteConfigAs(filename) }

Aşağıda bazı örnekler verilmiştir:

go
func TestWritingConfig(t *testing.T) {
   viper.WriteConfig() // Yapılandırmayı orijinal dosyaya yazar. Bu dosyalar 'viper.AddConfigPath()' ve 'viper.SetConfigName' ile tanımlanmış olmalıdır
   viper.SafeWriteConfig()
   viper.WriteConfigAs("/path/to/my/.config")
   viper.SafeWriteConfigAs("/path/to/my/.config") // Belirtilen dosya var olduğu için hata dönecektir
   viper.SafeWriteConfigAs("/path/to/my/.other_config")
}

İzleme ve Yeniden Yükleme

Viper uygulamaların çalışma zamanında yapılandırma dosyasını dinamik olarak okumasına izin verir. Yani uygulamayı yeniden başlatmadan güncellenmiş yapılandırmanın etkili olmasını sağlar. Her değişikliği kaçırmez. Viper örneğine yapılandırma değişikliklerini izlemesini söylemek yeterlidir. Veya her değişiklik olduğunda çalıştırılması için Viper'a bir fonksiyon sağlayabilirsiniz:

go
func TestWatchingConfig(t *testing.T) {
  viper.OnConfigChange(func(e fsnotify.Event) {
    fmt.Println("Yapılandırma dosyası değiştirildi:", e.Name)
  })
  viper.WatchConfig()
}

Takma Adlar

go
func TestAliases(t *testing.T) {
   viper.RegisterAlias("a", "b")
   viper.Set("a", 1)
   viper.Set("b", 2) // a'nın yapılandırmasının üzerine yazacaktır
   fmt.Println(viper.GetInt("a"))
}

Alt Yapıları Çıkarma

Önceki bölümde iç içe geçmiş yapılandırmalara erişmek için . ayırıcı kullanıldığı belirtildi. Aslında viper.Sub() fonksiyonu ile alt yapıları çıkarmak da mümkündür. Dönüş değeri bir Viper örneğidir. Aşağıdaki örnek:

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 { // Yoksa nil döner
  panic("cache1 yapılandırması mevcut değil")
}

İç İçe Ayırıcı Ayarlama

Belirtilen anahtar . içerdiğinde yanlış ayrıştırmayı önlemek için manuel olarak başka bir ayırıcı belirtmek gerekir. Örneğin:

go
viper.KeyDelimiter("/") // Ayırıcıyı / olarak ayarla

Serileştirme

Viper yapılandırmayı bir struct veya map'e serileştirmek için iki fonksiyon sağlar. İç içe yapıları da destekler:

  • 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("Struct'a serileştirilemiyor, %v", err)
}

Serileştirme

Mevcut yapılandırmayı yapılandırma dosyasına saklamak için belirli bir formatta string'e serileştirir. Genellikle JSON, TOML, YAML, HCL, envfile, Java properties desteklenir.

TIP

Viper özel serileştirme formatlarını da destekler: 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("Yapılandırma YAML olarak serileştirilemiyor: %v", err)
  }
  return string(bs)
}

Birden Fazla Örnek

Genellikle Viper tarafından sağlanan global örnek kullanmak için yeterlidir. Ancak bir örnek yalnızca bir yapılandırma dosyasıyla eşlenebildiğinden daha fazla işlem gerçekleştirmek için birden fazla örnek oluşturabilirsiniz. Örneğin:

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

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

//...

Golang by www.golangdev.cn edit