I have a struct Table with 2 Players, but I need to ignore some properties from the struct Player
when I send JSON.
I could use json:"-"
, but then the property will be ignored ALWAYS, and I need to ignore it only when I send the Table struct. I need those properties when I send the Player
in other parts of the code.
I have:
type Player struct {
Id Int64 `json:"id"`
Username string `json:"username,omitempty"`
Password string `json:"-,omitempty"`
Email string `json:"email,omitempty"`
Birthdate time.Time `json:"birthdate,omitempty"`
Avatar string `json:avatar,omitempty"`
}
type Table struct {
Id int `json:"id"`
PlayerTop Player `json:"playerTop"`
PlayerBottom Player `json:"playerBottom"`
}
I need:
{
"Table": {
"id": 1,
"playerBottom": {
"id": 1,
"username": "peter",
"avatar": "avatar.png"
},
"playerTop": {
"id": 1,
"username": "peter",
"avatar": "avatar.png"
}
}
}
The players come from the database, so the properties aren't empty.
a) I could do something like:
myTable = new(Table)
myTable.PlayerBottom.Email = ""
myTable.PlayerBottom.Birthdate = ""
myTable.PlayerTop.Email = ""
myTable.PlayerTop.Birthdate = ""
so those properties will be ignored in the JSON, thanks to json:"omitempty"
, but this is a bad idea.
b) I could use something like an alias struct but Table
is expecting that PlayerBottom
is of type Player
not PlayerAlias
, but I don't know how to implement it:
type PlayerAlias struct {
Id Int64 `json:"id"`
Username string `json:"username,omitempty"`
Avatar string `json:avatar,omitempty"`
}
c) I tried to add dynamically json:"-"
to the properties that I don't want from the JSON before to send it, but it was a mess.
To ignore individual properties, use the [JsonIgnore] attribute. You can specify conditional exclusion by setting the [JsonIgnore] attribute's Condition property. The JsonIgnoreCondition enum provides the following options: Always - The property is always ignored.
property names must start with lower case letter. Dictionary must be serialized into jsonp where keys will be used for property names. LowerCase rule does not apply for dictionary keys.
You could create a custom Marshaler
for Table
types. This is the interface you have to implement:
https://golang.org/pkg/encoding/json/#Marshaler
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
Then you'd remove the -
tag from Player
(because when you marshal it elsewhere you need to preserve the fields) and only ignore it in the custom MarshalJSON
method of Table
.
Here's a simple (unrelated) example of implementing custom marshaling for a type, encoding one of the fields in hex:
type Account struct {
Id int32
Name string
}
func (a Account) MarshalJSON() ([]byte, error) {
m := map[string]string{
"id": fmt.Sprintf("0x%08x", a.Id),
"name": a.Name,
}
return json.Marshal(m)
}
func main() {
joe := Account{Id: 123, Name: "Joe"}
fmt.Println(joe)
s, _ := json.Marshal(joe)
fmt.Println(string(s))
}
As you can see here, such marshaling is easy to do by constructing a map
with just the fields you need and passing it to json.Marshal
. For your Table
and Player
this will result in just a few lines of trivial code. IMHO it's better to do this than to modify the types and complicate them with embeddings/aliases, just for the sake of JSON encoding.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With