Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use Viper to get a value from a nested YAML structure?

Tags:

go

viper-go

How do I write the code below to get a string from my nested yaml struct?

Here is my yaml:

element:
  - one:
      url: http://test
      nested: 123
  - two:
      url: http://test
      nested: 123

weather:
  - test:
      zipcode: 12345
  - ca:
      zipcode: 90210

Here is example code

viper.SetConfigName("main_config")
  viper.AddConfigPath(".")
  err := viper.ReadInConfig()
  if err != nil {
    panic(err)
  }
testvar := viper.GetString("element.one.url")

My problem:

I get a blank string when I print this. According to the docs, this is how you get a nested element. I suspect its not working because the elements are lists. Do I need to do a struct? I am not sure how to make one, especially if it needs to be nested.

like image 600
Defenestrator6 Avatar asked Oct 01 '18 06:10

Defenestrator6


People also ask

What is Viper Unmarshal?

Viper is a very popular Golang package for this purpose. It can find, load, and unmarshal values from a config file. It supports many types of files, such as JSON, TOML, YAML, ENV, or INI. It can also read values from environment variables or command-line flags.

How do you use Viper in Golang?

Installing Viper is similar to installing any package in Go. The first step is to initialize the Go mod file. The best way to do this is to initialize the folder with git init . Next, set up the git origin using git remote add origin ORIGIN_URL , then initialize the project with go mod init .

What is Viper configuration?

Viper is a configuration management solution for Go applications which allows you to specify configuration options for your application in several ways, including configuration files, environment variables, and command-line flags. Cobra enables Viper by running the function initConfig when initializing the application.


1 Answers

There are different Get methods available in viper library and your YML structure is of type []map[string]string, so to parse your YML configuration file you have to use viper.Get method. So you have to parse your file something like this..

Note: You can use struct as well to un-marshal the data. Please refer this post mapping-nested-config-yaml-to-struct

package main

import (
    "fmt"

    "github.com/spf13/viper"
)

func main() {
    viper.SetConfigName("config")
    viper.AddConfigPath(".")
    err := viper.ReadInConfig()
    if err != nil {
        panic(err)
    }
    testvar := viper.Get("element")
    fmt.Println(testvar)
    elementsMap := testvar.([]interface{})
    for k, vmap := range elementsMap {
        fmt.Print("Key: ", k) 
        fmt.Println(" Value: ", vmap)
        eachElementsMap := vmap.(map[interface{}]interface{})

        for k, vEachValMap := range eachElementsMap {
            fmt.Printf("%v: %v \n", k, vEachValMap)
            vEachValDataMap := vEachValMap.(map[interface{}]interface{})

            for k, v := range vEachValDataMap {
                fmt.Printf("%v: %v \n", k, v)
            }
        }
    }
}

// Output:
/*
Key: 0 Value:  map[one:map[url:http://test nested:123]]
one: map[url:http://test nested:123]
url: http://test
nested: 123
Key: 1 Value:  map[two:map[url:http://test nested:123]]
two: map[url:http://test nested:123]
url: http://test
nested: 123
*/
like image 94
Deepak Singh Avatar answered Sep 24 '22 00:09

Deepak Singh