Golang: Json from map url
What is the best way to extract json from an ie Rest service from Go url? It also seems that most rest client libraries use json.marshall, which needs a framework to be used with it.
This does not work in the case of unstructured data, where you do not fully know what will happen. Is there a way for all of this to just appear as a map [string: string]?
source to share
Why not parse it into [string] as this code should do
var d map[string]interface{}
data, err := json.Unmarshal(apiResponse, &d)
You can also move data in this structure.
If you suspect the api's answer may be a non-singular object, but a collection of objects interface{}
works for arrays as well.
source to share
If you don't know what is coming in the message, you may have several situations.
The content of the message, which depends on the type
The type is usually indicated in a field of some type. In this case, you can use the "union" structure, which contains fields of all types:
type Foo struct {
A int
B string
}
type Bar struct {
C int
D string
}
type Message struct {
Type string
Foo
Bar
}
// or this, if you have common fields
type Message struct {
Type string
A int
B string
C int
D string
}
Detach the message in the merged structure, send by type and select the substructure.
var m Message
json.Unmarshal(data, &m)
switch m.Type {
case "foo":
...
case "bar":
...
}
Fully dynamic messages
In this case, you have a set of unrelated key values ββand handle them individually.
Understand map[string]interface{}
. The downside, of course, is that you have to use each value and check its type dynamically. Caveat: map[string]interface{}
converts all numbers to floats, even integers, so you added them to float64
.
You can also use map[string]json.RawMessage
, if you do not want to parse values, only keys ( json.RawMessage
are []byte
and are saved as with immediate).
Envelope message with dynamic payload
For example:
{
"type": "foo",
"payload": {
"key1": "value1"
}
}
{
"type": "bar",
"payload": {
"key2": "value2",
"key3": [1, 2]
}
}
Use a struct with json.RawMessage
.
type Message struct {
Type string
Payload json.RawMessage
}
type Foo struct {
Key1 string
}
type Bar struct {
Key2 string
Key3 []int
}
Parse the envelope (the payload will be saved), then send by type and process the payload into a substructure.
var m Message
_ = json.Unmarshal(data, &m)
switch m.Type {
case "foo":
var payload Foo
_ = json.Unmarshal(m.Payload, &payload)
// do stuff
case "bar":
var payload Bar
_ = json.Unmarshal(m.Payload, &payload)
// do stuff
}
source to share