1

An api endpoint, not within my control, returns json with a key people that can have one of 2 types.

Json:

{
    "people":{
       "admin":{
           "Name": "John Smith",
           "Address": "123 main street"
        },
       "user":{
           "Name": "Jane Doe",
           "Address": "321 broad street",
       }
}

Json type 2:

{
    "people":[
        {
            "name": "Jon Snow",
            "pet": "Ghost"
        },
        {
            "name": "Sansa Stark",
            "pet": "Lady",
        }
    ]
}

For the first type, I can create a structs as so

type People struct {
   Admin *Person `json:"admin,omitempty"`
   User  *Person `json:"user,omitempty"`
}

type Person struct {
   Name string `json:"name,omitempty"`
   Address string `json:"adress,omitempty"`
}

or the second type as

type People []*Person
type Person struct{
    Name string `json:"name,omitempty"`
    Pet  string `json:"pet,omitempty"`
}

Is there a way to design a single struct such that I can unmarshal either type of response?

  • 1
    like so? http://stackoverflow.com/questions/32346117/unmarshalling-a-json-that-may-or-may-not-return-an-array – JimB Dec 03 '15 at 18:56
  • You definitely could but it would probably be a lot easier to just try with one type and if it fails try the other. Few other little things worth mentioning; 1) you can definitely have a single `Person` definition with `Name`, `Address` and `Pet`., 2) your first json snippet is one closing brace short of being valid. 3) in both cases there is an outer object which you don't account for in the models posted here (ie it is an object that contains an array called people which has objects of type person, not an array with objects of type person). – evanmcdonnal Dec 03 '15 at 19:17
  • Easier maybe isn't correct. To do it nicely you still have to write some code, I just think it's simpler to reason about. I recommend exposing a single type or interface and within the package where you unmarhsal while hiding the actual types you use. What you expose should be dictated by what's more intuitive for consumers. Like if the array response could have more than 2 Person's in it, I'd probably just return an array. Maybe I'd add a `Role` field and assign `"admin"` or `"user"` there when the response is of the first form. If it's always an admin and user I'd just return the first type. – evanmcdonnal Dec 03 '15 at 19:48

1 Answers1

0

I'd decode people to a map then do type assertion to figure whether it's an array or an object.

Zippo
  • 15,850
  • 10
  • 60
  • 58