t313
t313

Reputation: 111

Unmarshal JSON with unknown objects

I've been searching my a** off but I couldn't find a solution that really helped me. I'm somewhat at a beginners level in go.

I have a JSON structure that has some parts that may change (see *_changing_name) and I have no access to change the JSON structure:

{
    "instance" : "http://woop.tld/api/v1/health",
    "version" : "1.0.0",
    "status" : {
        "Service1_changing_name" : {
            "isAlive" : true,
            "level" : 6,
            "message" : "Running under normal conditions"
        },
        "Service2_changing_name" : {
            "isAlive" : true,
            "level" : 1,
            "message" : "Critical condition"
        }
    },
    "errors" : {
        "level" : 1,
        "messages" : [
            "Service2 is in critical condition"
        ]
    },
    "performance" : {
        "operation" : {
            "changing_name1" : 10,
            "changing_name2" : 19839,
            "changing_name3" : 199,
            "changing_name4" : 99
        }
    }
}

I'm using this struct to unmarshal the JSON:

// HealthData object
type HealthData struct {
    Instance string `json:"instance"`
    Version  string `json:"version"`
    Status   interface {
    } `json:"status"`
    Errors struct {
        Level    int      `json:"level"`
        Messages []string `json:"messages"`
    } `json:"errors"`
    Performance struct {
        Operation map[string]interface {
        } `json:"operation"`
    } `json:"performance"`
}

Most solutions on Stackoverflow that I found are for some simpler structures without nested parts.

My problem are both the interface (Status) and map[string]interface (Operation). What am I missing to have the data in map and interface to more convenient arrays or slices?

Glad about any hint pointing me in the right direction.

Treize

Upvotes: 2

Views: 694

Answers (1)

vishal sharma
vishal sharma

Reputation: 54

I think, you should use this struct

type HealthData struct {
    Instance string `json:"instance"`
    Version  string `json:"version"`
    Status   map[string]struct {
        IsAlive bool   `json:"isAlive"`
        Level   int    `json:"level"`
        Message string `json:"message"`
    } `json:"status"`
    Errors struct {
        Level    int      `json:"level"`
        Messages []string `json:"messages"`
    } `json:"errors"`
    Performance struct {
        Operation map[string]int `json:"operation"`
    } `json:"performance"`
}

Then unmarshal is working like a charm.

healthData:=HealthData{}
if err:=json.Unmarshal(jsonData,&healthData); err!=nil{//error handling}

What am I missing to have the data in map and interface to more convenient arrays or slices?

for this just use a for loop, something like this

for key,_:=range healthData.Status{
        // you will get healthData.Status[key] as struct
}

and

for key,_:=range healthData.Performance.Operation{
        // you will get healthData.Performance.Operation[key] as int
}

Upvotes: 2

Related Questions