I have these nested structs in Go with custom tags for their properties,
type DummyParams struct {
Param1 string `yaml:"param1"`
Param2 string `yaml:"param2"`
}
type Dummy struct {
Name string `yaml:"name"`
Type string `yaml:"type"`
Params DummyParams `yaml:"params"`
}
I create some instances of Dummy and add them to a slice,
dummies := make([]Dummy, 0)
dummy1 := Dummy {
Name: "a"
Type: "type a"
Params: DummyParams {
Param1: "foo"
Param2: "bar"
}
}
dummies = append(dummies, dummy1)
dummy2 := Dummy {
Name: "b"
Type: "type b"
Params: DummyParams {
Param1: "foo"
Param2: "bar"
}
}
dummies = append(dummies, dummy2)
Finally I marshal the data and write it to file
yamlData, err := yaml.Marshal(&dummies)
// handle error ...
writeErr := os.WriteFile("foo.yaml", yamlData, 0644)
// handle write error ...
But the yaml I am getting does not have the lower case tagged names, instead it has the upper case Struct names. Anybody know why this is happening and how to fix it?
Blame it on the yaml implementation you're using. If you use gopkg.in/yaml.v3
for example, it works. Try it on the Go Playground. So one solution is to use another YAML implementation, such as gopkg.in/yaml.v3
.
You mentioned in the comments that you're using https://pkg.go.dev/sigs.k8s.io/yaml@v1.3.0. Its package doc says:
In short, this library first converts YAML to JSON using go-yaml and then uses
json.Marshal
andjson.Unmarshal
to convert to or from the struct. This means that it effectively reuses the JSON struct tags as well as the custom JSON methodsMarshalJSON
andUnmarshalJSON
unlike go-yaml.
So sigs.k8s.io/yaml@v1.3.0
first marshals to JSON. If you want lowercased field names, use json
tags instead of yaml
tags:
import "sigs.k8s.io/yaml"
type DummyParams struct {
Param1 string `json:"param1"`
Param2 string `json:"param2"`
}
type Dummy struct {
Name string `json:"name"`
Type string `json:"type"`
Params DummyParams `json:"params"`
}
With this change output contains lowercased names (try it on the Go Playground):
- name: a
params:
param1: foo
param2: bar
type: type a
- name: b
params:
param1: foo
param2: bar
type: type b
Note that having to use json
tags instead of yaml
to make it work is just a quirk of the sigs.k8s.io/yaml@v1.3.0
package. If you want to make it work with this package and other yaml implementations, you may provide both json
and yaml
tags:
type DummyParams struct {
Param1 string `json:"param1" yaml:"param1"`
Param2 string `json:"param2" yaml:"param2"`
}
type Dummy struct {
Name string `json:"name" yaml:"name"`
Type string `json:"type" yaml:"type"`
Params DummyParams `json:"params" yaml:"params"`
}