Home >Backend Development >Golang >How to Correctly MarshalJSON() When Embedding Structs with Custom MarshalJSON() Methods?

How to Correctly MarshalJSON() When Embedding Structs with Custom MarshalJSON() Methods?

Susan Sarandon
Susan SarandonOriginal
2024-12-16 07:22:10379browse

How to Correctly MarshalJSON() When Embedding Structs with Custom MarshalJSON() Methods?

Idiomatic Way to Embed Struct with Custom MarshalJSON() Method

Embedding a Struct with Custom MarshalJSON()

When embedding a struct with a custom MarshalJSON() method, the outer struct's fields are promoted to the promoted type, overriding the embedded struct's MarshalJSON() method. This can lead to unexpected results when marshalling the outer struct.

Problem:

Consider the following structs:

type Person struct {
    Name string `json:"name"`
}

func (p *Person) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct {
        Name string `json:"name"`
    }{
        Name: strings.ToUpper(p.Name),
    })
}

type Employee struct {
    *Person
    JobRole string `json:"jobRole"`
}

Marshalling an Employee instance produces unexpected results:

p := Person{"Bob"}
e := Employee{&p, "Sales"}
output, _ := json.Marshal(e)
fmt.Printf("%s\n", string(output))

Output:

{"name": "BOB"}

The jobRole field is missing, despite being set on the Employee instance.

Solution:

Option 1: Avoid MarshalJSON() on Embedded Type

  • Remove the MarshalJSON() method from the Person struct.
  • Instead, create a separate type (e.g., Name) that implements MarshalJSON().
  • Update the Person struct to use the new type (e.g., Person{Name: Name{"Bob"}}).
  • Employee structs will inherit the custom JSON encoding from the Name type.

Option 2: Implement MarshalJSON() on Outer Type

  • Implement a MarshalJSON() method on the Employee struct.
  • Call the embedded Person instance's MarshalJSON() method to obtain its JSON representation.
  • Unmarhsal the Person's JSON into an intermediate representation (e.g., map[string]interface{}).
  • Add the outer struct's fields to the intermediate representation and marshal it to JSON.

Note: Both options require some manual handling and may affect the ordering of fields in the final JSON output.

The above is the detailed content of How to Correctly MarshalJSON() When Embedding Structs with Custom MarshalJSON() Methods?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn