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]?

+3


source to share


2 answers


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.

+1


source


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
}

      

0


source







All Articles