Recursive AI

Write a struct to a YAML file in Go

All oneyaml Go recipes

Call oneyaml.Marshal on the struct and write the bytes. Fields come out in declaration order, in block style, named by their yaml tags.

Terminal
mkdir write-yaml && cd write-yaml
go mod init example.com/write-yaml
go get oneyaml.dev/[email protected]

Put this in main.go and run go run .:

GO
package main
 
import (
	"fmt"
	"log"
	"os"
	"reflect"
 
	oneyaml "oneyaml.dev/go"
)
 
type Service struct {
	Name     string            `yaml:"name"`
	Image    string            `yaml:"image"`
	Replicas int               `yaml:"replicas"`
	Ports    []int             `yaml:"ports"`
	Env      map[string]string `yaml:"env"`
	Command  []string          `yaml:"command,omitempty"`
	Note     string            `yaml:"note"`
}
 
func main() {
	svc := Service{
		Name:     "web",
		Image:    "nginx:1.27",
		Replicas: 2,
		Ports:    []int{80, 443},
		Env:      map[string]string{"LOG_LEVEL": "info", "PORT": "8080"},
		Note:     "no",
	}
 
	out, err := oneyaml.Marshal(svc)
	if err != nil {
		log.Fatal(err)
	}
	if err := os.WriteFile("service.yaml", out, 0o644); err != nil {
		log.Fatal(err)
	}
	fmt.Print(string(out))
 
	// Read it back: the same value.
	var back Service
	if err := oneyaml.Unmarshal(out, &back); err != nil {
		log.Fatal(err)
	}
	fmt.Println("round trip equal:", reflect.DeepEqual(back, svc))
}
Text
name: web
image: nginx:1.27
replicas: 2
ports:
  - 80
  - 443
env:
  LOG_LEVEL: info
  PORT: '8080'
note: 'no'
round trip equal: true

command is empty and omitempty leaves it out. Map keys come out sorted. Strings that some reader could take for another type are quoted, so the file means what the struct held for every parser: '8080', and 'no', which unquoted a YAML 1.1 parser such as yaml.v2 would read as false. To stream several documents to a writer, use oneyaml.NewEncoder(w).

Limits

  • No comments. A struct has nowhere to keep them. To change a file people maintain by hand and keep its comments, edit it as a Document: edit YAML and keep its comments.
  • Map keys are sorted. When the order matters, use a struct, whose fields keep their declaration order.

To read the file into the struct: parse YAML into a struct.