Search code examples
jsongostructmarshalling

Can I skip a json tag while Marshalling a struct in Golang?


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"}}


Solution

  • 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