Accessing Nested Config with Viper

Lorna Mitchell
2 min readJun 25, 2020

I’m writing a Go application that glues together a bunch of other things, so it has a whole bunch of basically unrelated config, dumped in a yaml file. I was struggling a little with this non-standard use of Viper but actually, it does everything I needed. And, presumaby, more besides. I thought I would put some examples here to show how to handle this.

A Slice of Structs

Let’s start with the configured colours to send to my LED shelf (which I realised I didn’t blog about, but I should!) In the config.yaml file it is a series of objects, with properties red, green and blue:

shelf_lights:
- red: 120
blue: 200
- red: 120
green: 150
- blue: 200
green: 40
red: 60

In my code, I have a struct called LEDColour to represent each of these objects, and it uses field tags to explain how the yaml data fits into the struct - similar to how the JSON field tags work if you've seen those. Viper uses a neat package called mapstructure to handle this part. My struct looks like this:

[pygmentize language=”go” ]0[/pygmentize]

To wrangle the yaml data into this structure, I declare the variable it will go into, then Viper has an UnmarshalKey which allows me to grab just the shelf_lights section from config and work on that.

[pygmentize language=”go” ]1[/pygmentize]

There was a lot of preamble but the actual moment it happens is neat!

Map of Structs with String Keys

This is pretty similar to above but I think a specific example might help. With a section of the yaml config file like this:

obs_scenes:
Camera:
name: Camera
image: "/camera.png"
Offline:
name: Offline
image: "/offline.png"
Secrets:
name: Secrets
image: "/secrets.png"

I have another struct, also with mapstructure features:

[pygmentize language=”go” ]2[/pygmentize]

The ButtonId field isn't updated until the scene is assigned to a button dynamically (this is from my streamdeck utility, OBS is a video streaming tool, don't worry if the words don't mean anything! One OBS has many scenes) so we don't need to include it when we're reading from config. Which looks like this:

[pygmentize language=”go” ]3[/pygmentize]

As usual, Viper has us covered and while for many applications it makes sense to read in the whole config file and refer to each setting as you need it, this ability to transform sections of config is very handy indeed!

Originally published at LornaJane.

--

--

Lorna Mitchell

Polyglot programmer, technology addict, open source fanatic and incurable blogger (see http://lornajane.net)