web-dev-qa-db-ja.com

ハンドラーに引数を渡す方法

グローバルオブジェクトを持つのではなく、データベースオブジェクトをハンドラーに渡そうとしています。しかし、これが可能かどうかはわかりません。GorillaMuxパッケージを使用しています。クロージャーを2番目のパラメーターとして使用していることがわかります。

// https://github.com/gorilla/mux/blob/master/mux.go#L174
// HandleFunc registers a new route with a matcher for the URL path.
// See Route.Path() and Route.HandlerFunc().
func (r *Router) HandleFunc(path string, f func(http.ResponseWriter,
    *http.Request)) *Route {
    return r.NewRoute().Path(path).HandlerFunc(f)
}

次に、使用できるパラメータを定義します。理想的には、このような3番目のパラメータが必要です。

// In my main
router.HandleFunc("/users/{id}", showUserHandler).Methods("GET")

func showUserHandler(w http.ResponseWriter, r *http.Request, db *gorm.DB) {
    fmt.Fprintf(w, "We should fetch the user with id %s", vars["id"])
}

回避策はありますか?または、グローバルdbオブジェクトが必要ですか?私はGoが初めてなので、潜在的な答えを詳細に説明してください。

27
MartinElvar

Goへようこそ。

グローバル変数と特別なデータベースオブジェクトを持つことは許容されます。

ただし、回避する方法がいくつかあります。たとえば、構造体を作成し、showHandlerを定義できます。

type Users struct {
    db *gorm.DB
}

func (users *Users) showHandler(w http.ResponseWriter, r *http.Request) {
    //now you can use users.db
}
func (users *Users) addHandler(w http.ResponseWriter, r *http.Request) {
    //now you can use users.db
}

// setup
users := &Users{db: createDB()}
router.HandleFunc("/users/{id}", users.showHandler).Methods("GET")
router.HandleFunc("/users/new", users.addHandler)
//etc

別のアプローチは、ラッパー関数を作成することです:

db := createDB()
router.HandleFunc("/users/{id}", func(w http.ResponseWriter, r *http.Request) {
    showUserHandler(w, r, db)
}).Method("GET")
55
OneOfOne