package main import ( "context" "fmt" "github.com/gorilla/mux" "log" "net/http" ) type FilterFunc func(http.Handler) http.Handler func FilterChain(filters ...FilterFunc) FilterFunc { return func(next http.Handler) http.Handler { for i := len(filters) - 1; i >= 0; i-- { next = filters[i](next) } return next } } type Context struct { context.Context req *http.Request res http.ResponseWriter } func (c *Context) String(code int, str string) error { c.res.WriteHeader(code) _, err := c.res.Write([]byte(str)) return err } func (c *Context) Result(code int, str string) error { c.res.WriteHeader(code) _, err := c.res.Write([]byte(str)) return err } type HandleFunc func(Context) error func IndexPage(ctx Context) error { //return errors.New("xxx") return ctx.String(200, "hello index") } func Logger() HandleFunc { return func(c Context) error { return nil } } func main() { app := mux.NewRouter() next := http.Handler(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { ctx := Context{ res: res, req: req, } h := Logger() h(ctx) if err := IndexPage(ctx); err != nil { ctx.Result(500, "err:"+err.Error()) } })) next = FilterChain(func(handler http.Handler) http.Handler { return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { fmt.Println("start") handler.ServeHTTP(writer, request) fmt.Println("end") }) })(next) app.Handle("/", next).Methods("GET") srv := http.Server{ Addr: ":9999", Handler: app, } log.Fatal(srv.ListenAndServe()) }