Given the following code: (reproduced here at play.golang.org.)
package main
import (
"encoding/json"
"fmt"
)
type User struct {
Make use of omitempty tags and a bit of logic so you can use a single type that produces the right output for different cases.
The trick is knowing when a value is considered empty by the JSON encoder. From the encoding/json documentation:
The empty values are false, 0, any nil pointer or interface value, and any array, slice, map, or string of length zero.
Here is your program slightly modified to produce the output you wanted. It omits certain fields when their values are "empty" - specifically, the JSON encoder will omit ints with "0" as value and maps with zero-length.
package main
import (
"encoding/json"
"fmt"
)
type User struct {
Id int `json:"id"`
Name string `json:"name,omitempty"`
UserId int `json:"userId,omitempty"`
Links map[string]string `json:"_links,omitempty"`
}
func Marshal(u *User) ([]byte, error) {
u.Links = make(map[string]string)
if u.UserId != 0 {
u.Links["self"] = fmt.Sprintf("http://user/%d", u.UserId)
} else if u.Id != 0 {
u.Links["self"] = fmt.Sprintf("http://session/%d", u.Id)
}
return json.MarshalIndent(u, "", " ")
}
func main() {
u := &User{Id: 123, Name: "James Dean"}
s := &User{Id: 456, UserId: 123}
json, err := Marshal(u)
if err != nil {
panic(err)
} else {
fmt.Println(string(json))
}
json, err = Marshal(s)
if err != nil {
panic(err)
} else {
fmt.Println(string(json))
}
}
Copy on play.golang.org.