为了账号安全,请及时绑定邮箱和手机立即绑定

使用 Negroni 时可以全局使用自定义 HTTP 处理程序还是仅按请求使用?

使用 Negroni 时可以全局使用自定义 HTTP 处理程序还是仅按请求使用?

Go
临摹微笑 2021-11-01 17:05:02
为了确保在所有请求中正确处理错误结果,我正在实现一个自定义处理程序,如http://blog.golang.org/error-handling-and-go 中所述。因此w http.ResponseWriter, r *http.Request,处理程序不仅可以接受参数,还可以选择返回一个error.我使用的内格罗尼,想知道我是否可以将它设置一次来包装所有的请求进入handler,或者如果它总是要建立在每个请求的基础,作为完成/并/foo在下面的例子吗?type handler func(w http.ResponseWriter, r *http.Request) error// ServeHTTP checks for error results and handles them globallyfunc (fn handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {    if err := fn(w, r); err != nil {        http.Error(w, err, http.StatusInternalServerError)    }}// Index matches the `handler` type and returns an errorfunc Index(w http.ResponseWriter, r *http.Request) error {    return errors.New("something went wrong")}func main() {    router := mux.NewRouter()    // note how `Index` is wrapped into `handler`. Is there a way to     // make this global? Or will the handler(fn) pattern be required     // for every request?    router.Handle("/", handler(Index)).Methods("GET")    router.Handle("/foo", handler(Index)).Methods("GET")    n := negroni.New(        negroni.NewRecovery(),        negroni.NewLogger(),        negroni.Wrap(router),    )    port := os.Getenv("PORT")    n.Run(":" + port)}
查看完整描述

1 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

r.Handle如果需要,您可以编写一个包装器。您不能使用 Negroni 全局执行此操作,因为并非您使用的所有中间件都假定您的handler类型。


例如


// Named to make the example clear.

func wrap(r *mux.Router, pattern string, h handler) *mux.Route {

    return r.Handle(pattern, h)

}


func index(w http.ResponseWriter, r *http.Request) error {

    io.WriteString(w, "Hello")

    return nil

}


func main() {

    r := mux.NewRouter()

    wrap(r, "/", index)


    http.ListenAndServe(":8000", r)

}

我认为这并不比明确地对处理程序进行类型转换(这很清楚,如果有点重复)或将处理程序类型转换为结构好多少。后者您可以稍后扩展以包含线程安全字段(您的数据库池、应用程序配置等),然后您可以显式地将其与每个处理程序一起传递)。


实际上,您当前的路由器代码仍然清晰易读,并且(对其他人)很明显是什么类型支持您的处理程序。


查看完整回答
反对 回复 2021-11-01
  • 1 回答
  • 0 关注
  • 133 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信