Go Echo 学习笔记(八)路由机制


Echo路由机制

作为一个号称轻快好省的服务端框架,Echo凭借其出色的路由查询速度在一众基于 Go 语言的服务器框架中脱颖而出。那么Echo是如何完成一次路由映射的又是如何保证路由映射的速度,本文就带大家来探索下Echo的路由机制。

简介

Echo 的路由之所以查询的速度非常快的原因主要有如下原因:

  • Echo 的路由映射是基于RadixTree(基数树,压缩前缀树)构建的,保证路由的查询速度。
  • Echo 的路由利用sync pool(同步池)来重用内存从而实现零动态内存分配,达到没有GC开销的效果。

路由匹配

Echo 中一个固定的路由可以指定到一个专门的 Handler 处理函数上,该函数便用来专门处理该请求的内容。

  • 利用 Echo.Any(path string, h Handler) 方法可以给所有的路由请求注册同一个请求处理函数。
  • 利用 Echo.Match(methods []string, path string, h Handler) 方法可以为一个路由请求注册多个请求处理函数。

对于 Echo 中的路由字符来说,可以按照通配符来设计路由来匹配多种请求,例如 /users/*路由可以匹配如下的请求:

  • /users/
  • /users/1
  • /users/1/files/1
  • /users/anything...

但是假如一个 http 请求路径匹配多个定义的 url 路径,Echo 框架会按定义的路由顺序匹配,先匹配到那个就用那个定义。

路由分组

Echo 利用 Echo#Group(prefix string, m ...Middleware) *Group 将具有公共前缀的路由进行分组处理,分组之后的路由可以利用中间件来进行相应的处理:

g := e.Group("/admin")
g.Use(middleware.BasicAuth(func(username, password string, c echo.Context) (bool, error) {
	if username == "joe" && password == "secret" {
		return true, nil
	}
	return false, nil
}))

路由命名

每一个将请求路径与处理程序注册完成之后的路由都会返回一个 Route 类型的对象,可以为该对象指定对应的名称:

route := e.POST("/users", func(c echo.Context) error {
})
route.Name = "create-user"

// or using the inline syntax
e.GET("/users/:id", func(c echo.Context) error {
}).Name = "get-user"

URL生成

可以利用 Echo#URI(handler HandlerFunc, params ...interface{}) 为一个绑定了请求路径的 handler 处理器生成一个添加了指定 params 参数的 URL,而集中所有URI模式有助于简化应用程序重构:

// Handler
h := func(c echo.Context) error {
	return c.String(http.StatusOK, "OK")
}

// Route
e.GET("/users/:id", h)

// 生成url:/users/1
e.URI(h, 1)

另一个方法:Echo#Reverse(name string, params ...interface{}) 也可以生成相应的 URL ,只不过该方法传入的是一个 Route 路由的名称(需要用到路由命名):

// Handler
h := func(c echo.Context) error {
	return c.String(http.StatusOK, "OK")
}

// Route
e.GET("/users/:id", h).Name = "foobar"

// 生成url:/users/1234
e.Reverse("foobar", 1234)

List Routes

利用 Echo#Routes() []*Route 方法可以获取到当前所有注册的路由,返回路由的 method、path、name信息

e.Routes()