golang高性能树状结构HTTP路由插件库httptreemux的使用

Golang高性能树状结构HTTP路由插件库httptreemux的使用

httptreemux是一个高速、灵活的基于树的Go语言HTTP路由器,它受到Julien Schmidt的httprouter启发,但实现方式有所不同。

安装

使用Go Modules安装:

import "github.com/dimfeld/httptreemux/v5"

基本使用示例

package main

import (
	"fmt"
	"net/http"
	"github.com/dimfeld/httptreemux/v5"
)

func main() {
	router := httptreemux.New()
	
	// 简单路由
	router.GET("/", func(w http.ResponseWriter, r *http.Request, params map[string]string) {
		fmt.Fprint(w, "首页")
	})
	
	// 带参数的路由
	router.GET("/user/:name", func(w http.ResponseWriter, r *http.Request, params map[string]string) {
		name := params["name"]
		fmt.Fprintf(w, "用户名: %s", name)
	})
	
	// 路由组
	api := router.NewGroup("/api")
	api.GET("/v1/users", func(w http.ResponseWriter, r *http.Request, params map[string]string) {
		fmt.Fprint(w, "API v1 用户列表")
	})
	
	http.ListenAndServe(":8080", router)
}

上下文支持示例

httptreemux支持使用标准http.HandlerFunc和context:

router := httptreemux.NewContextMux()

router.GET("/:page", func(w http.ResponseWriter, r *http.Request) {
	params := httptreemux.ContextParams(r.Context())
	page := params["page"]
	
	// 打印 GET /:page page=...
	fmt.Fprintf(w, "GET /%s", page)
})

group := router.NewGroup("/api")
group.GET("/v1/:id", func(w http.ResponseWriter, r *http.Request) {
	ctxData := httptreemux.ContextData(r.Context())
	params := ctxData.Params()
	id := params["id"]
	
	// 获取匹配的路由路径
	routePath := ctxData.Route()
	
	// 打印 GET /api/v1/:id id=...
	fmt.Fprintf(w, "GET %s id=%s", routePath, id)
})

路由规则

httptreemux支持以下路由模式:

  • /post/all - 静态路径
  • /post/:postid - 单段参数
  • /post/:postid/page/:page - 多段参数
  • /images/*path - 通配符路径
  • /favicon.ico - 静态文件
  • /:year/:month/ - 日期参数
  • /:page - 单参数

特殊字符处理

要使用:*作为路径段的开头,需要用反斜杠转义:

router.GET("/foo/\\*starToken", handler) // 匹配 /foo/*starToken
router.GET("/foo/star*inTheMiddle", handler) // 匹配 /foo/star*inTheMiddle

路由优先级

  1. 静态路径段优先级最高
  2. 通配符第二
  3. 最后是通配所有规则

中间件支持

虽然httptreemux本身不提供中间件,但支持使用中间件链:

router := httptreemux.New()

// 简单的日志中间件
router.Use(func(next httptreemux.HandlerFunc) httptreemux.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request, params map[string]string) {
		fmt.Printf("请求: %s %s\n", r.Method, r.URL.Path)
		next(w, r, params)
	}
})

router.GET("/", homeHandler)

注意事项

  • 项目已不再维护
  • 通配符路径不会匹配空字符串
  • 默认情况下会处理尾部斜杠重定向
  • 支持不区分大小写的路由

httptreemux提供了高性能的路由功能,同时保持了简单易用的特点,是构建Go Web应用的优秀选择。


更多关于golang高性能树状结构HTTP路由插件库httptreemux的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang高性能树状结构HTTP路由插件库httptreemux的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang高性能树状HTTP路由库httptreemux使用指南

httptreemux是一个基于基数树(radix tree)实现的高性能HTTP请求路由器,它比标准库的http.ServeMux和许多其他路由器性能更高,同时提供了灵活的路由功能。

主要特点

  1. 高性能:基于基数树实现,路由查找速度快
  2. 轻量级:代码简洁,依赖少
  3. 支持RESTful路由:支持:param*wildcard参数
  4. 中间件支持:可以方便地添加中间件
  5. 分组路由:支持路由分组管理

安装

go get github.com/dimfeld/httptreemux/v5

基本使用示例

package main

import (
	"fmt"
	"net/http"
	"log"
	"github.com/dimfeld/httptreemux/v5"
)

func main() {
	router := httptreemux.New()
	
	// 基本路由
	router.GET("/", func(w http.ResponseWriter, r *http.Request, params map[string]string) {
		fmt.Fprint(w, "Hello, World!")
	})
	
	// 带参数的路由
	router.GET("/user/:name", func(w http.ResponseWriter, r *http.Request, params map[string]string) {
		fmt.Fprintf(w, "Hello, %s!", params["name"])
	})
	
	// 通配符路由
	router.GET("/static/*filepath", func(w http.ResponseWriter, r *http.Request, params map[string]string) {
		fmt.Fprintf(w, "Requested file: %s", params["filepath"])
	})
	
	log.Println("Server starting on :8080...")
	log.Fatal(http.ListenAndServe(":8080", router))
}

路由参数

httptreemux支持两种参数形式:

  1. 命名参数:param形式,匹配单个路径段
  2. 通配符*wildcard形式,匹配剩余所有路径
router.GET("/product/:category/:id", func(w http.ResponseWriter, r *http.Request, params map[string]string) {
	category := params["category"]
	id := params["id"]
	fmt.Fprintf(w, "Category: %s, ID: %s", category, id)
})

router.GET("/download/*path", func(w http.ResponseWriter, r *http.Request, params map[string]string) {
	path := params["path"]
	fmt.Fprintf(w, "Downloading: %s", path)
})

路由分组

httptreemux支持路由分组,便于管理具有相同前缀的路由:

func main() {
	router := httptreemux.New()
	
	api := router.NewGroup("/api")
	api.GET("/version", apiVersionHandler)
	
	users := api.NewGroup("/users")
	users.GET("/", listUsersHandler)
	users.POST("/", createUserHandler)
	users.GET("/:id", getUserHandler)
	users.PUT("/:id", updateUserHandler)
	users.DELETE("/:id", deleteUserHandler)
	
	http.ListenAndServe(":8080", router)
}

中间件支持

虽然httptreemux本身不直接提供中间件机制,但可以很容易地与标准库中间件模式结合使用:

func loggingMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Printf("%s %s", r.Method, r.URL.Path)
		next.ServeHTTP(w, r)
	})
}

func main() {
	router := httptreemux.New()
	// 配置路由...
	
	// 应用中间件
	handler := loggingMiddleware(router)
	
	http.ListenAndServe(":8080", handler)
}

自定义NotFound和MethodNotAllowed处理

router.NotFoundHandler = func(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusNotFound)
	fmt.Fprint(w, "Custom 404 page")
}

router.MethodNotAllowedHandler = func(w http.ResponseWriter, r *http.Request, methods map[string]httptreemux.HandlerFunc) {
	w.WriteHeader(http.StatusMethodNotAllowed)
	fmt.Fprint(w, "Method not allowed")
}

性能比较

httptreemux在路由查找性能上表现优异,特别适合有大量路由的场景。与标准库http.ServeMux相比:

  1. 路由查找时间为O(k)(k是路径长度),而非O(n)
  2. 内存占用更优,因为共享公共前缀
  3. 特别适合RESTful API服务

注意事项

  1. 路由匹配是区分大小写的
  2. 参数和通配符名称在同一个路由中必须唯一
  3. 通配符路由应该放在最后,因为它们会匹配所有剩余路径

httptreemux是一个简单而高效的HTTP路由器,特别适合需要高性能路由的Go Web应用程序。它的API设计简洁,学习曲线平缓,是标准库http.ServeMux的一个很好的替代品。

回到顶部