检索模型(结构)列表的通用方法
Generic method for retrieving list of models (structs)
我正在尝试为我的服务创建基本的 CRUD。它基于在结构中创建的数据模型。问题是我真的不想重复 CRUD 方法的代码。例如,我将 ModelA 和 ModelB 定义为结构:
type ModelA struct {
ID bson.ObjectId `json:"ID,omitempty" bson:"_id,omitempty"`
Slug string `json:"slug" bson:"slug,omitempty"`
Creator string `json:"-" bson:"creator,omitempty"`
DefaultLanguage string `json:"defaultLanguage" bson:"defaultLanguage,omitempty"`
}
type ModelB struct {
ID bson.ObjectId `json:"ID,omitempty" bson:"_id,omitempty"`
Type string `json:"type" bson:"type,omitempty"`
}
我想要的是制作通用方法来检索给定模型的数组。使用模型对我来说很重要。我可以使用纯 interface{}
类型快速完成,但会丢失模型功能,例如在 JSON 输出中隐藏某些属性(例如 ModelA.Creator
)。
到目前为止,我已经创建了用于创建新数据和检索单个模型的通用方法。这是示例代码:
// GET: /modelsa/{:slug}
func (r *Routes) GetModelA(w rest.ResponseWriter, req *rest.Request) {
// set model as ModelA
var model models.ModelA
r.GetBySlug(w, req, &model, "models")
}
// GET: /modelsb/{:slug}
func (r *Routes) GetModelB(w rest.ResponseWriter, req *rest.Request) {
// set model as ModelB
var model models.ModelB
r.GetBySlug(w, req, &model, "models")
}
func (r *Routes) GetBySlug(w rest.ResponseWriter, req *rest.Request, m interface{}, collection string) {
slug := req.PathParam("slug")
if err := r.GetDocumentBySlug(slug, collection, m, w, req); err != nil {
rest.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteJson(m)
}
GetModelA
和 GetModelB
是使用通用方法 GetBySlug
的路由处理程序,即 returns 由给定模型格式化的 JSON。
我想做同样的事情,但使用给定模型的数组。到目前为止,我在将结果转换为结构时遇到了问题:
// GET /modelsa/
func (r *Routes) GetModels(w rest.ResponseWriter, req *rest.Request) {
// I think in this case I don't have to pass an array of struct
// because the given struct is only reference. It could be:
// var result models.ModelA as well. Converting it into array could
// be done in GetList() method
var result []models.ModelA
r.GetList(w, req, &result, "models")
}
func (r *Routes) GetList(w rest.ResponseWriter, req *rest.Request, res interface{}, col string) {
}
我无法将 res
参数设置为 interface{} 数组。另外,如果我尝试在 GetList()
方法中将结果转换为 []interface{}
,我不能将其转换为 res
参数,因为它不是数组。
有什么好的方法吗?也许我想错了,应该重新设计方法?任何建议将不胜感激。
您可以声明表示模型切片的新类型。例如,
type ModelAList []ModelA
type ModelBList []ModelB
然后当您将这些新类型的变量传递给您的 r.GetDocumentBySlug()
时,encoding/json
包中的函数将相应地解组切片。
您可以找到工作示例 here (marshaling) and here (unmarshaling)。
我正在尝试为我的服务创建基本的 CRUD。它基于在结构中创建的数据模型。问题是我真的不想重复 CRUD 方法的代码。例如,我将 ModelA 和 ModelB 定义为结构:
type ModelA struct {
ID bson.ObjectId `json:"ID,omitempty" bson:"_id,omitempty"`
Slug string `json:"slug" bson:"slug,omitempty"`
Creator string `json:"-" bson:"creator,omitempty"`
DefaultLanguage string `json:"defaultLanguage" bson:"defaultLanguage,omitempty"`
}
type ModelB struct {
ID bson.ObjectId `json:"ID,omitempty" bson:"_id,omitempty"`
Type string `json:"type" bson:"type,omitempty"`
}
我想要的是制作通用方法来检索给定模型的数组。使用模型对我来说很重要。我可以使用纯 interface{}
类型快速完成,但会丢失模型功能,例如在 JSON 输出中隐藏某些属性(例如 ModelA.Creator
)。
到目前为止,我已经创建了用于创建新数据和检索单个模型的通用方法。这是示例代码:
// GET: /modelsa/{:slug}
func (r *Routes) GetModelA(w rest.ResponseWriter, req *rest.Request) {
// set model as ModelA
var model models.ModelA
r.GetBySlug(w, req, &model, "models")
}
// GET: /modelsb/{:slug}
func (r *Routes) GetModelB(w rest.ResponseWriter, req *rest.Request) {
// set model as ModelB
var model models.ModelB
r.GetBySlug(w, req, &model, "models")
}
func (r *Routes) GetBySlug(w rest.ResponseWriter, req *rest.Request, m interface{}, collection string) {
slug := req.PathParam("slug")
if err := r.GetDocumentBySlug(slug, collection, m, w, req); err != nil {
rest.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteJson(m)
}
GetModelA
和 GetModelB
是使用通用方法 GetBySlug
的路由处理程序,即 returns 由给定模型格式化的 JSON。
我想做同样的事情,但使用给定模型的数组。到目前为止,我在将结果转换为结构时遇到了问题:
// GET /modelsa/
func (r *Routes) GetModels(w rest.ResponseWriter, req *rest.Request) {
// I think in this case I don't have to pass an array of struct
// because the given struct is only reference. It could be:
// var result models.ModelA as well. Converting it into array could
// be done in GetList() method
var result []models.ModelA
r.GetList(w, req, &result, "models")
}
func (r *Routes) GetList(w rest.ResponseWriter, req *rest.Request, res interface{}, col string) {
}
我无法将 res
参数设置为 interface{} 数组。另外,如果我尝试在 GetList()
方法中将结果转换为 []interface{}
,我不能将其转换为 res
参数,因为它不是数组。
有什么好的方法吗?也许我想错了,应该重新设计方法?任何建议将不胜感激。
您可以声明表示模型切片的新类型。例如,
type ModelAList []ModelA
type ModelBList []ModelB
然后当您将这些新类型的变量传递给您的 r.GetDocumentBySlug()
时,encoding/json
包中的函数将相应地解组切片。
您可以找到工作示例 here (marshaling) and here (unmarshaling)。