简体   繁体   English

golang-解码动态“扁平” http-json响应

[英]golang - decode dynamic 'flat' http-json response

I am trying to parse a dynamic http-json response in a classic go-struct. 我试图解析经典的go-struct中的动态http-json响应。 I am working with orient-db and the problem is the follow: 我正在使用Orient-db,问题如下:

  • 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. 而且我不知道解析器是否喜欢json中没有的“奇怪”结构( constant_fields )。


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. 在结构定义中使用json.RawMessage作为属性类型,则此属性将保留在原始文件中,而不进行解析。

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. 因为您可以将struct嵌套在struct中,就像json对象中的json对象一样。 put the common(statics) attributes in one json object and nest it is a good way. 将common(statics)属性放在一个json对象中并嵌套是一种好方法。

to the question update

yes it will work. 是的,它将起作用。 json parser will handle nested struct for you, not need to parse twice. json解析器将为您处理嵌套的struct,无需解析两次。 but your json string need match the Go's struct structure. 但是您的json字符串需要匹配Go的struct结构。 like json 像json

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

will match go struct: 将匹配go struct:

type nest_struct struct{
    K21 string `k21`
}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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