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 bso
Another alternative would be to declare an interface.
type SecureModel interface {
SecureMe()
}
Make sure your model implements it:
type User struct {
Id bson.ObjectId `json:"id,omitempty" bson:"_id,omitempty"`
Username string `json:"username" bson:"username"`
Secret string `json:"secret,omitempty" bson:"secret"`
}
func (u *User) SecureMe() {
u.Secret = ""
}
And only call it depending on which route is called.
// I am being sent to a non-admin, secure me.
if _, ok := user.(SecureModel); ok {
user.(SecureModel).SecureMe()
}
// Marshall to JSON, etc.
...
Edit: The reason for using an interface here is for cases where you might send arbitrary models over the wire using a common method.
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
.