I'm storing attachment in mongodb as Attachment object:
type Attachment struct {
ID string `bson:"_id" json:"id"`
Name string `bson:"name" json:"name"`
URL string `bson:"url" json:"url"`
}
The URL stored is the presigned URL for PUT request, retrieved using AWS session. In Ruby on Rails, I can use virtual attribute to change the URL to presigned URL for GET request:
// models/attachment.rb
def url
if super.present?
// get the presigned URL for get request using the URL from super
else
super
end
end
How can I accomplish this in Go? I have my configs in config.yaml and need to convert yaml to struct. Meanwhile, marshal and unmarshal of BSON only receive data []byte as parameter. I'm not sure how to initiate the AWS session in the marshal and unmarshal of BSON.
I prefer to modify the URL after I query from mongodb, but I want to do it in 1 place
The mongo-go
and mgo
drivers check for and call certain implemented interfaces when converting Go values to / from BSON values. Implement bson.Marshaler
and bson.Unmarshaler
on your type and you can do anything before saving it / after loading it.
Call the default bson.Marhsal()
and bson.Unmarshal()
functions to do the regular marshaling / unmarshaling process, and if that succeeds, then do what you want before returning.
For example:
// Called when an Attachment is saved.
func (a *Attachment) MarshalBSON() (data []byte, err error) {
data, err = bson.Marshal(a)
if err != nil {
return
}
// Do your additional thing here
return
}
// Called when an Attachment is loaded.
func (a *Attachment) UnmarshalBSON(data []byte) error {
if err := bson.Unmarshal(data, &a); err != nil {
return err
}
// Do your additional thing here
return nil
}
Also see related: How to ignore nulls while unmarshalling a MongoDB document?