How to Marshal/Unmarshal a common JSON & BSON key/field that can have two different formats in Go?

Viewed 100

I currently have mongo data stored in two forms (specifically for content key) in a collection. Partial sample data shown below:

Format 1.

{
    "type": "text",
    "content": "foobar",
    "extraTextData": "hello text"
}

Format 2

{
    "type": "group",
    "content": [
        {
            "type": "text",
            "content": "grouped-foobar"
        },
        {
            "type": "image",
            "url": "https://abc.jpg"
        },
    ],
    "extraGroupData": "hello group"
}

My attempt to structure this in golang is below.

type C struct {
    Type string `json:"type" bson:"type"`
    Content ???
    *TextC 
    *GroupC
}
type TextC struct {
    ExtraTextData `json:"extraTextData" bson:"extraTextData"`
}
type GroupC struct {
    ExtraGroupData `json:"extraGroupData" bson:"extraGroupData"`
}

I am having issues on how to setup the structure for "content" field that works for both the formats, TextC and GroupC.

Content for GroupC can be array of C like - Content []C Content for TextC can also be string type.

Can someone please help & give an example on how to tackle this situation?

1 Answers

Format2 json is Invalid. You can check it here : https://jsonlint.com/

I have created a sample scenario for your case.

You can try it here: https://go.dev/play/p/jaUE3rjI-Ik

Use interface{} like this:

type AutoGenerated struct {
        Type           string      `json:"type"`
        Content        interface{} `json:"content"`
        ExtraTextData  string      `json:"extraTextData,omitempty"`
        ExtraGroupData string      `json:"extraGroupData,omitempty"`
    }

And you should also remove comma from Format2:

{
    "type": "group",
    "content": [
        {
            "type": "text",
            "content": "grouped-foobar"
        },
        {
            "type": "image",
            "url": "https://abc.jpg"
        }
    ],
    "extraGroupData": "hello group"
}

If you don't remove comma then it will through an error like this:

invalid character ']' looking for beginning of value
Related