英文:
Override struct tags in go
问题
我在项目中有一个实体,可以被公开和管理员查看。并非所有字段都应该对公众可见。
例如:
type Foo struct {
Id bson.ObjectId `json:"id" bson:"_id"`
DateAdded time.Time `json:"date_added" bson:"date_added"`
Bar string `json:"bar" bson:"bar"`
AdminOnly string `json:"admin_only" bson:"admin_only"`
}
AdminOnly
字段应该只对管理员可见。目前,当来自公众的请求到达时,我调用一个单独的方法,将每个需要的字段复制到新的结构体中:
type FooPublic struct {
Id bson.ObjectId `json:"id" bson:"_id"`
DateAdded time.Time `json:"date_added" bson:"date_added"`
Bar string `json:"bar" bson:"bar"`
}
func (f *Foo) Public() (res FooPublic) {
res = FooPublic{
Id: f.Id,
DateAdded: f.DateAdded,
Bar: f.Bar,
}
return
}
但是,如果我需要在实体中添加新字段,我需要在三个地方添加它:在结构体本身中,FooPublic
中和 Public
方法中。这似乎违反了 DRY 原则。在这里,有什么正确的、惯用的解决方案吗?我可以定义 FooPublic
来覆盖所需字段的标签吗?或者可能有一种好的方法可以将一个结构体的相应字段复制到另一个结构体中,这样我就不需要在 Public
方法中手动执行此操作了吗?
英文:
I have an entity in my project that is viewable by public and by admin. Not all fields should be accessible by public.
For example
type Foo struct {
Id bson.ObjectId `json:"id" bson:"_id"`
DateAdded time.Time `json:"date_added" bson:"date_added"`
Bar string `json:"bar" bson:"bar"`
AdminOnly string `json:"admin_only" bson:"admin_only"`
}
AdminOnly field should be only visible to admins.
For now, when requests comes from public, I call separate method that copies every needed field to new struct
type FooPublic struct {
Id bson.ObjectId `json:"id" bson:"_id"`
DateAdded time.Time `json:"date_added" bson:"date_added"`
Bar string `json:"bar" bson:"bar"`
}
func (f *Foo) Public() (res FooPublic) {
res = FooPublic{
Id: f.Id,
DateAdded: f.DateAdded,
Bar:f.Bar,
}
return
}
But if I need to add new field to my entity, I need to add it in 3 places. In struct itself, in PublicFoo
and in Public
method.
This seems to be agains DRY principle. What is correct, idiomatic solution here? Can I define FooPublic
so it overrides tags of needed fields? Or probably there is at least good way to copy corresponding fields from one struct to another, so I don't need to do this manually in Public
method?
答案1
得分: 3
一般情况下,可以通过使用嵌入来避免这种重复。你的 Foo
类型应该嵌入 FooPublic
:
type FooPublic struct {
Id bson.ObjectId `json:"id" bson:"_id"`
DateAdded time.Time `json:"date_added" bson:"date_added"`
Bar string `json:"bar" bson:"bar"`
}
type Foo struct {
FooPublic
AdminOnly string `json:"admin_only" bson:"admin_only"`
}
func (f *Foo) Public() FooPublic {
return f.FooPublic
}
但是,如果有人能够调用 Foo.Public()
,那么这个人已经拥有 Foo
或 *Foo
值(因此可以访问导出的 AdminOnly
字段),那么这样做有什么意义呢?
一个更好的解决方案是使用接口,而不是暴露 Foo
结构体。
英文:
In general this repetition can be avoided by using embedding. Your Foo
type should embed FooPublic
:
type FooPublic struct {
Id bson.ObjectId `json:"id" bson:"_id"`
DateAdded time.Time `json:"date_added" bson:"date_added"`
Bar string `json:"bar" bson:"bar"`
}
type Foo struct {
FooPublic
AdminOnly string `json:"admin_only" bson:"admin_only"`
}
func (f *Foo) Public() FooPublic {
return f.FooPublic
}
But if someone is able to call the Foo.Public()
, that someone already has the Foo
or *Foo
value (and so can access the exported AdminOnly
field), so what's the point?
A better solution would be to use an interface, and not expose the Foo
struct.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论