我有一个大路由器:
router.HandleFunc("/tags", controllers.GetTags)
router.HandleFunc("/tags/items/{tagId}", controllers.GetTaggedItemsByTagId).Methods("GET")
// ...
每个此类函数如下所示:
func GetTags(w http.ResponseWriter, r *http.Request) {
tags, err := (&postgres.TagsService{}).GetTags()
if err != nil {
log.Println(err)
w.WriteHeader(500)
} else {
w.Header().Add("Content-Type", "application/json")
resp, _ := json.Marshal(tags)
w.Write(resp)
}
}
func GetTaggedItemsByTagId(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
tagId, err := strconv.Atoi(vars["tagId"])
items, err := (&postgres.TagsService{}).GetTaggedItemsByTagId(tagId)
if err != nil {
log.Println(err)
w.WriteHeader(500)
} else {
w.Header().Add("Content-Type", "application/json")
resp, _ := json.Marshal(items)
w.Write(resp)
}
}
在每个函数中,我从数据库中获取数据,将结果序列化为json
并将其返回给客户端。
我需要一些东西来避免代码重复。像这样:
func Handler(err error, data object) {
if err != nil {
log.Println(err)
w.WriteHeader(500)
} else {
w.Header().Add("Content-Type", "application/json")
resp, _ := json.Marshal(object)
w.Write(resp)
}
}
我不能这样做,因为Go是输入语言。在这种情况下,Go 中避免代码重复的最佳方法是什么?
为每个 http 处理程序的函数签名使用类型
type HandlerFunc func(w http.ResponseWriter, req *http.Request) (interface{}, error)
然后像这样包装函数
func WrapHandler(h HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
d, err := h(w, req)
// handle errors and sending out the data
}
然后使用
router.Get('/myroute', WrapHandler(GetTaggedItemsByTagId))