I faced recently the following problem and have not found any solution. I have two struct types in Go, let us call them Parent and Child. Child has an anonymous field of the type *Parent. However, Parent has a field called "ID" which has the type of a third struct which type we will call "IDType" (in my real problem this is a dialect/sql.NullInt64). IDType has an int field and a bool field.
The problem is the following: Both, Parent and Child, implement MarshalJSON() because for Parent I only want the int field inside the JSON and for Child the same. However, it seems that both MarshalJSONs infer with the result that only the values of Parent are encoded in the final JSON.
Maybe a minimal example makes it easier to understand:
package main
import (
"encoding/json"
"fmt"
"os"
)
type IDType struct {
Value int
Valid bool
}
type Parent struct {
ID IDType `json:"id"`
SomeString string `json:"some_string"`
}
type Child struct {
*Parent
Status int `json:"status"`
}
func (parent *Parent) MarshalJSON() ([]byte, error) {
type Alias Parent
fmt.Println("Parent")
return json.Marshal(struct {
*Alias
ID int `json:"id"`
}{
Alias: (*Alias)(parent),
ID: parent.ID.Value,
})
}
func (child *Child) MarshalJSON() ([]byte, error) {
type Alias Child
fmt.Println("Child")
return json.Marshal(struct {
*Alias
Status int `json:"status"`
}{
Alias: (*Alias)(child),
Status: child.Status,
})
}
func main() {
ID := IDType{Value: 1, Valid: true}
parent := Parent{ID: ID, SomeString: "Hello"}
child := Child{Parent: &Parent{ID: ID, SomeString: "Hello"}, Status: 1}
json.NewEncoder(os.Stdout).Encode(&parent)
json.NewEncoder(os.Stdout).Encode(&child)
}
The output is:
Parent
{"some_string":"Hello","id":1}
Child
Parent
{"some_string":"Hello","id":1}
I expect something like:
Parent
{"some_string":"Hello","id":1}
Child
Parent
{"some_string":"Hello","id":1, "status": 1}