Go HTTP处理函数

Go HTTP处理函数,go,httphandler,Go,Httphandler,我看到一些http处理程序函数声明是多种多样的。 我发现其中两个是标准函数和在处理程序中返回匿名函数的函数。 例如: 使用标准方式: func helloworld(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello World") } 这是为http api声明处理程序的最直接的方法 另一种方法是在处理函数中使用匿名/闭包函数: func helloworld2() http.Handler { r

我看到一些http处理程序函数声明是多种多样的。 我发现其中两个是标准函数和在处理程序中返回匿名函数的函数。 例如:

使用标准方式:

func helloworld(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Hello World")
}
这是为http api声明处理程序的最直接的方法

另一种方法是在处理函数中使用匿名/闭包函数:

func helloworld2() http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){
        fmt.Fprintln(w, "Hello World")
    })
}

区别和好处是什么?何时使用其中一个?最佳做法是什么?

通过返回闭包,返回匿名函数是处理需要附加参数的处理程序的唯一方法。例如:

func fooHandler(db *someDatabase) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // do something with `db` variable
    }
}
否则,两种方法之间通常没有实际区别。为了保持一致性,可以选择普遍使用匿名函数。

模式

func Middleware(next http.Handler) http.Handler{
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    // Do something
    next.ServeHTTP(w, r)
  })
}
通常用于构建类似于链的中间件

http.Handle("/", middlewareOne(middlewareTwo(finalHandler)))

关于返回匿名函数的结构,最流行的信息来源之一是Mat Ryer的博客文章

我相信在这里引用他的文章会很好:

。。。处理函数实际上并不处理请求,它们返回一个处理请求的函数。这为我们提供了一个关闭环境,处理程序可以在其中操作:

prepareThing只调用一次,因此您可以使用它执行一次性操作 按处理程序初始化,然后使用处理程序中的内容

而且

如果端点有自己的请求和响应类型,通常它们只对特定的处理程序有用。如果是这种情况,您可以在函数中定义它们

}

实际上,在编写RESTy API时,处理程序以资源命名,例如,您有/maps资源和适当的处理程序struct mapsHandler,并将依赖项(存储库、包含某些业务逻辑的服务、记录器)注入其中。但有时您还需要为每个句柄专门传递一个附加依赖项,突然意识到该句柄具有严格的签名,所以您应该将其包装起来。那么你有这样的东西

// RESTy routes for "maps" resource
router.Route("/maps", func(r chi.Router) {
    adHocDependency := newAdHocDependency(options)
    r.Post("/", mapsHandler.handleCreateMap(adHocDependency))
})
使您的特殊依赖项对处理程序可见

希望有帮助

如果你还没有阅读官方的围棋博客,请阅读
func (s *server) handleSomething() http.HandlerFunc {

  // you have these handy structs always visible to your handler and eyes 
  // and invisible to code that don't use them

  type request struct {
    Name string
  }

  type response struct {
    Greeting string `json:"greeting"`
  }

  return func(w http.ResponseWriter, r *http.Request) {
    // decode into request struct
    // validate
    // call business-logic 
    // encode response from business-logic into response struct 

  }
// RESTy routes for "maps" resource
router.Route("/maps", func(r chi.Router) {
    adHocDependency := newAdHocDependency(options)
    r.Post("/", mapsHandler.handleCreateMap(adHocDependency))
})