2016-12-16 154 views
1

我需要創建一個REST API一個HTTP處理程序。如何在Go中編寫通用處理程序?

這REST API都存儲在一個數據庫(MongoDB的在我的情況)許多不同的對象。

目前,我需要寫每對象操作一個處理程序。

我想找到一種方法,就像它可能與泛型編寫一個通用的處理程序可以處理一個特定的動作,但對於任何類型的對象(如基本上它只是CRUD在大多數的情況下)

如何我可以這樣做嗎?

這裏是我想處理程序的例子轉變爲一個通用的一個:

func IngredientIndex(w http.ResponseWriter, r *http.Request) { 
    w.Header().Set("Content-Type", "application/json; charset=UTF-8") 
    db := r.Context().Value("Database").(*mgo.Database) 
    ingredients := []data.Ingredient{} 
    err := db.C("ingredients").Find(bson.M{}).All(&ingredients) 
    if err != nil { 
     panic(err) 
    } 
    json.NewEncoder(w).Encode(ingredients) 
} 

func IngredientGet(w http.ResponseWriter, r *http.Request) { 
    w.Header().Set("Content-Type", "application/json; charset=UTF-8") 
    vars := mux.Vars(r) 
    logger := r.Context().Value("Logger").(zap.Logger) 
    db := r.Context().Value("Database").(*mgo.Database) 
    ingredient := data.Ingredient{} 
    err := db.C("ingredients").Find(bson.M{"_id": bson.ObjectIdHex(vars["id"])}).One(&ingredient) 
    if err != nil { 
     w.WriteHeader(404) 
     logger.Info("Fail to find entity", zap.Error(err)) 
    } else { 
     json.NewEncoder(w).Encode(ingredient) 
    } 
} 

基本上,我需要這樣的處理程序(這是我的暫定不工作):

func ObjectIndex(collection string, container interface{}) func(http.ResponseWriter, *http.Request) { 
    return func(w http.ResponseWriter, r *http.Request) { 
     w.Header().Set("Content-Type", "application/json; charset=UTF-8") 
     db := r.Context().Value("Database").(*mgo.Database) 
     objects := container 
     err := db.C(collection).Find(bson.M{}).All(&objects) 
     if err != nil { 
      panic(err) 
     } 
     json.NewEncoder(w).Encode(objects) 
    } 

我怎麼能這樣做?

+0

你說,「目前,我需要在每對象動作處理器寫。」這就是我使用'go generate'的原因。你不需要仿製藥! – eduncan911

+1

這是一個很好的做法嗎?因爲基本上,這樣做我依然會到處都重複的代碼,這將是難以維持比擁有一個通用的代碼處理大部分的情況。 – Kedare

回答

3

使用reflect包在每次調用創建一個新的容器:

​​

這樣稱呼它:

h := ObjectIndex("ingredients", data.Ingredient{}) 

假設data.Indgredient是片類型。

+0

真棒,這就是我一直在尋找的,謝謝! :) – Kedare

相關問題