目录
gorilla/mux与http.SeverMux
gorilla/mux的主要特点
使用实例
源码分析
- mux.go
- route.go
总结
参考资料
gorilla/mux与http.SeverMux
golang自带的http.SeverMux路由实现简单,本质是一个map[string]Handler,是请求路径与该路径对应的处理函数的映射关系。实现简单功能也比较单一:
- 不支持正则路由, 这个是比较致命的
- 只支持路径匹配,不支持按照Method,header,host等信息匹配,所以也就没法实现RESTful架构
而gorilla/mux是一个强大的路由,小巧但是稳定高效,不仅可以支持正则路由还可以按照Method,header,host等信息匹配,可以从我们设定的路由表达式中提取出参数方便上层应用,而且完全兼容http.ServerMux
gorilla/mux的主要特点
- 实现了http.Handler接口,因此可以兼容标准的http.ServeMux。
- 可以匹配URL 主机,路径,路径前缀,头部,查询值,HTTP方法或用户自定义的匹配。
- URL 主机、路径、查询值可以使用正则表达式匹配。
- 可以使用子路由。只有当父路由匹配成功后,子路由才会进行匹配。这种嵌套的路由可以加快匹配速度。
使用实例
package main
import (
"net/http"
"log"
"github.com/gorilla/mux"
)
func YourHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Gorilla!\n"))
}
func main() {
r := mux.NewRouter()
// Routes consist of a path and a handler function.
r.HandleFunc("/", YourHandler)
// Bind to a port and pass our router in
log.Fatal(http.ListenAndServe(":8000", r))
}
源码分析
主要是四个模块:mux.go,route.go,middleware.go,regexp.go,其中,middleware.go是中间件的相关定义,regexp.go是正则处理的相关定义。我们主要分析mux.go和route.go。
1 mux.go
mux是整个模块的入口。
NewRouter创建router实例:
// NewRouter returns a new router instance.
func NewRouter() *Router {
return &Router{
namedRoutes: make(map[string]*Route), KeepContext: false}
}
我们看看router的数据结构:
type Router struct {
// Configurable Handler to be used when no route matches.
NotFoundHandler http.Handler
// Configurable Handler to be used when the request method does not match the route.
MethodNotAllowedHandler http.Handler
// Parent route, if this is a subrouter.
parent parentRoute
// Routes to be matched, in order.
routes []*Route
// Routes by name for URL building.
namedRoutes map[string]*Route
// See Router.StrictSlash(). This defines the flag for new routes.
strictSlash bool
// See Router.SkipClean(). This defines the flag for new routes.
skipClean bool
// If true, do not clear the request context after handling the request.
// This has no effect when go1.7+ is used, since the context is stored
// on the request itself.
KeepContext bool
// see Router.UseEncodedPath(). This defines a flag for all routes.
useEncodedPath bool
// Slice of middlewares to be called after a match is found
middlewares []middleware
}
主要关注 routes 、parent 以及三个 flag:strictSlash、skipClean、useEncodedPath。
路由信息存放在routes中;如果只关心流程,可以先忽略这些flag。
strictSlash
// StrictSlash defines the trailing slash behavior for new routes. The initial
// value is false.
//
// When true, if the route path is "/path/", accessing "/path" will perform a redirect
// to the former and vice versa. In other words, your application will always
// see the path as specified in the route.
//
// When false, if the route path is "/path", accessing "/path/" will not match
// this route and vice versa.
//
// The re-direct is a HTTP 301 (Moved Permanently). Note that when this is set for
// routes with a non-idempotent method (e.g. POST, PUT), the subsequent re-directed
// request will be made as a GET by most clients. Use middleware or client settings
// to modify this behaviour as needed.
//
// Special case: when