如何避免路由器处理代码中的代码重复

时间:2017-03-23 13:26:01

标签: go refactoring

我有一个大路由器:

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避免代码重复的最佳方法是什么?

1 个答案:

答案 0 :(得分:3)

为每个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))