I have a scenario where I would like to skip a json tag while marshalling a struct in Golang. Is that possible? If so how can I achieve this?
For example I am getting this json:
{"Employee":{"Interface":{"Name":"xyz", "Address":"abc"}}}
But I want the json to be:
{"Employee":{"Name":"xyz", "Address":"abc"}}
CodePudding user response:
You can use anonymous structures
type Employee struct {
Interface Interface
}
type Interface struct {
Name string
Address string
}
func main() {
a := Employee{Interface: Interface{Name: "xyz", Address: "abc"}}
b := struct {
Employee Interface
}{
Employee: a.Interface,
}
jsonResult, _ := json.Marshal(b)
fmt.Println(string(jsonResult)) // {"Employee":{"Name":"xyz","Address":"abc"}}
}
CodePudding user response:
If the Interface
field's type is not an actual interface but a struct type then you could embed that field, this will promote the embedded struct's fields to Employee
and marshaling that into JSON will get you the output you want.
type Employee struct {
Interface // embedded field
}
type Interface struct {
Name string
Address string
}
func main() {
type Output struct{ Employee Employee }
e := Employee{Interface: Interface{Name: "xyz", Address: "abc"}}
out, err := json.Marshal(Output{e})
if err != nil {
panic(err)
}
fmt.Println(string(out))
}
https://play.golang.org/p/s5SFfDzVwPN
If the Interface
field's type is an actual interface type then embedding won't help, instead you could have the Employee
type implement the json.Marshaler
interface and customize the resulting JSON.
For example you could do the following:
type Employee struct {
Interface Interface `json:"-"`
}
func (e Employee) MarshalJSON() ([]byte, error) {
type E Employee
obj1, err := json.Marshal(E(e))
if err != nil {
return nil, err
}
obj2, err := json.Marshal(e.Interface)
if err != nil {
return nil, err
}
// join the two objects by dropping '}' from obj1 and
// dropping '{' from obj2 and then appending obj2 to obj1
//
// NOTE: if the Interface field was nil, or it contained a type
// other than a struct or a map or a pointer to those, then this
// will produce invalid JSON and marshal will fail with an error.
// If you expect those cases to occur in your program you should
// add some logic here to handle them.
return append(obj1[:len(obj1)-1], obj2[1:]...), nil
}