dictionary - Decode arbitrary JSON in Golang -
i have question decoding arbitrary json objects/messages in go.. lets example have 3 wildly different json objects (aka messages) can receive on http connection, lets call them sake of illustration:
{ home : { unique set of arrays, objects, fields, , arrays objects } }
and
{ bike : { unique set of arrays, objects, fields, , arrays objects } }
and
{ soda : { unique set of arrays, objects, fields, , arrays objects } }
what thinking decode these, http connection in map of interfaces such as:
func httpserverhandler(w http.responsewriter, r *http.request) { message := make(map[string]interface{}) decoder := json.newdecoder(r.body) _ = decoder.decode(&message)
then if, else if block valid json messages
if _, ok := message["home"]; ok { // decode interface{} appropriate struct } else if _, ok := message["bike"]; ok { // decode interface{} appropriate struct } else { // decode interface{} appropriate struct }
now in if block can make work if re-decode entire package, thinking kind of waste since have partially decoded , need decode value of map interface{}, can not seem work right.
redecoding entire thing works though, if following hometype example struct:
var homeobject hometype var bikeobject biketype var sodaobject sodatype
then in if block do:
if _, ok := message["home"]; ok { err = json.unmarshal(r.body, &homeobject) if err != nil { fmt.println("bad response, unable decode json message contents") os.exit(1) }
so without re-decoding / unmarshal-ing entire thing again, how work interface{} in map?
if have map[string]interface{} can access values using type assertions, e.g.
home, valid := msg["home"].(string) if !valid { return }
this works nicely simple values. more complicated nested structures might find easier deferred decoding json.rawmessage
or implement custom json.unmarshaler
. see this detailed discussion.
another idea might define custom message
type consisting of pointers home, bike, , soda structs. such as
type home struct { homestuff int morehomestuff string } type bike struct { bikestuff int } type message struct { bike *bike `json:"bike,omitempty"` home *home `json:"home,omitempty"` }
if set these omit if nil unmarshalling should populate relevant one. can play here.
Comments
Post a Comment