Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unmarshal a JSON array of heterogeneous structs

Tags:

json

go

I want to deserialise an object that includes an array of a some interface Entity:

type Result struct {
    Foo int;
    Bar []Entity;
};

Entity is an interface that is implemented by a number of struct types. JSON data identifies the struct type with a "type" field in each entity. E.g.

{"type":"t1","field1":1}
{"type":"t2","field2":2,"field3":3}

How would I go about deserialising the Result type in such a way that it correctly populates the array. From what I can see, I have to:

  1. Implement UnmarshalJSON on Result.
  2. Parse Bar as a []*json.RawMessage.
  3. Parse each raw message as map[string]interface{}.
  4. Check "type" field in the raw message.
  5. Create a struct of appropriate type.
  6. Parse the raw message again, this time into the just created struct.

This all sounds very tedious and boring. Is there a better way to do this? Or am I doing it backwards, and there is a more canonical method to handle an array of heterogeneous objects?

like image 449
Alex B Avatar asked Apr 14 '13 08:04

Alex B


1 Answers

I think your process is probably a bit more complicated than it has to be, see http://play.golang.org/p/0gahcMpuQc. A single map[string]interface{} will handle a lot of that for you.

Alternatively, you could make a type like

struct EntityUnion {
    Type string
    // Fields from t1
    // Fields from t2
    // ...
}

Unmarshal into that; it will set the Type string and fill in all the fields it can get from the JSON data. Then you just need a small function to copy the fields to the specific type.

like image 85
cthom06 Avatar answered Sep 20 '22 06:09

cthom06