tl;dr: Use ,omitempty
, and if you need to worry about the difference between a zero value and null/not specified, do what the GitHub API does and use a pointer.
Both json
and bson
support the ,omitempty
tag. For json, "empty values are false, 0, any nil pointer or interface value, and any array, slice, map, or string of length zero" (json docs). For bson, ,omitempty
means "Only include the field if it's not set to the zero value for the type or to empty slices or maps", and zero values include empty strings and nil pointers (bson docs).
So if you really need a Group struct, you can put a *Group
in instead, and it won't be stored when the pointer is nil. If Investment
only needs to hold the group's name, it's even simpler: ""
as group name keeps a group key from being stored.
bson
defaults to using the lowercased field name already so you can omit that from the struct tag when they match. json
will default to the Capitalized name, so specify the lowercase name in a tag if you need lowercase.
So, best case, maybe you can just use:
type Investment struct {
Base
Symbol string `json:"symbol" binding:"required"`
Group string `json:"group,omitempty" bson:",omitempty"`
Fields bson.M `json:"fields"`
}
If you ever run into fields where the zero value for the type ("", 0, false, etc.) is distinct from "not specified", you can do what the GitHub API does and put pointers in your structures--essentially an extension of the *Group
trick.
json.Marshaler
golang.org/pkg/encoding/json/#Marshaler it lets you define custom Marshaling behavior for json, which should (with some effort) allow you to not write a given field based on some logic. – Birthrightjson: "omitempty"
should do the trick, from memory. – Mauriciomaurie