英文:
Creating struct to read from API in Go
问题
我正在做一个项目,这是我第一次使用Go语言。
该项目查询了多个API,大部分情况下我都没有问题。
作为一个PHP背景的开发者,为我的JSON响应创建Go类型定义有点不同。
我在一个Magento API上遇到了问题,它返回的JSON响应如下所示:
{
"66937": {
"entity_id": "66937",
"website_id": "1",
"email": "email@email.com",
"group_id": "1",
"created_at": "2017-08-11 02:09:18",
"disable_auto_group_change": "0",
"firstname": "Joe",
"lastname": "Bloggs",
"created_in": "New Zealand Store View"
},
"66938": {
"entity_id": "66938",
"website_id": "1",
"email": "email1@email.comm",
"group_id": "1",
"created_at": "2017-08-11 02:16:41",
"disable_auto_group_change": "0",
"firstname": "Jane",
"lastname": "Doe",
"created_in": "New Zealand Store View"
}
}
我一直在使用一个名为JSON-to-Go的工具来帮助我创建struct
类型,但是对于这种响应风格,它看起来不太对:
type AutoGenerated struct {
Num0 struct {
EntityID string `json:"entity_id"`
WebsiteID string `json:"website_id"`
Email string `json:"email"`
GroupID string `json:"group_id"`
CreatedAt string `json:"created_at"`
DisableAutoGroupChange string `json:"disable_auto_group_change"`
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
CreatedIn string `json:"created_in"`
} `json:"0"`
Num1 struct {
EntityID string `json:"entity_id"`
WebsiteID string `json:"website_id"`
Email string `json:"email"`
GroupID string `json:"group_id"`
CreatedAt string `json:"created_at"`
DisableAutoGroupChange string `json:"disable_auto_group_change"`
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
CreatedIn string `json:"created_in"`
} `json:"1"`
}
我只对内部的JSON数据感兴趣 - 实际上与客户有关的内容。我正在循环遍历它以提取一些信息。
我该如何创建所需的struct
来读取这个JSON数据?
我查看了许多文档和文章,但它们往往使用更简单的JSON响应作为示例。
英文:
I'm working on a project and it is my first time using Go.
The project queries a number of APIs and for the most part I have had no trouble getting this working.
Coming from a PHP background, creating Go type definitions for my JSON responses is a little different.
I am stuck on one API, a Magento API, that returns a JSON response like so:
{
"66937": {
"entity_id": "66937",
"website_id": "1",
"email": "email@email.com",
"group_id": "1",
"created_at": "2017-08-11 02:09:18",
"disable_auto_group_change": "0",
"firstname": "Joe",
"lastname": "Bloggs",
"created_in": "New Zealand Store View"
},
"66938": {
"entity_id": "66938",
"website_id": "1",
"email": "email1@email.comm",
"group_id": "1",
"created_at": "2017-08-11 02:16:41",
"disable_auto_group_change": "0",
"firstname": "Jane",
"lastname": "Doe",
"created_in": "New Zealand Store View"
}
}
I have been using a tool, JSON-to-Go, to help me create the struct
types, however it doesn't look quite right for this style of response:
type AutoGenerated struct {
Num0 struct {
EntityID string `json:"entity_id"`
WebsiteID string `json:"website_id"`
Email string `json:"email"`
GroupID string `json:"group_id"`
CreatedAt string `json:"created_at"`
DisableAutoGroupChange string `json:"disable_auto_group_change"`
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
CreatedIn string `json:"created_in"`
} `json:"0"`
Num1 struct {
EntityID string `json:"entity_id"`
WebsiteID string `json:"website_id"`
Email string `json:"email"`
GroupID string `json:"group_id"`
CreatedAt string `json:"created_at"`
DisableAutoGroupChange string `json:"disable_auto_group_change"`
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
CreatedIn string `json:"created_in"`
} `json:"1"`
}
All I am interested in is the inner JSON - the stuff to actually do with the customer. I am looping over this to extract some information.
How do I create the required struct
to read from this?
I have looked at any number of documents or articles but they tend to use more simple JSON responses as examples.
答案1
得分: 1
对于你的JSON结构,以下可能适合。
播放链接:https://play.golang.org/p/ygXsdYALCb
创建一个名为Info
的struct
,或者你喜欢的其他名称,并根据需要自定义字段名称。
type Info struct {
EntityID string `json:"entity_id"`
WebsiteID string `json:"website_id"`
Email string `json:"email"`
GroupID string `json:"group_id"`
CreatedAt string `json:"created_at"`
DisableAutoGroupChange string `json:"disable_auto_group_change"`
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
CreatedIn string `json:"created_in"`
}
然后创建Info
结构的map
并进行解组。
var result map[string]Info
if err := json.Unmarshal(jsonBytes, &result); err != nil {
fmt.Println(err)
}
fmt.Printf("%+v", result)
编辑:
根据评论的要求,添加一个示例的for
循环:
fmt.Println("访问解组后的值:")
for key, info := range result {
fmt.Println("Key:", key)
fmt.Printf("Complete Object: %+v\n", info)
fmt.Println("Individual value, typical object field access:")
fmt.Println("EntityID:", info.EntityID)
fmt.Println("Email:", info.Email)
}
英文:
For your JSON structure following might suit well.
Play Link: https://play.golang.org/p/ygXsdYALCb
Create a struct
called Info
or name you prefer also customize your field names as you like.
type Info struct {
EntityID string `json:"entity_id"`
WebsiteID string `json:"website_id"`
Email string `json:"email"`
GroupID string `json:"group_id"`
CreatedAt string `json:"created_at"`
DisableAutoGroupChange string `json:"disable_auto_group_change"`
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
CreatedIn string `json:"created_in"`
}
And create map
of Info
struct and the unmarshal it.
var result map[string]Info
if err := json.Unmarshal(jsonBytes, &result); err != nil {
fmt.Println(err)
}
fmt.Printf("%+v", result)
EDIT:
As asked in the comment, adding for
example:
fmt.Println("Accessing unmarshal values:")
for key, info := range result {
fmt.Println("Key:", key)
fmt.Printf("Complete Object: %+v\n", info)
fmt.Println("Individual value, typical object field access:")
fmt.Println("EntityID:", info.EntityID)
fmt.Println("Email:", info.Email)
}
答案2
得分: 1
好的,以下是翻译好的内容:
首先,我不喜欢那里自动生成的结构定义。我会将其更改为以下形式:
type Customer struct {
EntityID string `json:"entity_id"`
WebsiteID string `json:"website_id"`
Email string `json:"email"`
GroupID string `json:"group_id"`
CreatedAt string `json:"created_at"`
DisableAutoGroupChange string `json:"disable_auto_group_change"`
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
CreatedIn string `json:"created_in"`
}
你可能想要创建一个包装类型:
type Customers map[string]Customer
这应该可以与你提供的 JSON 数据一起使用。将它们组合起来的代码如下:
customers := Customers{}
err := json.Unmarshal(jsonBytes, &customers)
英文:
Well, first, I don't like the auto-generated struct definitions there. I would change that to look like this
type Customer struct {
EntityID string `json:"entity_id"`
WebsiteID string `json:"website_id"`
Email string `json:"email"`
GroupID string `json:"group_id"`
CreatedAt string `json:"created_at"`
DisableAutoGroupChange string `json:"disable_auto_group_change"`
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
CreatedIn string `json:"created_in"`
}
You may want to create a wrapper type
type Customers map[string]Customer
This should work with your json that you've provided. To put this together
customers := Customers{}
err := json.Unmarshal(jsonBytes, &customers)
答案3
得分: 0
@Xibz和@jeevatkm都提供了很好的解决方案。然而,在某些情况下,并不是所有的JSON结构都可以解组成Go结构。你可能需要定义自己的解码函数。
如果你需要为特定的数据类型或结构定义自己的解码函数,你也可以尝试使用gorilla的schema包。
https://github.com/gorilla/schema
英文:
Both @Xibz and @jeevatkm provided great solutions. However, in some cases, not all JSON structures can be unmarshalled into Go structures. You may have to define your own decoding functions.
You can also try gorilla's schema package if you have to define your own decoding function for particular data type or structures.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论