简体   繁体   中英

golang - decode dynamic 'flat' http-json response

I am trying to parse a dynamic http-json response in a classic go-struct. I am working with orient-db and the problem is the follow:

  • there are ever static element for each object
  • each object has custom attributes

For example, a pseudo-struct-response could be:

type orientdb_reply struct {
  # the "statics" elements that we always have
  element_type string   `json:"@type"`
  rid          string   `json:"@rid"`
  version      int      `json:"@version"`
  class        string   `json:"@class"`

  # then we have custom attributes for each object

  # for example, object 'server' can have
  hostname     string   `json:"hostname"`
  ip           string   `json:"ip"`

  # object 'display' can have
  model         string  `json:"model"`
  serial_number string  `json:"serial_number"`
  resolution    string  `json:"resolution"`

  # and so on
}

The difficulty in this case is that the response is "flat", if it contains sub-element the resolution is trivial and could be adding simply other structs as child.

But in this case I would like avoid to build a mega-huge struct that contains each possible attribute and I would like to keep the structure separate for object-type without repeating the constants elements in each object-struct.

Is this possible?


A possible solution, that now I see could be:

type constant_fields struct {
  # the "constants" elements that we ever have
  element_type string   `json:"@type"`
  rid          string   `json:"@rid"`
  version      int      `json:"@version"`
  class        string   `json:"@class"`
}

type server_fields struct {
  constants     constant_fields
  # for example, object 'server' can have
  hostname     string   `json:"hostname"`
  ip           string   `json:"ip"`
}

type display_fields struct {
  constants     constant_fields
  # object 'display' can have
  model         string  `json:"model"`
  serial_number string  `json:"serial_number"`
  resolution    string  `json:"resolution"`
}

But this means that I should parse twice each request (one for constants stuff and another for the attributes stuff). And I don't know if the parser likes a "strange" struct ( constant_fields ) not really present in the json.


Real example:

{
   "result" : [
      {
         "name" : "cen110t",
         "guest_state" : "running",
         "@type" : "d",
         "guest_mac_addr" : "XX:XX:XX:XX:XX:XX",
         "@version" : 1,
         "hostname" : "",
         "vm_uid" : "vm-29994",
         "guest_ip" : "10.200.1.92",
         "vm_type" : "VirtualMachine",
         "@rid" : "#13:103",
         "guest_family" : "linuxGuest",
         "storage_type" : "",
         "guest_fullname" : "CentOS 4/5/6/7 (64-bit)",
         "@class" : "VM"
      }
   ]
}

I would like avoid to build a mega-huge struct that contains each possible attribute

use json.RawMessage for a attribute type in you struct definition, then this attribute will be kept in raw and not parsed.

I would like to keep the structure separate for object-type without repeating the statics element in each object-struct

of cause you can nest struct in struct, just like json object in json object. put the common(statics) attributes in one json object and nest it is a good way.

to the question update

yes it will work. json parser will handle nested struct for you, not need to parse twice. but your json string need match the Go's struct structure. like json

{
    "k1":"v1",
    "k2":{
        "k21":"v21"
    }
}

will match go struct:

type nest_struct struct{
    K21 string `k21`
}

type top struct{
    K1 string `k1`,
    K2 nest_struct `k2`
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM