Drathier
Drathier

Reputation: 14509

Go unmarshal json with a field that is an array of objects or strings

In go you unmarshal json into a struct. The problem is that I have an api that might change the type of the value of a key from request to request.

For example objects that might be inlined objects like this:

{
  "mykey": [
    {obj1}, 
    {obj2}
  ]
}

but also point to objects by keys, like this:

{
  "mykey": [
    "/obj1/is/at/this/path", 
    "/obj2/is/at/this/other/path"
  ]
}

Some objects can be inlined, but others are referenced from multiple locations.

In javascript or python this wouldn't be a problem. Just check the type.

What's the go-idiomatic way to unmarshal and parse these two objects? Is Reflect the only way?

Upvotes: 3

Views: 2285

Answers (1)

James Henstridge
James Henstridge

Reputation: 43899

You could unmarshal this JSON to a structure like the following:

type Data struct {
    MyKey []interface{} `json:"mykey"`
}

If the JSON includes strings, they will be decoded as strings in the array. If the JSON includes objects, they will be decoded as map[string]interface{} values. You can distinguish between the two using a type switch. Something like this:

for i, v := range data.MyKey {
    switch x := v.(type) {
    case string:
        fmt.Println("Got a string: ", x)
    case map[string]interface{}:
        fmt.Printf("Got an object: %#v\n", x)
    }
}

You can play around with this example here: http://play.golang.org/p/PzwFI2FSav

Upvotes: 4

Related Questions