json.Marshal(struct) returns "{}"

ghz 9months ago ⋅ 106 views
type TestObject struct {
    kind string `json:"kind"`
    id   string `json:"id, omitempty"`
    name  string `json:"name"`
    email string `json:"email"`
}

func TestCreateSingleItemResponse(t *testing.T) {
    testObject := new(TestObject)
    testObject.kind = "TestObject"
    testObject.id = "f73h5jf8"
    testObject.name = "Yuri Gagarin"
    testObject.email = "Yuri.Gagarin@Vostok.com"

    fmt.Println(testObject)

    b, err := json.Marshal(testObject)

    if err != nil {
        fmt.Println(err)
    }

    fmt.Println(string(b[:]))
}

Here is the output:

[ `go test -test.run="^TestCreateSingleItemResponse$"` | done: 2.195666095s ]
    {TestObject f73h5jf8 Yuri Gagarin Yuri.Gagarin@Vostok.com}
    {}
    PASS

Why is the JSON essentially empty?

Answers

The issue in your code is related to the field tags used in the TestObject struct. In Go, field tags are used to provide additional metadata about struct fields, such as JSON serialization options. However, the tags need to be exported (i.e., start with an uppercase letter) to be recognized by external packages like encoding/json.

Here's the corrected version of your struct definition:

type TestObject struct {
    Kind  string `json:"kind"`
    ID    string `json:"id,omitempty"`
    Name  string `json:"name"`
    Email string `json:"email"`
}

Changes made:

  • Capitalized the field names to export them.
  • Added the omitempty option to the id field tag.

With these changes, the json.Marshal function will correctly serialize the TestObject instance into JSON format, including only non-empty fields and using the specified JSON field names.