0

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"`   
}

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(&newMessage)
      messageInData := newMessage
      return newMessage
}

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

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

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

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

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

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

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

3
  • 3
    Since you're using mongo, try bson:",omitempty" (note that bson is not a typo). Commented Jul 18, 2022 at 11:35
  • Thanks @mkopriva this worked! So omitempty can work on unmarshall/decode as well then? Commented Jul 18, 2022 at 11:42
  • No, omitempty is purely a marshal/encode thing. The bson:",omitempty" tag has an effect on how the struct is marshaled/encoded into BSON, i.e. it has an effect on how the struct is store into the mongo database. It has no effect whatsoever on JSON unmarshaling, e.g. json.NewDecoder(req.Body).Decode(&newMessage) Commented Jul 18, 2022 at 11:49

1 Answer 1

1

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:"title" bson:"title"`
    Text         string        `json:"text" bson:"text"`
    Data         *B            `json:"data,omitempty" bson:"data,omitempty"`
}

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:"" tag, while official go mongodb library that you might be using, will process the bson:"" tags.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.