router in Go – run a function before each http request

huangapple go评论68阅读模式
英文:

router in Go - run a function before each http request

问题

你可以使用中间件(middleware)来在每个 HTTP 请求之前运行函数。在 Go 中,中间件是一个函数,它接收一个 http.Handler 对象作为参数,并返回一个新的 http.Handler 对象。

首先,你可以创建一个中间件函数,用于在每个请求之前运行的逻辑。例如,你可以创建一个名为 authMiddleware 的函数,用于检查请求路径是否包含 "/authAPI/",如果包含则执行相应的逻辑。

func authMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // 在这里执行你的逻辑
        if strings.Contains(r.URL.Path, "/authAPI/") {
            // 执行特定的逻辑
        }

        // 继续处理请求
        next.ServeHTTP(w, r)
    })
}

然后,在你的路由设置中,将中间件应用到需要的路由上。例如,你可以将 authMiddleware 应用到所有路由以及 /authAPI/ 路径下的路由。

mux := http.NewServeMux()

// 应用中间件到所有路由
mux.Handle("/", authMiddleware(http.HandlerFunc(test)))

// 应用中间件到包含 "/authAPI/" 的路由
mux.Handle("/authAPI/", authMiddleware(http.HandlerFunc(auth)))

这样,每当有请求到达时,中间件函数 authMiddleware 将会在处理请求之前执行相应的逻辑。

英文:

I'm using Go with http with Go like this:

mux := http.NewServeMux()
mux.HandleFunc("/API/user", test)
mux.HandleFunc("/authAPI/admin", auth)

and I would like to run a function before every http request
and better yet, run a function on every request that has the /authAPI/ in them.
how can I achieve this in Go?

答案1

得分: 5

在@Thomas提出的建议之上,你可以在自己的mux中包装整个mux,在调用任何处理程序之前调用它,并且可以调用自己的处理程序。这就是在Go中实现替代HTTP路由器的方式。示例代码如下:

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Handled %s", r.RequestURI)
}

func main(){
    // 这将执行实际的路由,但这不是强制性的,我们可以编写自定义的路由器
    mux := http.NewServeMux()
    mux.HandleFunc("/foo", handler)
    mux.HandleFunc("/bar", handler)
    
    // 我们传递一个自定义的http处理程序,它进行预处理并调用mux来调用实际的处理程序
    http.ListenAndServe(":8081", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request){
        fmt.Fprintln(w, "Preprocessing yo")
        mux.ServeHTTP(w,r)
    }))
}

这段代码中,我们创建了一个自定义的mux,并将处理程序注册到不同的路径上。然后,我们创建了一个自定义的http处理程序,它在调用实际处理程序之前进行预处理,并调用mux来处理请求。最后,我们使用http.ListenAndServe函数来启动服务器并监听指定的端口。

英文:

On top of what @Thomas has proposed, you can wrap the whole mux in your own mux that is called before any handler is invoked, and can just invoke handlers of its own. That's how alternative http routers are implemented in go. Example:

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Handled %s", r.RequestURI)
}


func main(){
    // this will do the actual routing, but it's not mandatory, 
    // we can write a custom router if we want
	mux := http.NewServeMux()
    mux.HandleFunc("/foo", handler)
    mux.HandleFunc("/bar", handler)
    
    // we pass a custom http handler that does preprocessing and calls mux to call the actual handler
    http.ListenAndServe(":8081", http.HandlerFunc(func (w http.ResponseWriter, r *http.Request){
        fmt.Fprintln(w, "Preprocessing yo")
        mux.ServeHTTP(w,r)
    }))
}

答案2

得分: 2

你可以编写一个包装函数:

func wrapHandlerFunc(handler http.HandlerFunc) http.HandlerFunc {
  return func(w http.ResponseWriter, req *http.Request) {
    // ...
    // 做一些操作
    // ...
    handler(w, req)
  }
}

然后像这样使用它:

mux.HandleFunc("/authAPI/admin", wrapHandlerFunc(auth))

据我所知,自动运行在给定 URL 树下的所有内容(在 mux 的术语中称为子路由器)是不支持的。

英文:

You could just write a wrapper function:

func wrapHandlerFunc(handler http.HandlerFunc) http.HandlerFunc {
  return func(w http.ResponseWriter, req *http.Request) {
    // ...
    // do something
    // ...
    handler(w, req)
  }
}

And use it like this:

mux.HandleFunc("/authAPI/admin", wrapHandlerFunc(auth))

Running it automatically for everything under a given URL tree (subrouter, in mux parlance) is, as far as I know, not supported.

huangapple
  • 本文由 发表于 2015年8月2日 18:21:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/31770872.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定