2017-03-23 125 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))