-
httprouter是什么?
HttpRouter是Go的轻量级高性能HTTP请求路由器(也称为多路复用器或简称mux)。
与Go的net/http包的默认mux相比,这个路由器支持路由模式中的变量,并与请求方法进行匹配。它的伸缩性也更好。
该路由器为高性能和小内存占用进行了优化。即使是很长的路径和大量的路径,它也能很好地扩展。采用一种压缩的动态基树结构(radix tree)进行有效匹配。
市场上大部分http框架使用的路由底层实现方式都是radix tree
-
httprouter 主要特点:
明确的路由匹配,一个
path对应一个Handler。不用关心
/,例如当请求/foo/时,此path不存在,如果有/foo会自动302转发path自动修正,例如//foo转化成/foo。path中携带参数。 -
使用
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)) } -
底层实现
httprouter由router.go、tree.go、path.go 组成,主要实现由
Router和node结构体实现.- 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(根节点)