Reputation: 341
I'm calling an API which will return Json objects like this:
{
name: "XXX"
type: "TYPE_1"
shared_fields: {...}
type_1_fields: {...}
..
type_2_fields: {...}
}
Based on different types, this object will have different kinds of fields, but these fields are certain for different types. So, I unmarshal the Json string to map[string]interface{} to fetch the the different type but how can I turn these map[string]interface{} to a certain struct?
var f map[string]interface{}
err := json.Unmarshal(b, &f)
type := f["type"]
switch type {
case "type_1":
//initialize struct of type_1
case "type_2":
//initialize struct of type_2
}
Upvotes: 1
Views: 711
Reputation: 3241
If the types are different enough and you want to be lazy you can just try to decode it in each format:
f1 := type1{}
err := json.Unmarshal(b, &f1)
if err == nil {
return f1
}
f2 := type2{}
err := json.Unmarshal(b, &f2)
if err == nil {
return f2
}
...
If the objects are similar or you want to be less lazy, you could just decode the type and then do something:
type BasicInfo struct {
Type string `json:"type"`
}
f := BasicInfo{}
err := json.Unmarshal(b, &f)
switch f.Type {
case "type_1":
//initialize struct of type_1
case "type_2":
//initialize struct of type_2
}
Upvotes: 0
Reputation: 9519
One way to do it would be to have a constructor function (one that starts with New…
) that takes a map as input parameter.
A second way, much slower in my opinion, would be to redo the unmarshalling to the right struct type.
Upvotes: 0
Reputation: 4373
For this sort of two-step json decoding you will probably want to check out json.RawMessage. It allows you to defer processing of parts of your json response. The example in the docs shows how.
Upvotes: 2