第一次链接函数
First time chaining functions
假设我想 运行 一个记录器,然后 运行 我的自定义 HTTP 服务器多路复用器。
部分方式我可以链接记录器并添加这样的自定义多路复用器:https://play.golang.org/p/Edurl-Rhqb9
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
}
但现在假设我想 运行 我的多路复用器在记录器之后,在那种情况下我想我会做类似的事情:
preMiddle := []Middleware{
LogFirst,
LogSecond,
Router,
}
但我不确定如何包装 Router 以使其工作,或者这是否是一种合法的方法。有人可以告诉我我在这里缺少什么吗?
修改代码以使用 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)
})
}
创建路由器并向路由器注册处理程序。为 IndexHandler 添加 parameters 参数,使该函数与 httprouter 兼容。
router := httprouter.New()
router.GET("/", IndexHandler)
使用新版本的 ServeHTTPIterator 封装路由器。
httpServer.Handler = ServeHTTPIterator(router, preMiddle...)
进行这些更改后,日志将在调用路由器之前写入。
您可以实现它,而不是在您的 serveIterator 函数中传播中间件,期望像这样应用中间件片段:go playground
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
}
假设我想 运行 一个记录器,然后 运行 我的自定义 HTTP 服务器多路复用器。
部分方式我可以链接记录器并添加这样的自定义多路复用器:https://play.golang.org/p/Edurl-Rhqb9
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
}
但现在假设我想 运行 我的多路复用器在记录器之后,在那种情况下我想我会做类似的事情:
preMiddle := []Middleware{
LogFirst,
LogSecond,
Router,
}
但我不确定如何包装 Router 以使其工作,或者这是否是一种合法的方法。有人可以告诉我我在这里缺少什么吗?
修改代码以使用 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)
})
}
创建路由器并向路由器注册处理程序。为 IndexHandler 添加 parameters 参数,使该函数与 httprouter 兼容。
router := httprouter.New()
router.GET("/", IndexHandler)
使用新版本的 ServeHTTPIterator 封装路由器。
httpServer.Handler = ServeHTTPIterator(router, preMiddle...)
进行这些更改后,日志将在调用路由器之前写入。
您可以实现它,而不是在您的 serveIterator 函数中传播中间件,期望像这样应用中间件片段:go playground
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
}