Hypothetical, I run an API and when a user makes a GET request on the user resource, I will return relevant fields as a JSON
type User struct {
Id bson.ObjectId `json:"id,omitempty" bson:"_id,omitempty"`
Name string `json:"name,omitempty" bson:"name,omitempty"`
Secret string `json:"-,omitempty" bson:"secret,omitempty"`
}
As you can see, the Secret field in User has json:"-"
. This implies that in most operation that I would not like to return. In this case, a response would be
{
"id":1,
"Name": "John"
}
The field secret will not be returned as json:"-"
omits the field.
Now, I am openning an admin only route where I would like to return the secret field. However, that would mean duplicating the User struct.
My current solution looks like this:
type adminUser struct {
Id bson.ObjectId `json:"id,omitempty" bson:"_id,omitempty"`
Name string `json:"name,omitempty" bson:"name,omitempty"`
Secret string `json:"secret,omitempty" bson:"secret,omitempty"`
}
Is there a way to embed User into adminUser? Kind of like inheritance:
type adminUser struct {
User
Secret string `json:"secret,omitempty" bson:"secret,omitempty"`
}
The above currently does not work, as only the field secret will be returned in this case.
Note: In the actual code base, there are few dozens fields. As such, the cost of duplicating code is high.
The actual mongo query is below:
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)
}
You should take a look at the bson package's inline flag (that is documented under bson.Marshal). It should allow you to do something like this:
type adminUser struct {
User `bson:",inline"`
Secret string `json:"secret,omitempty" bson:"secret,omitempty"`
}
However, now you'll notice that you get duplicate key errors
when you try to read from the database with this structure,
since both adminUser
and User
contain the key secret
.
In your case I would remove the Secret
field from User
and only have the one in adminUser
.
Then whenever you need to write to the secret
field,
make sure you use an adminUser
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With