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/73https://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

3 回复

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场景。

回到顶部