We get some JSON input, unmarshal, perform some work, then marshal and ship off somewhere else. The JSON we get may have a field named "user". When we marshal back to JSON we need to have that field "user" changed to "username". We can do this by creating a new struct with all the same fields, but different JSON tags, but that seemed a bit cumbersome. I thought a custom marshaller would work here, but I'm a bit stuck. Consider the following code.
package main
import (
"encoding/json"
"fmt"
)
type StructA struct {
Username string `json:"user"`
Process string `json:"process"`
}
func main() {
var test1 StructA
err := json.Unmarshal([]byte(`{"user": "user123", "process": "something"}`), &test1)
if err != nil {
fmt.Println(err)
}
// do some work with test1
jsonByte, err := json.Marshal(&test1)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(jsonByte))
}
func (u *StructA) MarshalJSON() ([]byte, error) {
type Alias StructA
return json.Marshal(&struct {
Username string `json:"username"`
*Alias
}{
Username: u.Username,
Alias: (*Alias)(u),
})
}
https://play.golang.org/p/_w0rlQrcgrW
Ideally this would allow me to change the JSON tag on that field from "user" to "username". However, I get both "username" and "user".
{"username":"user123","user":"user123","process":"something"}
I certainly could create an entirely new struct that mirrors StructA with the tags I want, but I don't have to have to copy every single field and worry about keeping those two structs in sync. It's not the end of the world, but it doesn't seem like a good approach.
To be clear, the end result I'm looking for is the following:
{"username":"user123","process":"something"}
I'm sure I'm missing something trivial here, but it's been a long week and any assistance would be appreciated. Thanks!