【问题标题】:How do I pass arguments to my handler如何将参数传递给我的处理程序
【发布时间】:2014-11-30 11:02:53
【问题描述】:

我试图将我的数据库对象传递给我的处理程序,而不是拥有一个全局对象。但我不知道这是否可能,我正在使用 Gorilla Mux 包,我可以看到它需要一个闭包作为第二个参数。

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

然后定义我可以使用的参数,理想情况下我希望有第三个这样的参数。

// 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 新手,所以请详细解释一个可能的答案。

【问题讨论】:

标签: go gorilla


【解决方案1】:

欢迎来到。

具有全局变量和特别是数据库对象是可以接受的。

但是,如果您不想这样做,也有几种解决方法,例如,您可以创建一个结构并在其上定义您的 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")

【讨论】:

  • 谢谢 OneOfOne。这个想法是,我想要一种更直接的方式来做这件事,也许我想多了。您认为哪种解决方案最干净?
  • @MartinElvar 对于数据库连接,我会说全局变量很好。如果您想要只能由一组特定函数使用的特定变量,那么结构解决方案。
  • @MartinElvar 还请记住,虽然大多数数据库处理程序对于并发是安全的,但其他一切都不是,所以如果你在一个处理程序中设置一个变量并在另一个处理程序中获取它,你将不得不使用某种锁定。
  • 非常感谢您的帮助,谢谢@OneOfOne :)
  • 我会采用建议的“包装”方法。我已经看到它通常用于用“中间件”服务包装处理程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-02
  • 1970-01-01
  • 1970-01-01
  • 2012-08-30
相关资源
最近更新 更多