Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show empty object instead of empty struct or nil in Go json marshal

I need to show json's empty object {} when do json.Marshal() for a struct pointer. I can only output either null value or empty struct value.

If the person key is filled with &Person{} or new(Person), it will show empty struct like below:

{
    "data": {
        "person": {
            "name": "",
            "age": 0
        },
        "created_date": "2009-11-10T23:00:00Z"
    }
}

And if we don't initialize it at all, it will show null.

{
    "data": {
        "person": null,
        "created_date": "2009-11-10T23:00:00Z"
    }
}

I want to show "person": {}. Is it possible?

Go Playground for the complete code: https://play.golang.org/p/tT15G2ESPVc

like image 391
tama Avatar asked May 02 '18 14:05

tama


1 Answers

Option A, use the omitempty tag option on all of the Person's fields and make sure the response's field is allocated before marshaling.

type Person struct {
    Name string `json:"name,omitempty"`
    Age  int    `json:"age,omitempty"`
}

// ...

resp.Person = new(Person)

https://play.golang.org/p/o3jWdru_8bC


Option B, use a non-pointer wrapper type that embeds the Person pointer type.

type PersonJSON struct {
    *Person
}

type Response struct {
    Person      PersonJSON `json:"person"`
    CreatedDate time.Time   `json:"created_date"`
}

https://play.golang.org/p/EKQc7uf1_Vk


Option C, have the Reponse type implement the json.Marshaler interface.

func (r *Response) MarshalJSON() ([]byte, error) {
    type tmp Response
    resp := (*tmp)(r)

    var data struct {
        Wrapper struct {
            *Person
        } `json:"person"`
        *tmp
    }
    data.Wrapper.Person = resp.Person
    data.tmp = resp
    return json.Marshal(data)
}

https://play.golang.org/p/1qkSCWZ225j


There may be other options...

like image 69
mkopriva Avatar answered Nov 15 '22 04:11

mkopriva