An idiomatic way to embed a structure using the custom MarshalJSON () method

Given the following structures:

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

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

I can easily fake Employee JSON as expected:

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

Conclusion:

{"name": "Bob", "jobRole": "Sale"}

But when the inline structure has its own method MarshalJSON()...

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

it breaks completely:

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

Now the results:

{"name": "BOB"}

(Note the noticeable drawback of the field jobRole)

It is easy to expect ... the built-in Personstruct implements the function MarshalJSON()that is called.

The problem is that I do not want this. I would like to:

{"name": "BOB", "jobRole": "Sale"}

, Employee Person MarshalJSON() JSON.

MarshalJSON() Employee, , , MarshalJSON(), (a) (b) Person MarshalJSON() - , . (, , , MarshalJSON()?)

, ?

+4
1

MarshalJSON Person, . type Name string Name MarshalJSON. Person

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

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


, MarshalJSON . , . , MarshalJSON, map[string]interface{} . ,

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

+4

Source: https://habr.com/ru/post/1648568/


All Articles