英文:
Golang: Json from URL as map
问题
从URL提取JSON的最佳方法是什么,例如来自Go的REST服务?
此外,似乎大多数Go中的REST客户端库都强制使用json.marshall,它需要与结构体一起使用。
这在不完全了解即将到来的非结构化数据的情况下是行不通的。有没有一种方法可以将所有数据简单地作为map[string:string]传入?
英文:
What is the best way to extract json from a url i.e. Rest service from Go?
Also it seems most rest client libraries in go force a use of the json.marshall which needs a struct to be used with it.
This doesn't work in the case of unstructured data where you don't fully know what will be coming in. Is there a way to have it all simply come in as a map[string:string]?
答案1
得分: 0
为什么不将其解析为map[string]string,因为这段代码需要这样做:
var d map[string]interface{}
data, err := json.Unmarshal(apiResponse, &d)
你也可以在这个结构体中遍历数据。
如果你怀疑API响应可能不是单个对象,而是对象的集合,interface{}
也适用于数组。
英文:
Why not to parse it into map[string]string as this code have to do
var d map[string]interface{}
data, err := json.Unmarshal(apiResponse, &d)
You can traverse data in this struct too.
If you suspect, that api response can be not singular object, but the collection of objects, the interface{}
also works for arrays.
答案2
得分: 0
如果你不知道消息中会有什么内容,可能会遇到几种情况。
根据类型确定消息内容
通常可以通过某个类型字段来指示类型。在这种情况下,你可以使用一个包含所有类型字段的“联合”结构体:
type Foo struct {
A int
B string
}
type Bar struct {
C int
D string
}
type Message struct {
Type string
Foo
Bar
}
// 或者,如果有共同的字段
type Message struct {
Type string
A int
B string
C int
D string
}
将消息解组为联合结构体,根据类型进行分发,并选择子结构体。
var m Message
json.Unmarshal(data, &m)
switch m.Type {
case "foo":
...
case "bar":
...
}
完全动态的消息
在这种情况下,你有一组不相关的键值对,并且需要逐个处理它们。
解析为map[string]interface{}
。当然,缺点是你必须动态地将每个值转换并检查其类型。注意:map[string]interface{}
会将所有数字转换为浮点数,即使是整数,所以你需要将它们转换为float64
。
如果你只想解析键(json.RawMessage
是[]byte
,在解组时保持不变),你也可以使用map[string]json.RawMessage
。
具有动态载荷的“信封”消息
例如:
{
"type": "foo",
"payload": {
"key1": "value1"
}
}
{
"type": "bar",
"payload": {
"key2": "value2",
"key3": [1, 2]
}
}
使用带有json.RawMessage
的结构体。
type Message struct {
Type string
Payload json.RawMessage
}
type Foo struct {
Key1 string
}
type Bar struct {
Key2 string
Key3 []int
}
解析信封(载荷将被保留),然后根据类型进行分发,并将载荷解析为子结构体。
var m Message
_ = json.Unmarshal(data, &m)
switch m.Type {
case "foo":
var payload Foo
_ = json.Unmarshal(m.Payload, &payload)
// 处理操作
case "bar":
var payload Bar
_ = json.Unmarshal(m.Payload, &payload)
// 处理操作
}
英文:
If you don't know what's coming in a message, you can have several situations.
#Message contents that depend on type
Type is usually indicated by some type field. In this case you can use a "union" struct that contains fields from 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
}
Unmarshal the message into the union struct, dispatch on type, and select the sub-struct.
var m Message
json.Unmarshal(data, &m)
switch m.Type {
case "foo":
...
case "bar":
...
}
#Completely dynamic messages
In this case you have a collection of unrelated key-values and process them individually.
Parse into a map[string]interface{}
. The downside, of course, is that you have to cast each value and check its type dynamically. Caveat: map[string]interface{}
will convert all numbers to floats, even integers, so you have cast them to float64
.
You can also use map[string]json.RawMessage
, if you do not want to parse values, only keys (json.RawMessage
is a []byte
, and is preserved as is when unmarshaled).
#"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 (payload will be preserved), then dispatch on type, and parse payload into a sub-struct.
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论