How middleware works
In fact, we’re actually already using some middleware in our application — the http.StripPrefix() function from serving static files, which removes a specific prefix from the request’s URL path before passing the request on to the file server.
The pattern
The standard pattern for creating your own middleware looks like this:
func myMiddleware(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { // TODO: Execute our middleware logic here... next.ServeHTTP(w, r) } return http.HandlerFunc(fn) }
The code itself is pretty succinct, but there’s quite a lot in it to get your head around.
- The myMiddleware() function is essentially a wrapper around the next handler, which we pass to it as a parameter.
- It establishes a function fn which closes over the next handler to form a closure. When fn is run it executes our middleware logic and then transfers control to the next handler by calling it’s ServeHTTP() method.
- Regardless of what you do with a closure it will always be able to access the variables that are local to the scope it was created in — which in this case means that fn will always have access to the next variable.
- In the final line of code, we then convert this closure to a http.Handler and return it using the http.HandlerFunc() adapter.
If this feels confusing, you can think of it more simply: myMiddleware() is a function that accepts the next handler in a chain as a parameter. It returns a handler which executes some logic and then calls the next handler.
Simplifying the middleware
A tweak to this pattern is to use an anonymous function inside myMiddleware() middleware, like so:
func myMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // TODO: Execute our middleware logic here... next.ServeHTTP(w, r) }) }
Positioning the middleware
It’s important to explain that where you position the middleware in the chain of handlers will affect the behavior of your application.
If you position your middleware before the servemux in the chain then it will act on every request that your application receives.
myMiddleware → servemux → application handler
A good example of where this would be useful is middleware to log requests — as that’s typically something you would want to do for all requests.
Alternatively, you can position the middleware after the servemux in the chain — by wrapping a specific application handler. This would cause your middleware to only be executed for a specific route.
servemux → myMiddleware → application handler
An example of this would be something like authorization middleware, which you may only want to run on specific routes.
标签:Web,http,middleware,next,Application,myMiddleware,handler,Go,your From: https://www.cnblogs.com/zhangzhihui/p/18397194