使用 Go 将复杂的 http json 响应数组转换为简单的结构切片,而无需创建多个结构来匹配响应
Converting a complex http json response array to a simple struct slice without creating several structs to match the response using Go
如果 http 响应的格式不是直接的对象列表,我唯一能弄清楚如何将它们转换为结构的方法是创建两个结构来匹配响应的确切格式。无论如何,我可以只创建一个 Product 结构而不需要创建 ProductRes 包装器结构来做这个清洁器吗?
下面是我呼叫的 api 的响应示例:
{
"items": [
{
"name": "Product 1",
"price": 20.45
},
{
"name": "Product 2",
"price": 31.24
}
]
}
这是我创建的两个结构,用于将 api 响应转换为产品片段:
type Product struct {
Name string `json:"name"`
Price float64 `json:"price"`
}
type ProductRes struct {
Items []Product `json:"items"`
}
这是发出 api 请求并将响应转换为产品片段的部分代码:
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
log.Fatalln(err)
}
resp, err := c.client.Do(req)
if err != nil {
log.Fatalln(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
products := ProductRes{}
// This line makes me think I actually do need multiple structs, unless I can modify body somehow prior to sending it in here
json.Unmarshal(body, &products)
您可以使用匿名类型消除声明的类型ProductRes
:
var wrapper struct { Items []Product }
err := json.Unmarshal(body, &wrapper)
if err != nil {
// TODO: handle error
}
products := wrapper.Items
您还可以使用地图:
var m map[string][]Product
err := json.Unmarshal(body, &m)
if err != nil {
// TODO: handle error
}
products := m["items"]
如果 http 响应的格式不是直接的对象列表,我唯一能弄清楚如何将它们转换为结构的方法是创建两个结构来匹配响应的确切格式。无论如何,我可以只创建一个 Product 结构而不需要创建 ProductRes 包装器结构来做这个清洁器吗?
下面是我呼叫的 api 的响应示例:
{
"items": [
{
"name": "Product 1",
"price": 20.45
},
{
"name": "Product 2",
"price": 31.24
}
]
}
这是我创建的两个结构,用于将 api 响应转换为产品片段:
type Product struct {
Name string `json:"name"`
Price float64 `json:"price"`
}
type ProductRes struct {
Items []Product `json:"items"`
}
这是发出 api 请求并将响应转换为产品片段的部分代码:
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
log.Fatalln(err)
}
resp, err := c.client.Do(req)
if err != nil {
log.Fatalln(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
products := ProductRes{}
// This line makes me think I actually do need multiple structs, unless I can modify body somehow prior to sending it in here
json.Unmarshal(body, &products)
您可以使用匿名类型消除声明的类型ProductRes
:
var wrapper struct { Items []Product }
err := json.Unmarshal(body, &wrapper)
if err != nil {
// TODO: handle error
}
products := wrapper.Items
您还可以使用地图:
var m map[string][]Product
err := json.Unmarshal(body, &m)
if err != nil {
// TODO: handle error
}
products := m["items"]