Home > front end >  Can I skip a json tag while Marshalling a struct in Golang?
Can I skip a json tag while Marshalling a struct in Golang?

Time:11-12

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
}

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

  • Related