我正在考虑使用标准库进行路由的方法。具有根据请求类型调用其他处理程序功能的处理程序功能是否有效?例如
func main() {
m := http.NewServeMux()
m.HandleFunc("/books", books)
// ...
}
func books(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
getBooks(w, r)
case "POST":
createBook(w, r)
}
}
这是好习惯吗?我不想声明自定义处理程序,因为我发现函数要干净一些。
答案 0 :(得分:5)
是的,这是完全正确的;处理程序只是函数,因此没有理由不应该这样做。实际上,middleware is usually implemented就是这样。
关于处理程序功能根本没有“魔术”。只要您要写入正确的文件描述符(w http.ResponseWriter
),一切都会发生。
这并不意味着对于所有应用程序而言,使用此模式不一定是个好主意-路由库的存在是有原因的-但对于较小的程序,它就可以正常工作。
答案 1 :(得分:3)
让
HandlerFunc
呼叫另一个HandlerFunc
是完全有效的。
实际上,这就是使用标准库实现中间件的方式。
这是 Mat Ryer 的Post(令人惊讶的家伙btw),他进一步详细解释了他所说的
“ http.Handler包装器技术”
您想要使用HandlerFunc
的方式使我想起Laravel's Resource Controllers,我认为它非常简洁。但是,不小心使用它们可能会成为不必要的开销。
我建议您尝试一下julienschmidt/httprouter库。
它非常快速且易于使用。
答案 2 :(得分:2)
这是有效的,正如其他答案处理程序中提到的那样,它们只是函数。
改变的是请求方法;可能值得考虑使用地图实现。随着您需要更改处理程序的数量,这可能会更具扩展性。
type BookController struct {
routes map[string]http.HandlerFunc
}
func (b BookController) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// beware this very basic example will panic if there's not a registered handler for r.Method
// but I assume you'd have to do handling of missing method logic in your default switch anyway
b.routes[r.Method].ServeHTTP(w, r)
}
并注册它们:
m := http.NewServeMux()
b := BookController{}
b.routes = map[string]http.HandlerFunc{
"GET": getBooks,
"POST": createBooks,
}
m.Handle("/books", b)
稍微多一些样板,但以后可以更轻松地添加/删除处理程序。