Search code examples
jsongostructmarshallingslice

Marshal slice of structs as slice of numbers


I'm trying to figure out what is the best way to marshal to JSON string below structure:

type User struct {
    Id string    `json:"id"`
    Roles []Role `json:"roles"`
}

type Role struct {
    Id string    `json:"-"`
    Role int     
}

Get JSON output like: {"id": "abc", "roles": [1, 2, 3]}


Solution

  • You can implement any custom marshaling logic by implementing the json.Marshaler interface.

    So simply implement the MarshalJSON() ([]byte, error) method on Role, in which you marshal it like a simple int number.

    This is how it could look like:

    func (r Role) MarshalJSON() ([]byte, error) {
        return json.Marshal(r.Role)
    }
    

    As you can see, Role.MarshalJSON() only marshals the Role.Role int field, and not the whole struct.

    Testing it:

    u := User{
        Id: "abc",
        Roles: []Role{
            Role{Id: "a", Role: 1},
            Role{Id: "b", Role: 2},
            Role{Id: "c", Role: 3},
        },
    }
    if err := json.NewEncoder(os.Stdout).Encode(u); err != nil {
        panic(err)
    }
    

    Output is as you expect it (try it on the Go Playground):

    {"id":"abc","roles":[1,2,3]}