Golang中最灵活的路由器/muxer推荐
Golang中最灵活的路由器/muxer推荐 目前我99%的项目都是API相关的/REST|RPC导向/,比如不需要模板。我认为Golang非常适合我的需求,即使不是最佳选择。
目前我正在尝试不同的路由器/多路复用器。试过gorilla/mux、httprouter、核心net/http以及几个框架 - beego、gin、buffalo、chi……其中一些内部已经使用了上述多路复用器/gin使用httprouter,buffalo使用gorilla/mux……
另外,我不太需要完整的Web框架。
我面临的问题是其中一些有限制 - 这里有一些例子:
在gin中我们不能这样写:
...
r.GET("/api/v1/order/:orderId/order_lines/:orderLineId", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "some message here",
})
})
r.GET("/api/v1/order/:orderId/order_lines/stats", func(c *gin.Context) {
c.JSON(200, gin.H{
"stats": "some other message here",
})
})
...
我们就是不能。
关于这个问题,我在这里找到了类似的内容 -> https://github.com/julienschmidt/httprouter/issues/73,https://github.com/julienschmidt/httprouter/issues/73#issuecomment-110228393 但问题仍然没有解决/实现。
在gorilla/mux中,如果你想要类似的功能,比如:
app.GET("/order/{id}", OrderFetchHandler)
app.GET("/order/stat", OrderStatHandler)
这样不太行。 应该这样写:
...
app.GET("/order/stat", OrderStatHandler)
app.GET("/order/{id}", OrderFetchHandler)
...
也就是说,静态路由应该放在带参数的路由之前。
想象一个拥有数十/数百个端点的项目……
目前我正在考虑chi:
r.Get("/api/v1/some_resource/{id}", func(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
w.Write([]byte("Id: " + id))
})
r.Get("/api/v1/some_resource/stats", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("/api/v1/some_resource/stats"))
})
无论定义顺序如何,哪个先定义都没关系,它都能正常工作。
任何建议都将不胜感激。
注意:我不需要"最快的"或"最酷的"。我需要的,尤其是在处理API类工作时,是限制最少的/特别是在URL模式/匹配方面没有限制的/,也就是最灵活的。
更多关于Golang中最灵活的路由器/muxer推荐的实战教程也可以访问 https://www.itying.com/category-94-b0.html
chi mux 支持正则表达式,因此您应该能够实现这个功能。
更多关于Golang中最灵活的路由器/muxer推荐的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
好的,正如我提到的,我正在测试chi路由库。 但是,还有其他没有这些限制的多路复用器吗?
对于API开发中路由灵活性的需求,我推荐使用chi路由器。它基于标准库的net/http构建,提供了出色的路由匹配能力,特别是在处理参数化路由与静态路径冲突时表现优秀。
chi的路由匹配算法采用深度优先搜索,能够智能区分相似路径,无需担心路由定义顺序。以下示例展示其灵活性:
package main
import (
"net/http"
"github.com/go-chi/chi/v5"
)
func main() {
r := chi.NewRouter()
// 静态路径和参数化路径可以任意顺序定义
r.Get("/api/v1/order/{orderId}/order_lines/stats", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("order lines stats"))
})
r.Get("/api/v1/order/{orderId}/order_lines/{orderLineId}", func(w http.ResponseWriter, r *http.Request) {
orderId := chi.URLParam(r, "orderId")
orderLineId := chi.URLParam(r, "orderLineId")
w.Write([]byte("order: " + orderId + ", line: " + orderLineId))
})
// 另一个例子:静态路由和参数路由的灵活处理
r.Get("/product/featured", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("featured products"))
})
r.Get("/product/{productId}", func(w http.ResponseWriter, r *http.Request) {
productId := chi.URLParam(r, "productId")
w.Write([]byte("product: " + productId))
})
http.ListenAndServe(":8080", r)
}
chi还支持路由组、中间件链和子路由,非常适合大型API项目:
func main() {
r := chi.NewRouter()
// API版本路由组
r.Route("/api/v1", func(r chi.Router) {
r.Get("/users/stats", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("users statistics"))
})
r.Get("/users/{userId}", func(w http.ResponseWriter, r *http.Request) {
userId := chi.URLParam(r, "userId")
w.Write([]byte("user: " + userId))
})
r.Get("/users/{userId}/posts/{postId}", func(w http.ResponseWriter, r *http.Request) {
userId := chi.URLParam(r, "userId")
postId := chi.URLParam(r, "postId")
w.Write([]byte("user: " + userId + ", post: " + postId))
})
})
http.ListenAndServe(":8080", r)
}
chi完全兼容net/http标准,不强制使用特定的上下文类型,可以通过chi.URLParam(r, "paramName")轻松获取路径参数。这种设计在保持高性能的同时,提供了最大的路由定义灵活性,特别适合复杂的REST API场景。

