Golang parse YAML file [Simple and Nested]

In this tutorial, we will walk through how to work with yaml file in Golang. If you familiar with Kubernetes, you know that we can create pods using yaml file. Here is an example of a yaml file:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
spec: 
  containers:
  - name: nginx
  image: nginx
  ports:
  - containerPort: 80

Some time, we may want to parse this kind of file to a Golang application. Golang provide yaml package to help us cope with this problem:

Advertisement

The yaml package enables Go programs to comfortably encode and decode YAML values. It was developed within Canonical as part of the juju project, and is based on a pure Go port of the well-known libyaml C library to parse and generate YAML data quickly and reliably.

 

Parse simple YAML file using Golang yaml package

The import path for the package is gopkg.in/yaml.v2.

To install it, run:

go get gopkg.in/yaml.v2

We will use Unmarshal() to decode the yaml file's content

func Unmarshal(in []byte, out interface{}) (err error): Unmarshal decodes the first document found within the in byte slice and assigns decoded values into the out value. Maps and pointers (to a struct, string, int, etc) are accepted as out values. If an internal pointer within a struct is not initialized, the yaml package will initialize it if necessary for unmarshalling the provided data. The out parameter must not be nil.

In the first example, we read a simple yaml (example1.yaml) file:

one: 1
two: 2
three: 3
four: 4
five: 5
six: 6

Example Go code:

Advertisement
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"gopkg.in/yaml.v2"
)

func main() {

	file, err := ioutil.ReadFile("example1.yaml")
	if err != nil {
		log.Fatal(err)
	}

	parsedData := make(map[interface{}]interface{})

	err2 := yaml.Unmarshal(file, &parsedData)
	if err2 != nil {
		log.Fatal(err2)
	}

	for k, v := range parsedData {
		fmt.Printf("%s -> %d\n", k, v)
	}
}

Output:

one -> 1
two -> 2
three -> 3
four -> 4
five -> 5
six -> 6

Explanation:

  • Firstly, read the content of the file
  • Define a map to store the parsed data. Since we do not know the type of the field name and the value, we use interface{} type.
  • Parse the data into the map by using Unmarshal function()
  • Print out the field name - value pairs

 

Parse complex YAML file using Golang YAML package

In this example, we will parse a more complex yaml (example2.yaml) file. In this example, we define a complex struct instead of simple map to store the parsed data.

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: default
spec: 
  containers:
  - name: nginx
  image: nginx
  ports:
  - containerPort: 80

Example go code:

package main

import (
	"fmt"
	"io/ioutil"

	"gopkg.in/yaml.v2"
)

type KubernetesStruct struct {
	APIVersion string `yaml:"apiVersion"`
	Kind       string `yaml:"kind"`
	Metadata   struct {
		Name      string `yaml:"name"`
		Namespace string `yaml:"namespace"`
	} `yaml:"metadata"`
	Spec struct {
		Containers []struct {
			Name string `yaml:"name"`
		} `yaml:"containers"`
		Image string `yaml:"image"`
		Ports []struct {
			ContainerPort int `yaml:"containerPort"`
		} `yaml:"ports"`
	} `yaml:"spec"`
}

func main() {
	file, err := ioutil.ReadFile("example2.yaml")

	if err != nil {
		panic(err)
	}

	var kubernetesStruct KubernetesStruct

	err = yaml.Unmarshal(file, &kubernetesStruct)
	if err != nil {
		panic(err)
	}

	fmt.Printf("Value: %#v\n", kubernetesStruct.APIVersion)
	fmt.Printf("Value: %#v\n", kubernetesStruct.Metadata.Name)
	fmt.Printf("Value: %#v\n", kubernetesStruct.Spec.Ports)
}

Output:

Value: "v1"
Value: "nginx"
Value: []struct { ContainerPort int "yaml:\"containerPort\"" }{struct { ContainerPort int "yaml:\"containerPort\"" }{ContainerPort:80}}

 

Summary

In this tutorial we learned how to parse YAML file (Simple and Complex with multiple nested keys) using golang yaml package. We use yaml.Unmarshal to store the values of YAML key into struct or map and then access the struct content.

 

References

https://pkg.go.dev/gopkg.in/yaml.v2

 

Categories GO

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment

X