首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >切片嵌套函数

切片嵌套函数
EN

Stack Overflow用户
提问于 2017-09-19 05:46:35
回答 2查看 83关注 0票数 1

我正在构建一个Go web应用程序,它在处理路由时支持各种中间件功能。我试图尽可能多地坚持使用net/http,并想知道如何不用像negroni这样的中间件库来完成这个任务。

本质上,我想要做的是能够提供中间件功能的一部分,比如一个用于日志记录,一个用于检查有效的JWT,最后是处理处理程序来处理请求。

通过定义以下结构,我就可以使用negroni相当简单地完成这一任务:

代码语言:javascript
复制
// Route ..
type Route struct {
  Method     string
  Path       string
  Middleware []negroni.Handler
  Handler    http.HandlerFunc
}

然后定义一条路线,如:

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

最后,当我启动服务器时,我导入路由列表并按如下方式注册它们:

代码语言:javascript
复制
for _, r := range routes {

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

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

这件事做得很好。

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

代码语言:javascript
复制
http.Handle("/", middlewareOne(middlewareTwo(finalHandler)))

谢谢您:)

EN

回答 2

Stack Overflow用户

发布于 2017-09-19 07:25:20

代码语言:javascript
复制
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完成

票数 1
EN

Stack Overflow用户

发布于 2017-09-19 07:40:08

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

代码语言:javascript
复制
// 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)))

每个处理程序接受下一个处理程序,并返回一个闭包,该闭包可以执行任何您想要的操作,并调用下一个处理程序。如果您需要大量这样的工具,那么编写一个类似于此的助手可能是有意义的:

代码语言:javascript
复制
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)
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46292705

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档