I'd like to decode a JSON blob into a Go struct, manipulate on it, and encode it back to JSON. However, there are dynamic fields in the JSON that aren't relevant to my struct and I want to maintain them when I serialize back to JSON.
For example:
{ "name": "Joe Smith",
"age": 42,
"phone": "614-555-1212",
"debug": True,
"codeword": "wolf" }
type Person struct {
Name string
Age uint
Phone string
}
var p Person
json.Unmarshal(data, &p)
// Happy birthday
p.Age++
data, _ = json.Marshal(p)
// Any way to maintain the "debug" and "codeword" fields -- which might not
// be known ahead of time?
I know one possibility is to decode everything into a map[string]interface{}
but boy, do things get ugly when you do that.
Is there any way to have the best of both worlds?
To parse JSON, we use the Unmarshal() function in package encoding/json to unpack or decode the data from JSON to a struct. Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. Note: If v is nil or not a pointer, Unmarshal returns an InvalidUnmarshalError.
Marshal function, will take JSON data and translate it back into Go data. You provide json. Unmarshal with the JSON data as well as the Go variable to put the unmarshalled data into and it will either return an error value if it's unable to do it, or a nil error value if it succeeded.
Unmarshal is the contrary of marshal. It allows you to convert byte data into the original data structure. In go, unmarshaling is handled by the json. Unmarshal() method.
With encoding/json
there's no way to do decode a struct and save unknown fields at the same level for posterior re-encoding. What you can do is choose not to decode part of the struct by using the json.RawMessage type, along the lines of:
type Person struct {
Name string
Address json.RawMessage
}
You might workaround that by implementing your own Unmarshaler that decodes the document into a map and saves the unknown keys in a field of the struct, and then have a counterpart Marshaler that puts the fields back before marshaling.
Just out of curiosity, the feature you're looking for does exist in labix.org/v2/mgo/bson, via the inline tag flag, and the goal was to solve precisely the use case you're describing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With