4

I am watching a tutorial on how to create Go restful APIs that use MongoDB for persistence (this one to be more precise).

The instructor is using in his model (struct) both json and bson tags, something like

type NoteUpdate struct {
    ID        string `json:"id,omitempty" bson:"_id,omitempty"`
    Title     string `json:"title" bson:"title,omitempty"`
    Content   string `json:"content" bson:"content,omitempty"`
    ChangedAt int64  `json:"changed_at" bson:"changed_at"`
}

However the official go driver example does not do so.

As a matter of fact there, no struct tags are used at all.

What is the purpose / usefulness of using bson tags?

The one thing that comes to my mind is the case were one would want to create custom mongo _id fields in which case an explicit bson mapping with that struct's field should be declared.

Is there any other added value for the bson tags?

icza
  • 389,944
  • 63
  • 907
  • 827
pkaramol
  • 16,451
  • 43
  • 149
  • 324

2 Answers2

6

The MongoDB drivers use only the bson tags. json tags are solely for the encoding/json package (or other 3rd party packages dealing with JSON marshaling/unmarshaling).

You are not required to specify and use bson tags, in which case the drivers usually just use the lowercased field names when encoding struct values. bson tags are required however when you need a different name.

And it's also a good practice to specify bson tags even if you want to use the lowercased field names, because there might come a time when you need to rename struct fields, and that would cause troubles and inconsistencies. If you specify bson tags, it won't matter if you rename fields in the future, they will be still marshalled into the same properties, and unmarshaling them will continue to work.

icza
  • 389,944
  • 63
  • 907
  • 827
  • is it possible that using https://godoc.org/go.mongodb.org/mongo-driver/bson/bsoncodec can successfully take the place of bson tags if you needed to change a struct's field name? I'm asking because I'm thinking to use generated protobuf structs and don't want to ever need to mess with customizing the tags. I found https://godoc.org/go.mongodb.org/mongo-driver/bson/bsoncodec and it seems like it will allow all the problems to be solved. What's your opinion at a glance? – Yehuda Makarov Dec 02 '20 at 15:31
  • 1
    @YehudaMakarov Using custom codecs or implementing custom unmarshal logic, you can do whatever you want to. Using `bson` tags is just the default behavior of the default codec. – icza Dec 03 '20 at 12:59
3

bson tags can also contain flags to change the default marshaling behavior:

OmitEmpty  Only include the field if it's not set to the zero value for the type or to
           empty slices or maps.

MinSize    Marshal an integer of a type larger than 32 bits value as an int32, if that's
           feasible while preserving the numeric value.

Truncate   When unmarshaling a BSON double, it is permitted to lose precision to fit within
           a float32.

Inline     Inline the field, which must be a struct or a map, causing all of its fields
           or keys to be processed as if they were part of the outer struct. For maps,
           keys must not conflict with the bson keys of other struct fields.

Skip       This struct field should be skipped. This is usually denoted by parsing a "-"
           for the name.
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
reda la
  • 801
  • 1
  • 6
  • 10