2017-03-23 124 views
1

我有一个大的路由器:如何避免路由器代码重复处理代码

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在这种情况下避免代码重复的最佳方法是什么?

回答

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))