Go Language Classic library usage analysis (vi) | Negroni Middleware (ii)

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Go Language Classic library usage analysis, not to be continued, welcome to sweep code attention flysnow_org to the public number or website http://www.flysnow.org/, the first time to see the following series. If you feel helpful, share it with your friends and thank you for your support.

Previous Go Language Classic library usage analysis (v) | Negroni Middleware (i) introduces the use of Negroni intermediate and some introduction, such as how to add intermediate, middleware, such as routing. This article mainly talk about the principle, such as how to build the intermediate processing chain, how to write their own middleware and so on.

Negroni Handler Processor

Essentially Negroni an HTTP Handler, because he implements the HTTP Handler interface, so he can be http.ListenAndServe used, followed by a set Negroni of their own internal Handler processing chain, through which they can achieve the purpose of processing HTTP requests, The processors in these handler processing chains are middleware.

123
 func(n *negroni)servehttp(rw http. Responsewriter, R *http. Request)  {n.middleware.servehttp (Newresponsewriter (rw), R)}

The above code, is the implementation of the Negroni HTTP handler, so that the label Library and the HTTP seamless integration. Implemented HTTP Handler, for HTTP request, there is a unified portal, all the HTTP Requet processing, will be Negroni passed through the method to the ServeHTTP Negroni internal registration of the middleware.

12345
type Interface {servehttp (rw http. Responsewriter, R *http. Request, next http. Handlerfunc)}typefunc(rw http. Responsewriter, R *http. Request, next http. Handlerfunc) 

This is Negroni your own definition of the handler processor, which is very similar to the HTTP handler, the only difference is that one more next parameter, which next is the core of the middleware processing chain.

How to build a middleware processing chain

We already know that we Negroni have our own set of handler middleware processing chain, so this processing chain and how to build it? To solve this riddle, let's first look at Negroni how to register a middleware.

12345678910111213
type struct {Middleware Middlewarehandlers   []handler}func(n *negroni)use(Handler Handler)  {if  Nil {panic("Handler cannot be nil"append(n.handlers, handler) N.middleware = Build (N.handlers)}

When we call the Use method, we will put Negroni the Handler in its own handlers field, this is a slice type field, can save our stored Negroni Handler. The middleware processing chain is built based on the slice that holds the Negroni handler middleware .

1234
type struct {handler Handlernext    *middleware}

middlewareStructs have very simple, there are two fields, one is the current Negroni Handler, and the other is the middleware pointer down one next . With such a middleware struct, you can build a perfect middleware processing chain.

1234567891011121314151617181920
 func build(handlers []handler) middleware {varNext middlewareif Len(handlers) = =0{returnVoidmiddleware ()}Else if Len(handlers) >1{next = Build (handlers[1:])}Else{next = Voidmiddleware ()}returnmiddleware{handlers[0], &next}} func voidmiddleware() middleware {returnMiddleware{handlerfunc ( func(rw http. Responsewriter, R *http. Request, next http. Handlerfunc) {}), &middleware{},}}

The above code is to construct a middleware processing chain logic, which is a recursive function, logic is relatively simple.

When the handlers argument is empty, voidMiddleware an empty one is returned directly from the function middleware .
When the handlers parameter has only 1 processors, the build is milldeware not next , so next it is obtained through the voidMiddleware function, and then generated by the return middleware{handlers[0], &next} composition middleware and returned.

The last situation is that there are more than 1 Negroni Handler, that through the build function loop recursion, starting from the 2nd Handler, continue to recursive processing, so the first added Negroni Handler will be placed in front of the middleware processing chain, It also means that it will be implemented as a priority.

How middleware is called

How can these middleware be called when the processor chain is built? In the previous chapters, we talked about the Negroni is an HTTP Handler, so the total entrance is in the ServeHTTP method.

123
 func(n *negroni)servehttp(rw http. Responsewriter, R *http. Request)  {n.middleware.servehttp (Newresponsewriter (rw), R)}

As can be seen from the above code, the method is called middleware.ServeHTTP , which is the beginning of the implementation of the middleware.

123
 func(M middleware)servehttp(rw http. Responsewriter, R *http. Request)  {m.handler.servehttp (rw, R, m.next.servehttp)}

middleware.ServeHTTPThe current handler method in the method invocation middleware ServeHTTP executes the middleware processing logic we write ourselves.

12345
type  func(rw http. Responsewriter, R *http. Request, next http. Handlerfunc)func(H handlerfunc)servehttp(rw http. Responsewriter, R *http. Request, next http. Handlerfunc) {h (RW, R, next)}

Back here again, Handler's method of ServeHTTP execution, essentially the execution of our own defined Negroni. Handlerfunc.

The current middleware is executed, so how is the next trigger? This is the next parameter in our own definition of the middleware function. After we have finished processing our middleware, we need to call the next function to continue executing the next middleware if we feel it is necessary, and if we do not call the next function, then the processing of the middleware chain is broken. See an example of a custom middleware.

1234567
func (l *logger) servehttp (rw http.) Responsewriter, R *http. Request, next http. Handlerfunc)  {start: = time. Now () Next (RW, R)//Omit extraneous code }

This is the implementation of the Negroni built-in log middleware, and you can see that it calls the next(rw, r) function, allowing the middleware processing chain to continue executing. next(rw, r)What is this? Actually, we talked about it earlier.

123
 func(M middleware)servehttp(rw http. Responsewriter, R *http. Request)  {m.handler.servehttp (rw, R, m.next.servehttp)}

nextFunction call, is the next middleware ServeHTTP call again, this is a recursive, but also the middleware processing chain design of the ingenious, flexible control, free choice whether to invoke the next middleware.

Go Language Classic library usage analysis, not to be continued, welcome to sweep code attention flysnow_org to the public number or website http://www.flysnow.org/, the first time to see the following series. If you feel helpful, share it with your friends and thank you for your support.

Conversion between HTTP handler and Negroni handler

When we first introduced Negroni, we know that it is compatible with HTTP handler, Negroni can directly convert the HTTP handler to Negroni HTTP, so that we can use HTTP handler directly as a Negroni middleware, Let's see how it's converted.

1234567
func (n *negroni) Usehandler (Handler http. Handler)  {n.use (Wrap (Handler)}}func(n *negroni)usehandlerfunc  func (rw http.) Responsewriter, R *http. Request) {n.usehandler (http. Handlerfunc (Handlerfunc))}

Negroni provides two methods, respectively compatible http.Handler and http.HandlerFunc , UseHandlerFunc method is essentially called UseHandler method, the UseHandler focus of the method implementation is Wrap(handler) that it completes the HTTP. Handler to Negroni.handler conversion.

123456
func Wrap (Handler http. Handler)Handler  {return handlerfunc (func(rw http. Responsewriter, R *http. Request, next http. Handlerfunc)  {handler. Servehttp (RW, R) Next (rw, R)})}

This function is essentially the implementation of the Negroni middleware, and its code logic is to execute the implementation of the http.Handler middleware first and then invoke the next(rw, r) next middleware.

Introduction to built-in middleware

Negroni has several middleware built into it, and when we Classic create one through *Negroni the function, we have

123
func Classic () *Negroni  {return New (Newrecovery (), Newlogger (), Newstatic (http. Dir ("public"))}

NewRecovery, NewLogger and NewStatic is this several built-in middleware, are implemented Negroni handler middleware, the specific source code you can see, here is not specifically introduced.

Write your own middleware

Writing their own middleware, in the Negroni can be used in two ways, one is http.Handler the way, the advantages of this approach is everyone is familiar with, and has been, the disadvantage is that you can not control the processing chain middleware, the default is to call the next middleware, we can not interrupt.

The other is the way it is implemented negroni.Handler , and this is the way Negroni recommends it.

123456789101112131415161718192021222324252627282930
//blog:www.flysnow.org//wechat:flysnow_org func main() {N: = Negroni. New () N.usefunc (Printauthorinfo) router:=http. Newservemux () router. Handle ("/", Handler ()) N.usehandler (router) n.run (": 1234")} func printauthorinfo(rw http. Responsewriter, R *http. Request, next http. Handlerfunc) {FMT. Println ("Blog:www.flysnow.org") FMT. Println ("wechat:flysnow_org") Next (Rw,r)} func handler() http. Handler {returnhttp. Handlerfunc (MyHandler)} func myhandler(rw http. Responsewriter, R *http. Request) {rw. Header (). Set ("Content-type","Text/plain") Io. WriteString (RW,"Hello World")}

We printAuthorInfo implement a Negroni handler middleware through the function, which is very simple, just prints some author information, then executes the next middleware.

When using, we n.UseFunc(printAuthorInfo) register this middleware, we start the service, access, http://localhost:1234 you can see the following information in the console:

12
Blog: www.flysnow.orgWechat:flysnow_org

For example, I this middleware is relatively simple, we can meet their own needs to achieve their own business middleware.

Some middleware introduction

GitHub has a lot of third-party middleware developed specifically for Negroni to match the use of Negroni, such as gzip, oauth2.0, etc., and you can view the third party's intermediate list by following the links below:

Https://github.com/urfave/negroni#third-party-middleware

Summary

Here, Negroni this middleware analysis is over, there may be some no analysis, such as With methods, Run methods, they are relatively simple, we can see.

Another important thing is that NewResponseWriter this function, which is the wrapper for us now NewResponseWriter , adds some additional information to this knowledge point I used in this article Go Language Classic Library analysis (iv) | Gorilla Handlers source code Implementation analysis of the article in detail, it will not repeat the introduction.

HTTP middleware, is an HTTP interceptor, Negroni for the interceptor processing better, can be flexible control, whether terminal, etc., reasonable use of Negroni, you can make more effort.

Go Language Classic library usage analysis, not to be continued, welcome to sweep code attention flysnow_org to the public number or website http://www.flysnow.org/, the first time to see the following series. If you feel helpful, share it with your friends and thank you for your support.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.