Golang: Struct Tagging for playing nice with data marshalling

Mipsmonsta
2 min readJan 5, 2022

--

The title sounds esoteric and is a mouth-full. So think of the case where you have the json file below and you need to read it into a struct. How would you do it and what are the pitfalls?

{suffix: "day", toRemove: true}

Let’s create the struct and try to read in and unmarshal the json string with the following code.

package hour20import (
"encoding/json"
"fmt"
"testing"
)
type suffixStruct struct {
Suffix string
ToRemove bool
}
func TestJsonToStruct(t *testing.T) {
jsonString := `{
suffix: "day",
toRemove: true,
}` //multiline string
aSuffix := suffixStruct{}err := json.Unmarshal([]byte(jsonString), &aSuffix)
if err != nil {
t.Fatal(err)
}
fmt.Printf("%+v\n", aSuffix)}

There is no error and the test pass. Most importantly, despite the case difference between “Suffix” in the struct and “struct” in the json key, the correct struct is created. Same for “ToRemove” and “toRemove” json key.

$ go test -v structToJsonExample_test.go
=== RUN TestJsonToStruct
{Suffix:day ToRemove:false}
— — PASS: TestJsonToStruct (0.00s)
PASS
ok command-line-arguments 0.034s

But what happen if the struct attributes are named differently?

type suffixStruct struct {
Suffix string
IsRemove bool
}

Unexpectedly, there is no error. But from the verbose output of the struct logged, you can see that the wrong bool value of false is captured, which is the zero value when IsRemove is initialized without assignment.

$ go test -v structToJsonExample_test.go
=== RUN TestJsonToStruct
{Suffix:day IsRemove:false}
 — — PASS: TestJsonToStruct (0.00s)
PASS
ok command-line-arguments 0.042s

Clearly you need a solution to bridge the different naming of attributes.

To solve this, struct tags are created by the author of Golang. These are tags created with multi-line syntax e.g. `json:"suffix"

type suffixStruct struct {
Suffix string
IsRemove bool `json:"toRemove"`
}

When we add the tag, then IsRemove is true as intended.

$ go test -v structToJsonExample_test.go
=== RUN TestJsonToStruct
{Suffix:day IsRemove:true}
 — — PASS: TestJsonToStruct (0.00s)
PASS
ok command-line-arguments 0.039s

Before we go, another important point to have struct tag for JSON is so that the exported (capitalized) variables for the JSON output will be in lower caps. This is the convention.

Happy coding!

--

--

Mipsmonsta

Writing to soothe the soul, programming to achieve flow