英文:
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 响应转换为 Product 切片:
type Product struct {
Name string `json:"name"`
Price float64 `json:"price"`
}
type ProductRes struct {
Items []Product `json:"items"`
}
这是部分代码,用于发起 API 请求并将响应转换为 Product 切片:
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{}
// 这一行让我觉得我实际上确实需要多个结构体,除非我可以在发送之前修改 body
json.Unmarshal(body, &products)
希望这能帮到你!如果你有任何其他问题,请随时问我。
英文:
If an http response comes in a format that is not directly a list of objects the only way I could figure out how to convert them to structs is by creating two structs to match the exact format of the response. Is there anyway to do this cleaner where I can just create a Product struct and don't need to create the ProductRes wrapper struct?
Below is an example of what the response from the api I am calling looks like:
{
"items": [
{
"name": "Product 1",
"price": 20.45
},
{
"name": "Product 2",
"price": 31.24
}
]
}
Here are the two structs I create to convert the api response to a slice of Product:
type Product struct {
Name string `json:"name"`
Price float64 `json:"price"`
}
type ProductRes struct {
Items []Product `json:"items"`
}
Here is part of the code to make the api request and convert the response to a slice of Product:
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)
答案1
得分: 3
你可以通过使用匿名类型来消除声明的类型ProductRes
:
var wrapper struct { Items []Product }
err := json.Unmarshal(body, &wrapper)
if err != nil {
// TODO: 处理错误
}
products := wrapper.Items
你也可以使用map:
var m map[string][]Product
err := json.Unmarshal(body, &m)
if err != nil {
// TODO: 处理错误
}
products := m["items"]
英文:
You can eliminate the declared type ProductRes
by using an anonymous type:
var wrapper struct { Items []Product }
err := json.Unmarshal(body, &wrapper)
if err != nil {
// TODO: handle error
}
products := wrapper.Items
You can also use a map:
var m map[string][]Product
err := json.Unmarshal(body, &m)
if err != nil {
// TODO: handle error
}
products := m["items"]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论