golang httprouter详解

922 阅读2分钟
  1. httprouter是什么?

    HttpRouter是Go的轻量级高性能HTTP请求路由器(也称为多路复用器或简称mux)。

    与Go的net/http包的默认mux相比,这个路由器支持路由模式中的变量,并与请求方法进行匹配。它的伸缩性也更好。

    该路由器为高性能和小内存占用进行了优化。即使是很长的路径和大量的路径,它也能很好地扩展。采用一种压缩的动态基树结构(radix tree)进行有效匹配。

    市场上大部分http框架使用的路由底层实现方式都是radix tree

  2. httprouter 主要特点:

    明确的路由匹配,一个path对应一个Handler

    不用关心/,例如当请求/foo/时,此path不存在,如果有/foo会自动302转发

    path自动修正,例如//foo转化成/foo

    path中携带参数。

  3. 使用

     package main
    
     import (
         "fmt"
         "net/http"
         "log"
    
         "github.com/julienschmidt/httprouter"
     )
    
     func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
         fmt.Fprint(w, "Welcome!\n")
     }
    
     func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
         fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
     }
    
     func main() {
         router := httprouter.New()
         router.GET("/", Index)
         router.GET("/hello/:name", Hello)
    
         log.Fatal(http.ListenAndServe(":8080", router))
     }
    
  4. 底层实现

    httprouter由router.go、tree.go、path.go 组成,主要实现由Routernode结构体实现.

    • node
    节点类型:
    
    const (
        static nodeType = iota // 非根节点的普通字符串节点,默认
        root   //根节点
        param   //参数节点,例如 :id
        catchAll  //通配符节点,例如 *anyway
     )
     
     节点结构体:
     type node struct {
        path      string//到达节点时,所经过的字符串路径
        wildChild bool//子节点中是否包含参数
        nType     nodeType//节点类型
        maxParams uint8//参数数量,最大255
        priority  uint32//优先级
        indices   string//子节点索引,当子节点为非参数类型,即本节点的 wildChild 为 false 时,会将每个子节点的首字母放在该索引数组。说是数组,实际上是个 string。
        children  []*node//子节点切片
        handle    Handle//path对于操作
     }
     
     node主要方法:
         addRoute:添加路由
             func (n *node) addRoute(path string, handle Handle)
         getValue:通过给定path返回具体操作Handle
            func (n *node) getValue(path string) (handle Handle, p Params, tsr bool)
            
    
    • Router

        type Router struct {    
           trees map[string]*node
           RedirectTrailingSlash bool
           RedirectFixedPath bool
           HandleMethodNotAllowed bool
           HandleOPTIONS bool
           GlobalOPTIONS http.Handler
           globalAllowed string
           NotFound http.Handler
           MethodNotAllowed http.Handler
           PanicHandler func(http.ResponseWriter, *http.Request, interface{})
        }
        
        trees:HTTP methods node树
        RedirectTrailingSlash:是否重定向使用斜杠"/",如"/foo/"在查找不到情况下,会重定向到"/foo"
        RedirectFixedPath:是否重定向修复请求路径
        HandleMethodNotAllowed:是否处理不被允许的方法(MethodNotAllowed)
        PanicHandler:自定义异常处理方法
        
      

      Router主要方法

        Handle方法用于添加路由
            func (r *Router) Handle(method, path string, handle Handle)
                Handle是GET、HEAD、OPTIONS、POST、PUT、PATCH、DELETE别名调用
        ServeHTTP:使用路由器实现http.Handler接口
             func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)
      

      Router中使用的node 类型都是root(根节点)