Go 第一时间链函数

Go 第一时间链函数,go,chaining,Go,Chaining,假设我想在运行http服务器的自定义mux之前运行一个记录器 部分情况下,我可以链接记录器并添加自定义mux,如下所示: 但我不知道如何包装路由器,以使这项工作,或者这是否是一个合法的方法。有人能告诉我这里缺少什么吗?修改代码以使用http.Handler而不是http.HandlerFunc type Middleware func(http.Handler) http.Handler func ServeHTTPIterator(h http.Handler, m ...Middlewar

假设我想在运行http服务器的自定义mux之前运行一个记录器

部分情况下,我可以链接记录器并添加自定义mux,如下所示:


但我不知道如何包装路由器,以使这项工作,或者这是否是一个合法的方法。有人能告诉我这里缺少什么吗?

修改代码以使用http.Handler而不是http.HandlerFunc

type Middleware func(http.Handler) http.Handler

func ServeHTTPIterator(h http.Handler, m ...Middleware) http.Handler {
    if len(m) < 1 {
        return h
    }
    wrapped := h

    // loop in reverse to preserve middleware order
    for i := len(m) - 1; i >= 0; i-- {
        wrapped = m[i](wrapped)
    }
    return wrapped
}
    
func LogFirst(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Print(`First`)
        h.ServeHTTP(w, r)
    })
}

func LogSecond(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Print(`Second`)
        h.ServeHTTP(w, r)
    })
}
使用新版本的ServeHTTPIterator包装路由器

httpServer.Handler = ServeHTTPIterator(router, preMiddle...)

通过这些更改,可以在调用路由器之前写入日志。

您可以通过以下方式实现此目的,而不是在您的服务器函数中传播中间件。您希望应用一部分中间件,如:

主程序包
进口(
“fmt”
“net/http”
“时间”
“github.com/julienschmidt/httprouter”
)
键入中间件func(http.HandlerFunc)http.HandlerFunc
func servehttppiterator(h http.HandlerFunc,m[]中间件)http.HandlerFunc{
如果len(m)<1{
返回h
}
包裹:=h
//反向循环以保持中间件顺序
对于i:=len(m)-1;i>=0;i--{
包裹=m[i](包裹)
}
退货包装
}
func IndexHandler(w http.ResponseWriter,r*http.Request){
Fprintf(w,“你好索引!”)
}
func LogFirst(h http.HandlerFunc)http.HandlerFunc{
返回http.HandlerFunc(func(w http.ResponseWriter,r*http.Request){
格式打印(`First`)
h、 ServeHTTP(w,r)
})
}
func LogSecond(h http.HandlerFunc)http.HandlerFunc{
返回http.HandlerFunc(func(w http.ResponseWriter,r*http.Request){
格式打印(`Second`)
h、 ServeHTTP(w,r)
})
}
func main(){
httpServer:=&http.Server{
地址:`my.local:8080`,
读取超时:5*次。秒,
WriteTimeout:5*次。秒,
空闲时间:5*次。秒,
}
var路由器*httprouter.Router
preMiddle:=[]中间件{
首先,
第二,,
}
http.HandleFunc(“/”,ServeHTTPIterator(IndexHandler,preMiddle))
httpServer.Handler=路由器
}

使用此部分
http.Handle(“/”,…
http.Handle
只对默认的mux起作用,如果是这样的话,这行中是否有任何价值,因为我们最终用httprouter替换默认的mux,当我们这样做
httpServer.Handler=…
时?我很感激并很抱歉提出另一个问题,但我使用的是一个自定义路由器
HttpOuter
(见顶部)因此
router:=http.NewServeMux()
在这种情况下并不适用,除非代码完全相同。“问题中的代码不使用httprouter”-嗯?
var router*httprouter
&
“github.com/julienschmidt/httprouter”
&
httpServer.Handler=Router
就在代码中,但如果您做了任何更改,则不会有任何影响。问题中的应用程序确实使用指向httprouter的nil指针,但应用程序不会创建httprouter或使用httprouter注册处理程序。确实,它只是一个代码片段,而不是完整的应用程序,如果我认为,为了让问题变得足够清楚,有必要加入更多的内容。我会……不可能总是知道多少是足够的,多少只是增加了干扰手头问题的噪音。仅供参考:我宁愿将这两个答案分开,因为这两个答案都同样有效。我只喜欢另一个,因为没有问题,我也学会了这种方法
type Middleware func(http.Handler) http.Handler

func ServeHTTPIterator(h http.Handler, m ...Middleware) http.Handler {
    if len(m) < 1 {
        return h
    }
    wrapped := h

    // loop in reverse to preserve middleware order
    for i := len(m) - 1; i >= 0; i-- {
        wrapped = m[i](wrapped)
    }
    return wrapped
}
    
func LogFirst(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Print(`First`)
        h.ServeHTTP(w, r)
    })
}

func LogSecond(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Print(`Second`)
        h.ServeHTTP(w, r)
    })
}
router := httprouter.New()
router.GET("/", IndexHandler)
httpServer.Handler = ServeHTTPIterator(router, preMiddle...)
package main

import (
    "fmt"
    "net/http"
    "time"

    "github.com/julienschmidt/httprouter"
)

type Middleware func(http.HandlerFunc) http.HandlerFunc

func ServeHTTPIterator(h http.HandlerFunc, m []Middleware) http.HandlerFunc {
    if len(m) < 1 {
        return h
    }
    wrapped := h

    // loop in reverse to preserve middleware order
    for i := len(m) - 1; i >= 0; i-- {
        wrapped = m[i](wrapped)
    }
    return wrapped
}

func IndexHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello Index!")
}

func LogFirst(h http.HandlerFunc) http.HandlerFunc {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Print(`First`)
        h.ServeHTTP(w, r)
    })
}

func LogSecond(h http.HandlerFunc) http.HandlerFunc {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Print(`Second`)
        h.ServeHTTP(w, r)
    })
}

func main() {
    httpServer := &http.Server{
        Addr:         `my.local:8080`,
        ReadTimeout:  5 * time.Second,
        WriteTimeout: 5 * time.Second,
        IdleTimeout:  5 * time.Second,
    }

    var Router *httprouter.Router
    
    preMiddle := []Middleware{
        LogFirst,
        LogSecond,
    }

    http.HandleFunc("/", ServeHTTPIterator(IndexHandler, preMiddle))

    httpServer.Handler = Router
}