Usually a simple http service framework is to register a bunch of routes and then call different logic to process them according to the routing.
But in fact, there may be some uniform processing involved in almost all routes, such as logging, such as permissions and so on.
So it's a good idea to do a pretreatment in the middle at this time.
Define a middleware unit:
1 package main 2 3 import ( 4 "net/http" 5 ) 6 7 // AdaptorHandle middleware func type 8 type AdaptorHandle func(w http.ResponseWriter, r *http.Request) (next bool, err error) 9 10 // MiddleWareAdaptor router middlewares mapped by url 11 type MiddleWareAdaptor struct { 12 URLs map[string][]AdaptorHandle 13 } 14 15 // MakeMiddleWareAdaptor make a middleware adaptor 16 func MakeMiddleWareAdaptor() *MiddleWareAdaptor { 17 mwa := &MiddleWareAdaptor{ 18 URLs: make(map[string][]AdaptorHandle), 19 } 20 21 return mwa 22 } 23 24 // Regist regist a adaptor 25 func (mw *MiddleWareAdaptor) Regist(url string, Adaptor ...AdaptorHandle) { 26 for _, adp := range Adaptor { 27 mw.URLs[url] = append(mw.URLs[url], adp) 28 // mw.URLs[url] = adp 29 } 30 } 31 32 // Exec exec middleware adaptor funcs... 33 func (mw *MiddleWareAdaptor) Exec(url string, w http.ResponseWriter, r *http.Request) (bool, error) { 34 if adps, ok := mw.URLs[url]; ok { 35 for _, adp := range adps { 36 if next, err := adp(w, r); !next || (err != nil) { 37 return next, err 38 } 39 } 40 } 41 return true, nil 42 }
Then the routing function is wrapped up with middleware entries:
1 func middlewareHandler(next http.Handler) http.Handler { 2 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 3 // before call handler 4 start := time.Now() 5 do, _ := mwa.Exec(r.URL.Path, w, r) // exec middleware 6 // call next handler 7 if do { 8 log.Println("middleware done. next...") 9 next.ServeHTTP(w, r) 10 } else { 11 log.Println("middleware done.break...") 12 } 13 // after call handle 14 log.Printf("Comleted %s in %v", r.URL.Path, time.Since(start)) 15 }) 16 } 17 18 mux.Handle("/", middlewareHandler(&uPlusRouterHandler{})) 19 20 type uPlusRouterHandler struct { 21 } 22 23 func (rh *uPlusRouterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 24 ... 25 }
Finally, register the middleware you need:
mwa = MakeMiddleWareAdaptor() // init middleware mwa.Regist("/", testMWAfunc, testMWAfunc2) // regist middleware ... func testMWAfunc(w http.ResponseWriter, r *http.Request) (bool, error) { log.Println("I am the first Middleware...") log.Printf("Started %s %s", r.Method, r.URL.Path) return true, nil } func testMWAfunc2(w http.ResponseWriter, r *http.Request) (bool, error) { log.Println("I am the second Middleware...") return false, nil // return false,break follow-up actions. }
Although the code is simple, record a thought.