Golang study notes-A brief analysis of the standard library "Net/http" and the self-made Simple routing framework

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

Original link: http://targetliu.com/golang-http-router/

Still on the way to go, I used PHP to eat over-reliance on the framework of the loss. Now when you learn go, you decide to start with the basics and learn from the standard library.

SOURCE Analysis

We know that the simplest way to build HTTP server code is basically this:

http.HandleFunc('/', func(w http.ResponseWriter, r *http.Request){    fmt.Fprint(w, "Hello world")})http.ListenAndServe(":8080", nil)

This will successfully establish a listening 8080 port of the HTTP server, when access to the output Hello world

Let's HandleFunc take a look at what we've done:

func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {    DefaultServeMux.HandleFunc(pattern, handler)}

Here we continue to DefaultServeMux register the route by invoking the HandleFunc method, this DefaultServeMux again He Shan:

type ServeMux struct {    mu    sync.RWMutex    m     map[string]muxEntry    hosts bool // whether any patterns contain hostnames}type muxEntry struct {    explicit bool    h        Handler    pattern  string}// NewServeMux allocates and returns a new ServeMux.func NewServeMux() *ServeMux { return new(ServeMux) }// DefaultServeMux is the default ServeMux used by Serve.var DefaultServeMux = &defaultServeMuxvar defaultServeMux ServeMux

DefaultServeMuxis net/http a default type provided by the package ServeMux , which ServeMux implements the Handler interface.

To find out, the HTTP server received a request by go c.serve(ctx) opening goroutine processing the request, in this process called the Handler interface function ServeHTTP to do further processing (such as matching methods, links, etc.).

So, we can understand ServeMux that it's net/http a built-in routing feature.

Continue to HandleFunc come back to:

func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {    mux.Handle(pattern, HandlerFunc(handler))}

ServeMuxHandleFuncmethod converts our incoming route-specific implementation function into a HandlerFunc type and registers it with a Handle route. This HandlerFunc type also implements the Handler interface:

type HandlerFunc func(ResponseWriter, *Request)// ServeHTTP calls f(w, r).func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {    f(w, r)}

Finally to Handle this method, the Handle method by the pattern path and the implementation of the Handler interface method one by one corresponding to the save to ServeMux the map[string]muxEntry next request when the call. Therefore, you can also Handle register a route by passing directly to a Handler method that implements the interface.

At this point, net/http the registration process for the default route in the package has basically gone.

As for the routing call at the time of the request, remember to ServeHTTP find map the corresponding path in the lookup and call the relevant method.

Home-made routing

Through the above analysis, we can leaf out and implement our own routing function.

package routeimport (    "net/http"    "strings")//返回一个Router实例func NewRouter() *Router {    return new(Router)}//路由结构体,包含一个记录方法、路径的maptype Router struct {    Route map[string]map[string]http.HandlerFunc}//实现Handler接口,匹配方法以及路径func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {    if h, ok := r.Route[req.Method][req.URL.String()]; ok {        h(w, req)    }}//根据方法、路径将方法注册到路由func (r *Router) HandleFunc(method, path string, f http.HandlerFunc) {    method = strings.ToUpper(method)    if r.Route == nil {        r.Route = make(map[string]map[string]http.HandlerFunc)    }    if r.Route[method] == nil {        r.Route[method] = make(map[string]http.HandlerFunc)    }    r.Route[method][path] = f}

Use:

r := route.NewRouter()r.HandleFunc("GET", "/", func(w http.ResponseWriter, r *http.Request) {    fmt.Fprint(w, "Hello Get!")})r.HandleFunc("POST", "/", func(w http.ResponseWriter, r *http.Request) {    fmt.Fprint(w, "hello POST!")})http.ListenAndServe(":8080", r)

This example is just a simple function implementation of leaf out.

A complete routing framework should contain more complex matching, error detection and so on, you can try to try it yourself.

Reading the source code and repeating the wheel are all ways to learn.

Finally, you are welcome to follow my blog http://targetliu.com/

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.