2016-12-16 9 views
1

REST API用にHTTPハンドラを作成する必要があります。Goに汎用ハンドラを書き込む方法は?

このREST APIには、データベース(私の場合はMongoDB)に格納されているさまざまなオブジェクトがあります。

現在、オブジェクトごとにアクションごとに1つのハンドラを記述する必要があります。

私はそれが(基本的には例ほとんどのちょうど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

呼び出しごとに新しいコンテナの作成に反映されたパッケージを使用します。

​​

をこのようにそれを呼び出します。

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

data.Indgredientはスライスタイプであると仮定。

+0

驚くばかりです、私が探していたものです。ありがとうございました! :) – Kedare

関連する問題