The problem I'm trying to solve is that I have a model of a community that looks like this
type Community struct {
Name string
Description string
Sources []Source
Popularity int
FavoriteCount int
Moderators []string
Children []Community
Tracks []Track
}
Communities hold a lot of information and there are scenarios when I want to return only part of the description such as if I'm returning a list of trending communities. In this case I'd want to return only
type Community struct {
Name string
Description string
Popularity int
FavoriteCount int
}
The only way I can think of doing this is to create a new type containing only those fields and write a convenience method that takes a community and returns that type, but essentially creating a new object and copying those fields by value, is there a better way to do this?
I'm aware of the json:"-"
syntax, but I'm not sure of how you could do this on a case by case basis as I still need to sometimes return the full object, perhaps a different type that is converted to?
[This](http://attilaolah.eu/2014/09/10/json-and-struct-composition-in-go/ ) is a cool approach, which involves creating a sort of Masking struct.
Here's the example in the article:
type User struct {
Email string `json:"email"`
Password string `json:"password"`
// many more fields…
}
type omit *struct{}
type PublicUser struct {
*User
Password omit `json:"password,omitempty"`
}
// when you want to encode your user:
json.Marshal(PublicUser{
User: user,
})
I developed a library which can help you in this regard: Sheriff
You can annotate your struct fields with special tags and call Sheriff to transform the given struct into a subset of it. After that you can call json.Marshal()
or whatever else you want to marshal into.
Your example would become as simple as:
type Community struct {
Name string `json:"name" groups:"trending,detail"`
Description string `json:"description" groups:"trending,detail"`
Sources []Source `json:"sources" groups:"detail"`
Popularity int `json:"popularity" groups:"trending,detail"`
FavoriteCount int `json:"favorite_count" groups:"trending,detail"`
Moderators []string `json:"moderators" groups:"detail"`
Children []Community `json:"children" groups:"detail"`
Tracks []Track `json:"tracks" groups:"detail"`
}
communities := []Community{
// communities
}
o := sheriff.Options{
Groups: []string{"trending"},
}
d, err := sheriff.Marshal(&o, communities)
if err != nil {
panic(err)
}
out, _ := json.Marshal(d)
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