Reputation: 524
I would like to get ObjectID as a string because I have other storage types, so I want to avoid to use primitive.ObjectID in my struct to keep the layers independent. I'm new to Golang, thanks.
package listing
type Card struct {
ID string
Hanzi string
Pinyin string
Traducao string
}
My storage file: package storage
func (m *Mongodb)GetCards() []*listing.Card {
var list []*listing.Card
collection := m.Client.Database("flashcards").Collection("cards")
cur, err := collection.Find(context.TODO(), bson.M{})
if err != nil {
log.Fatal("Erro buscando cards:", err)
}
for cur.Next(context.TODO()) {
var card listing.Card
err = cur.Decode(&card)
if err != nil {
log.Fatal("Erro decodificando documento", err)
}
list = append(list, &card)
}
return list
}
Upvotes: 6
Views: 7682
Reputation: 1867
Like you, I was looking for a solution to keep modules as independent as possible and keep coupling levels low. I scratched my head A LOT but in the end, I found this. I hope it's a valid and clear, solution.
You can use a custom type that implements the ValueMarshaler interface: so you have to implement MarshalValue func!
type Card struct {
ID MyObjectID `bson:"_id"`
CardSuit string `bson:"cardSuit"`
}
type MyObjectID string
func (id MyObjectID) MarshalBSONValue() (bsontype.Type, []byte, error) {
p, err := primitive.ObjectIDFromHex(string(id))
if err != nil {
return bsontype.Null, nil, err
}
return bson.MarshalValue(p)
}
ID is practically a string
, but with the custom marshaller, it will be saved as an ObjectID in Mongo, and parsed correctly during unmarshalling.
Here is a working example, obviously, you need mongo to make it run.
Related question that helped me.
Upvotes: 6
Reputation: 19
For me it works out of the box when having the bson annotation (version 5.0.6):
type User struct {
Id string `bson:"_id,omitempty" json:"id,omitempty"`
Name string `bson:"name" json:"name"`
}
Upvotes: 0
Reputation: 18430
Use bson:"-"
for ignore ObjectID
in response and json:"-"
for ignoring in database.
And you don't need to decode two times.
type Card struct {
ObjectID primitive.ObjectID `json:"-" bson:"_id"`
ID string `bson:"-"`
Hanzi string
Pinyin string
Traducao string
}
err = cur.Decode(&card)
card.ID = card.ObjectID.Hex()
Upvotes: -2
Reputation: 524
Ok, I figured out. I created another struct just to hold the ObjectId
type HexId struct {
ID primitive.ObjectID `bson:"_id"`
}
then I used Hex() to pass the value to Card.ID
err = cur.Decode(&card)
err = cur.Decode(&hexId)
card.ID = hexId.ID.Hex()
Now I can use it to make links.
Upvotes: 1