英文:
Mapping JSON returned by REST API containing dynamic keys to a struct in Golang
问题
我正在从我的Go程序中调用一个REST API,该API在请求中接收n个酒店ID,并将它们的数据作为JSON返回。当我在请求中传递2个ID(1018089108070373346和2017089208070373346)时,响应如下所示:
{
"data": {
"1018089108070373346": {
"name": "A Nice Hotel",
"success": true
},
"2017089208070373346": {
"name": "Another Nice Hotel",
"success": true
}
}
}
由于我对Golang还不熟悉,我使用了一个可在http://mholt.github.io/json-to-go/上找到的JSON转Go结构体的工具来获取上述响应的结构体表示。我得到的结果是:
type Autogenerated struct {
Data struct {
Num1017089108070373346 struct {
Name string json:"name"
Success bool json:"success"
} json:"1017089108070373346"
Num2017089208070373346 struct {
Name string json:"name"
Success bool json:"success"
} json:"2017089208070373346"
} json:"data"
}
我不能使用上述结构体,因为实际的ID值和我传递的ID数量每次可能都不同,返回的JSON将具有不同的键。如何将这种情况映射到一个结构体中呢?
谢谢。
英文:
I'm calling a REST API from my Go program which takes n number of hotel ids in the request and returns their data as a JSON. The response is like the following when say I pass 2 ids in the request, 1018089108070373346 and 2017089208070373346 :
{
"data": {
"1018089108070373346": {
"name": "A Nice Hotel",
"success": true
},
"2017089208070373346": {
"name": "Another Nice Hotel",
"success": true
}
}
}
Since I'm new to Golang I using a JSON Go tool available at http://mholt.github.io/json-to-go/ to get the struct representation for the above response. What I get is:
type Autogenerated struct {
Data struct {
Num1017089108070373346 struct {
Name string `json:"name"`
Success bool `json:"success"`
} `json:"1017089108070373346"`
Num2017089208070373346 struct {
Name string `json:"name"`
Success bool `json:"success"`
} `json:"2017089208070373346"`
} `json:"data"`
}
I cannot use the above struct because the actual id values and the number of ids I pass can be different each time, the JSON returned will have different keys. How can this situation be mapped to a struct ?
Thanks
答案1
得分: 3
使用地图:
type Item struct {
Name string `json:"name"`
Success bool `json:"success"`
}
type Response struct {
Data map[string]Item `json:"data"`
}
英文:
Use a map:
type Item struct {
Name string `json:"name"`
Success bool `json:"success"`
}
type Response struct {
Data map[string]Item `json:"data"`
}
<kbd>Run it on the playground</kbd>
答案2
得分: 0
以下是使用Mellow Marmots答案的示例代码,并展示了如何迭代响应中的项目。
test.json
{
"data": {
"1018089108070373346": {
"name": "一个不错的酒店",
"success": true
},
"2017089208070373346": {
"name": "另一个不错的酒店",
"success": true
}
}
}
test.go
package main
import (
"encoding/json"
"fmt"
"os"
)
// Item 结构体
type Item struct {
Name string `json:"name"`
Success bool `json:"success"`
}
// Response 结构体
type Response struct {
Data map[string]Item `json:"data"`
}
func main() {
jsonFile, err := os.Open("test.json")
if err != nil {
fmt.Println("打开测试文件时出错\n", err.Error())
return
}
jsonParser := json.NewDecoder(jsonFile)
var filedata Response
if err = jsonParser.Decode(&filedata); err != nil {
fmt.Println("读取测试文件时出错\n", err.Error())
return
}
for key, value := range filedata.Data {
fmt.Println(key, value.Name, value.Success)
}
}
输出结果为:
1018089108070373346 一个不错的酒店 true
2017089208070373346 另一个不错的酒店 true
英文:
Here is some sample code that utilizes Mellow Marmots answer and shows how to iterate over the items in the response.
test.json
{
"data": {
"1018089108070373346": {
"name": "A Nice Hotel",
"success": true
},
"2017089208070373346": {
"name": "Another Nice Hotel",
"success": true
}
}
}
test.go
package main
import (
"encoding/json"
"fmt"
"os"
)
// Item struct
type Item struct {
Name string `json:"name"`
Success bool `json:"success"`
}
// Response struct
type Response struct {
Data map[string]Item `json:"data"`
}
func main() {
jsonFile, err := os.Open("test.json")
if err != nil {
fmt.Println("Error opening test file\n", err.Error())
return
}
jsonParser := json.NewDecoder(jsonFile)
var filedata Response
if err = jsonParser.Decode(&filedata); err != nil {
fmt.Println("Error while reading test file.\n", err.Error())
return
}
for key, value := range filedata.Data {
fmt.Println(key, value.Name, value.Success)
}
}
Which outputs:
1018089108070373346 A Nice Hotel true
2017089208070373346 Another Nice Hotel true
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论