猿问

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

为了确保在所有请求中正确处理错误结果,我正在实现一个自定义处理程序,如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 globally

func (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 error

func 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)

}


临摹微笑
浏览 146回答 1
1回答

桃花长相依

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)}我认为这并不比明确地对处理程序进行类型转换(这很清楚,如果有点重复)或将处理程序类型转换为结构好多少。后者您可以稍后扩展以包含线程安全字段(您的数据库池、应用程序配置等),然后您可以显式地将其与每个处理程序一起传递)。实际上,您当前的路由器代码仍然清晰易读,并且(对其他人)很明显是什么类型支持您的处理程序。
随时随地看视频慕课网APP

相关分类

Go
我要回答