Embedded Types and JSON Marshaling in Go with MongoDB
In MongoDB, embedded types are a common way to represent hierarchical data structures. However, when using Go's JSON encoder with embedded types, it's important to consider how omitted fields are handled.
Suppose you have a User struct with a Secret field annotated with json:"-" to exclude it from regular JSON responses. To return the secret field for admin users, you might be tempted to create a separate adminUser struct with a duplicate Secret field. However, this approach duplicates code and can lead to maintenance issues.
Instead, consider using the bson:",inline" tag for the User field in adminUser. This instructs the JSON encoder to inline the fields of the embedded struct, effectively combining them into a single JSON object.
type adminUser struct { User `bson:",inline"` Secret string `json:"secret,omitempty" bson:"secret,omitempty"` }
However, this approach can introduce duplicate key errors when reading from MongoDB, as both adminUser and User contain the Secret field. To resolve this, remove the Secret field from User and only have it in adminUser.
type User struct { Id bson.ObjectId `json:"id,omitempty" bson:"_id,omitempty"` Name string `json:"name,omitempty" bson:"name,omitempty"` } type adminUser struct { User `bson:",inline"` Secret string `json:"secret,omitempty" bson:"secret,omitempty"` }
Now, when retrieving a user with an admin user, the secret field will be included in the JSON response.
func getUser(w http.ResponseWriter, r *http.Request) { ....omitted code... var user adminUser err := common.GetDB(r).C("users").Find( bson.M{"_id": userId}, ).One(&user) if err != nil { return } common.ServeJSON(w, &user) }
This approach preserves the single source of truth for the User struct and allows you to dynamically include or exclude the secret field based on user permissions.
The above is the detailed content of How to Handle Embedded Types and JSON Marshaling with MongoDB in Go?. For more information, please follow other related articles on the PHP Chinese website!