gorouter

近來無事,仿httprouter造一輪子gorouter

gorouter 是一個(gè)輕便的HTTP API 路由庫(kù)。

項(xiàng)目創(chuàng)建背景

之前一直使用大名鼎鼎的 httprouter。但由于我寫的RESTful API不規(guī)范,導(dǎo)致存在一些路由沖突。例如github上討論的這個(gè)問題

r.GET("/teachers/list", func (c *gin.Context){})
r.GET("/teachers/:id/profile", func (c *gin.Context){})

Error:
[GIN-debug] GET /teachers/list --> main.func·001 (3 handlers)
[GIN-debug] GET /teachers/:id/profile --> main.func·002 (3 handlers)
panic: wildcard route ':id' conflicts with existing children in path '/teachers/:id/profile'

當(dāng)然我們可以把 GET /teachers/list 改成 GET /teachers。或者把 GET /teachers/:id/profile 改成 GET /teacher/:id/profile。 按照restful風(fēng)格應(yīng)該采用第一種,但有時(shí)候接口太多或者沒有嚴(yán)格按照restful風(fēng)格風(fēng)格就會(huì)導(dǎo)致路由沖突。所以我就偶爾我就會(huì)采用第二種,但第二種又會(huì)導(dǎo)致我沒辦法把兩個(gè)接口歸納在同一個(gè)group。gorouter就是為了解決這個(gè)問題。

用法


func main()  {

    router := gorouter.New()

    router.GET("/teachers/list", func(resp http.ResponseWriter, req *http.Request, params *gorouter.Param) {
        resp.Write([]byte("/teachers/list"))
    })

    router.GET("/teachers/:id/profiles", func(resp http.ResponseWriter, req *http.Request, params *gorouter.Param) {
        resp.Write([]byte(fmt.Sprintf("%s = %s", "id", params.GetValue("id"))))
    })

    router.GET("/teachers/:id/profiles/:id", func(resp http.ResponseWriter, req *http.Request, params *gorouter.Param) {
        resp.Write([]byte(fmt.Sprintf("id1 = %s; id2 = %s", params.Values[0], params.Values[1])))
    })

    http.ListenAndServe(":3001", router)

}

路由規(guī)則

gorouter 借鑒了httprouter的基數(shù)樹實(shí)現(xiàn)方法。但當(dāng)存在通配符和靜態(tài)路由都匹配url時(shí),優(yōu)先匹配靜態(tài)路由,如果匹配失敗則返回再去匹配通配符。

路由:
① GET /users/:id/name   
② GET /users/id/name

請(qǐng)求:
/users/id/name   匹配②
/users/idd/name  匹配①

Benchmark

引用echo的測(cè)試用例編寫了gorouter-example,跑了下基準(zhǔn)測(cè)試,感覺性能還不錯(cuò)。因?yàn)楣δ芎?jiǎn)單可能占些便宜。


goos: darwin
goarch: amd64
Benchmark_Echo_Static-8                30000         42460 ns/op        2413 B/op        157 allocs/op
Benchmark_Echo_GitHubAPI-8             20000         61322 ns/op        2496 B/op        203 allocs/op
Benchmark_Echo_GplusAPI-8             500000          3255 ns/op         173 B/op         13 allocs/op
Benchmark_Echo_ParseAPI-8             300000          5634 ns/op         323 B/op         26 allocs/op

Benchmark_Gorouter_Static-8            50000         29292 ns/op        1007 B/op        157 allocs/op
Benchmark_Gorouter_GitHubAPI-8         30000         58802 ns/op        5666 B/op        275 allocs/op
Benchmark_Gorouter_GplusAPI-8         500000          3164 ns/op         437 B/op         22 allocs/op
Benchmark_Gorouter_ParseAPI-8         300000          4543 ns/op         615 B/op         37 allocs/op

Benchmark_Gin_Static-8                 30000         52282 ns/op        8693 B/op        157 allocs/op
Benchmark_Gin_GitHubAPI-8              20000         79637 ns/op       10616 B/op        203 allocs/op
Benchmark_Gin_GplusAPI-8              300000          4409 ns/op         681 B/op         13 allocs/op
Benchmark_Gin_ParseAPI-8              200000          8040 ns/op        1421 B/op         26 allocs/op

Benchmark_Beego_Static-8               10000        198317 ns/op       76586 B/op       1099 allocs/op
Benchmark_Beego_GitHubAPI-8             5000        269359 ns/op       98868 B/op       1422 allocs/op
Benchmark_Beego_GplusAPI-8            100000         15628 ns/op        6356 B/op         91 allocs/op
Benchmark_Beego_ParseAPI-8             50000         29614 ns/op       12712 B/op        182 allocs/op

Benchmark_Httprouter_Static-8         100000         15696 ns/op        1006 B/op        157 allocs/op
Benchmark_Httprouter_GitHubAPI-8       50000         38157 ns/op       15583 B/op        370 allocs/op
Benchmark_Httprouter_GplusAPI-8      1000000          1874 ns/op         735 B/op         24 allocs/op
Benchmark_Httprouter_ParseAPI-8       500000          2866 ns/op         830 B/op         42 allocs/op
PASS

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容