Golang嵌套结构体未被省略。

huangapple go评论70阅读模式
英文:

Golang nested structs not getting omitted

问题

我想要在一个JSON请求中省略某些嵌套的结构体。我在Golang上创建了一个REST API,它从HTTP请求中读取消息体,将其解码为代码中定义的结构体,并将其插入Mongo DB。

我的结构体如下所示。请注意,对于嵌套结构体C,我使用指针以便能够省略它。

type A struct {
	Title        string        `json:"title"`
	Text         string        `json:"text"`
	Data         B             `json:"data"`
}

type B struct {
	Product      *C            `json:"product,omitempty"`
	ExternalLink string        `json:"external_link,omitempty"`
}

type C struct {
	Name          string       `json:"name"` 
	Id            int          `json:"id"`   
}

以下是我如何解码它的方式(我没有使用Json.Unmarshall,因为我读到对于HTTP请求体,应该使用解码而不是反序列化)。

func NewMessage(req *http.Request) *A {
      var newMessage *A
      json.NewDecoder(req.Body).Decode(&newMessage)
      messageInData := newMessage
      return newMessage
}

返回的"newMessage"直接插入Mongo。然而,即使请求的负载不包含结构体C,比如下面的例子:

{
    "title": "First message from GoLang",
    "text": "Hello Dastgyr",
    "data": {
             "external_link": "some link here"
             //这里没有product对象(C结构体)
             }
}

插入Mongo的对象仍然包含结构体C,但其值为null,如下所示:

{
    "title": "First message from GoLang",
    "text": "Hello Dastgyr",
    "data": {
             "product": null,
             "external_link": "some link here"
             }
}

我还尝试将B作为A结构体的指针,但没有成功:

type A struct {
	Title        string        `json:"title"`
	Text         string        `json:"text"`
	Data         *B            `json:"data,omitempty"`
}

我想要能够省略某些嵌套的结构体。尽管使用了指针,但我仍然无法省略我想要的结构体。我在定义结构体时犯了什么错误?由于我对Golang还不熟悉,希望能得到正确的指导。

英文:

I want to omit certain structs nested in a JSON request. I've created a rest API on golang which reads a message body from an http request, decodes it into the struct defined in the code and inserts it into Mongo DB

>My structs are as follows. Note that for the nested structure C, I use a pointer in order to be able to omit it.

type A struct {
	Title        string        `json:"title"`
	Text         string        `json:"text"`
	Data         B             `json:"data"`
}

type B struct {
	Product      *C            `json:"product,omitempty"`
	ExternalLink string        `json:"external_link,omitempty"`
}

type C struct {
	Name          string       `json:"name"` 
	Id            int          `json:"id"`   
}

<br />

>Here is how I decode it (Didn't go for Json.Unmarshall as I read that for http bodies, decoding should be used over unmarshall)

func NewMessage(req *http.Request) *A {
      var newMessage *A
      json.NewDecoder(req.Body).Decode(&amp;newMessage)
      messageInData := newMessage
      return newMessage
}

<br />

>The "newMessage" upon return is inserted into Mongo directly. However, Even if the request payload contains no such object as the struct C for instance like below

{
    &quot;title&quot;: &quot;First message from GoLang&quot;,
    &quot;text&quot;: &quot;Hello Dastgyr&quot;,
    &quot;data&quot;: {
             &quot;external_link&quot;: &quot;some link here&quot;
             //no product object (C struct) here
             }
}

<br />

>The object inserted into Mongo still contains the struct C as having a null value as shown below

{
    &quot;title&quot;: &quot;First message from GoLang&quot;,
    &quot;text&quot;: &quot;Hello Dastgyr&quot;,
    &quot;data&quot;: {
             &quot;product&quot;: null,
             &quot;external_link&quot;: &quot;some link here&quot;
             }
}

<br />

>I've also tried using B as a pointer in Struct A but to no avail

type A struct {
	Title        string        `json:&quot;title&quot;`
	Text         string        `json:&quot;text&quot;`
	Data         *B            `json:&quot;data,omitempty&quot;`
}

I want to be able to omit certain nested structs. Despite using pointers, the struct I want is still not omitting. What mistake am I making in defining structs?
Still new to golang so a nudge in the right direction would help

答案1

得分: 2

你正在使用json标签进行json解组,看起来解组正确(因为你没有提到任何错误,并且继续使用MongoDB)。

如何将数据添加到MongoDB是完全不同的问题,与你的JSON标签无关。它使用bson标签,如果你希望将相同的结构用作MongoDB模型表示,你需要添加它们。类似于这样:

type A struct {
    Title        string        `json:"title" bson:"title"`
    Text         string        `json:"text" bson:"text"`
    Data         *B            `json:"data,omitempty" bson:"data,omitempty"`
}

请记住,golang中的标签只是与结构一起添加的一些元数据,某些代码实际上会读取并处理它们。json库识别并处理json:""标签,而你可能正在使用的官方go mongodb库将处理bson:""标签。

英文:

You are using json tags for json un-marshaling, it seems to be un-marshaling correctly (concluding this as you didn't mention any errors, and moved on to MongoDB)

How you add data to MongoDB is a totally different matter, and has nothing to do with your JSON tags. It uses bson tags, and you will need to add them, if you wish to use this same struct as a mongo DB model representation. Something like this:

type A struct {
    Title        string        `json:&quot;title&quot; bson:&quot;title&quot;`
    Text         string        `json:&quot;text&quot; bson:&quot;text&quot;`
    Data         *B            `json:&quot;data,omitempty&quot; bson:&quot;data,omitempty&quot;`
}

Remember that tags in golang, are just some metadata being added with a structure, which some code actually reads and acts on. json library identifies & processes json:&quot;&quot; tag, while official go mongodb library that you might be using, will process the bson:&quot;&quot; tags.

huangapple
  • 本文由 发表于 2022年7月18日 19:26:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/73021581.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定