【问题标题】:Nest Functions From Slice从切片嵌套函数
【发布时间】:2017-09-19 05:46:35
【问题描述】:

我正在构建一个在处理路由时支持各种中间件功能的 Go Web 应用程序。我正在尝试尽可能地坚持net/http,并且想知道如何在不使用negroni之类的中间件库的情况下完成此操作。

基本上,我想做的是能够提供一个中间件功能,一个用于记录,一个用于检查有效的 JWT,最后是处理请求的处理程序。

我可以通过定义以下结构来相当简单地用 negroni 做到这一点:

// Route ..
type Route struct {
  Method     string
  Path       string
  Middleware []negroni.Handler
  Handler    http.HandlerFunc
}

然后定义如下路线:

var commonRoutes = []Route{
    {
        Method:     "GET",
        Path:       "/info",
        Middleware: []negroni.Handler{negroni.HandlerFunc(middleware.CheckCache), negroni.HandlerFunc(middleware.Authenticated), negroni.NewLogger()},
        Handler:    handlers.APIInfo,
    },
}

最后,当我启动服务器时,我会导入路由列表并像这样注册它们:

for _, r := range routes {

  handler := append(r.Middleware, negroni.Wrap(r.Handler))

  router.Handle(r.Path, negroni.New(handler...)).Methods(r.Method)
}

这很完美。

知道如何仅使用标准的net/http 签名和定义中间件处理程序的方式来做到这一点,如下所示:

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

谢谢你:)

【问题讨论】:

    标签: go slice middleware


    【解决方案1】:
    func Auth(n http.Handler) http.Handler {
      return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
          log.Printf("Start")
          n.ServeHTTP(w, r)
          log.Printf("End")
      })
    }
    
    func processReq(w http.ResponseWriter, r *http.Request) {
      w.Write([]byte("Success"))
    }
    
    
    func main() {
      handler := http.HandlerFunc(processReq)
    
      http.Handle("/",Auth(handler))
      http.ListenAndServe(":8000", nil)
    }
    

    可以使用 http.handler 来完成

    【讨论】:

      【解决方案2】:

      简单。您可以像这样定义每个处理程序:

      // So I don't have to type it over and over...
      type HTTPHandler func(w http.ResponseWriter, r *http.Request)
      
      func Handler1(next HTTPHandler) HTTPHandler {
          return func(w http.ResponseWriter, r *http.Request){
              // Do stuff
      
              if next != nil {
                  next(w, r)
              }
          }
      }
      
      // Handler2 ... HandlerN defined in the same basic way.
      
      // Chaining:
      http.Handle("/", Handler1(Handler2(nil)))
      

      每个处理程序获取下一个处理程序并返回一个闭包,该闭包执行您想要的任何操作并调用下一个处理程序。如果你需要很多这些,编写一个类似于这个的帮助器可能是有意义的:

      func MakeHandler(worker, next HTTPHandler) HTTPHandler {
          return func(w http.ResponseWriter, r *http.Request){
              // Maybe have to worker return an error and do standard error
              // handling here? Could simplify your code some depending on
              // what you are doing.
              worker(w, r)
      
              if next != nil {
                  next(w, r)
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-24
        • 1970-01-01
        • 2011-07-17
        • 2021-10-23
        • 1970-01-01
        • 2013-02-23
        • 2019-01-02
        • 1970-01-01
        相关资源
        最近更新 更多