I have this struct
type SyncInfo struct { Target string }
Now I query some json
data from ElasticSearch. Source
is of type json.RawMessage
. All I want is to map source
to my SyncInfo
which I created the variable mySyncInfo
for.
I even figured out how to do that...but it seems weird. I first call MarshalJSON()
to get a []byte
and then feed that to json.Unmarshal()
which takes an []byte
and a pointer to my struct.
This works fine but it feels as if I'm doing an extra hop. Am I missing something or is that the intended way to get from a json.RawMessage
to a struct
?
var mySyncInfo SyncInfo jsonStr, _ := out.Hits.Hits[0].Source.MarshalJSON() json.Unmarshal(jsonStr, &mySyncInfo) fmt.Print(mySyncInfo.Target)
RawMessage is a raw encoded JSON value. It implements Marshaler and Unmarshaler and can be used to delay JSON decoding or precompute a JSON encoding. Example (Marshal) This example uses RawMessage to use a precomputed JSON during marshal.
Unmarshal() function takes some encoded JSON data and a pointer to a value where the encoded JSON should be written, and returns an error if something goes wrong.
To parse JSON, we use the Unmarshal() function in package encoding/json to unpack or decode the data from JSON to a struct. Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. Note: If v is nil or not a pointer, Unmarshal returns an InvalidUnmarshalError.
As said, the underlying type of json.RawMessage
is []byte
, so you can use a json.RawMessage
as the data parameter to json.Unmarshal
.
However, your problem is that you have a pointer (*json.RawMessage
) and not a value. All you have to do is to dereference it:
err := json.Unmarshal(*out.Hits.Hits[0].Source, &mySyncInfo)
Working example:
package main import ( "encoding/json" "fmt" ) type SyncInfo struct { Target string } func main() { data := []byte(`{"target": "localhost"}`) Source := (*json.RawMessage)(&data) var mySyncInfo SyncInfo // Notice the dereferencing asterisk * err := json.Unmarshal(*Source, &mySyncInfo) if err != nil { panic(err) } fmt.Printf("%+v\n", mySyncInfo) }
Output:
{Target:localhost}
Playground: http://play.golang.org/p/J8R3Qrjrzx
json.RawMessage
is really just a slice of bytes. You should be able to feed it directly into json.Unmarshal
directly, like so:
json.Unmarshal(out.Hits.Hits[0].Source, &mySyncInfo)
Also, somewhat unrelated, but json.Unmarshal
can return an error and you want to handle that.
err := json.Unmarshal(*out.Hits.Hits[0].Source, &mySyncInfo) if err != nil { // Handle }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With