Gotcha: Field casing is important when marshalling structs to JSON in Go

I'm trying to learn a bit of Go, and while working through a few things, I spotted a little gotcha with marshalling JSON from structs.
In tutorials and example code, I've seen a mix of structs with uppercase field names:
type User struct {
Name string
}
But also some with lowercase field names:
type User struct {
name string
}
Thinking that this didn't matter, I started using lowercase names, as I'm more used to lowercase, as a Java developer, and to my surprise, found that serialising this to JSON didn't work.
The following code:
package main
import (
"encoding/json"
"fmt"
)
type User struct {
name string
}
func main() {
r, err := json.Marshal(User{name: "Bob"})
if err != nil {
panic(err)
}
fmt.Println(string(r))
}
Would return me the following output:
{}
It turns out that this is an expected case, because according to this answer on StackOverflow:
This is because only fields starting with a capital letter are exported, or in other words visible outside the curent package (and in the json package in this case).
Therefore, the fix here was to make the following change, so the Name field would appear in the JSON as the $.name property:
type User struct {
- name string
+ Name string `json:"name"`
}