I have a collection of documents that contain an array of a custom interface type that I have. Example below. What do I need to do to Unmarshal the bson from mongo so I can eventually return a JSON response?
type Document struct {
Props here....
NestedDocuments customInterface
}
What do I need to do to map the nested interfaces to the right structs?
I think it is evident that an interface cannot be instantiated, therefore the bson
runtime does not know which struct
has to be used to Unmarshal
that object. Additionally, your customInterface
type should be exported (i.e. with capital "C") otherwise it won't be accessible from the bson
runtime.
I suspect that using an interface implies that the NestedDocuments array may contain different types, all implementing customInterface
.
If that's the case, I am afraid that you will have to do some changes:
Firstly, NestedDocument
need to be a struct holding your document plus some information to help the decoder understand what's the underpinning type. Something like:
type Document struct {
Props here....
Nested []NestedDocument
}
type NestedDocument struct {
Kind string
Payload bson.Raw
}
// Document provides
func (d NestedDocument) Document() (CustomInterface, error) {
switch d.Kind {
case "TypeA":
// Here I am safely assuming that TypeA implements CustomInterface
result := &TypeA{}
err := d.Payload.Unmarshal(result)
if err != nil {
return nil, err
}
return result, nil
// ... other cases and default
}
}
In this way, the bson
runtime will decode the whole Document
but leave the payload as a []byte
.
Once you have decoded the main Document
, you can use the NestedDocument.Document()
function to get a concrete representation of your struct
.
One last thing; when you persist your Document
, make sure that Payload.Kind
is set to 3, which represents an embedded document. See the BSON specifications for more details on this.
Hope it is all clear and good luck with your project.