Tango v0.4 版本發布,帶來統一高性能的新路由(Golang)
原文 http://lunny.info/2015/04/06/3-Tango-new-router.html
起子
自Tango發布之后大概有3個月了,受到了很多人的關注,也提了很多的改進意見。我自己也通過不斷 的用他開發,從而發現問題,不斷改進。昨天我發布了0.4.0版本,很明顯,最近版本號升得比較快。
從0.3到0.4,最重大的改變是路由方面的。路由基本上完全重寫,目前路由變得更統一,更靈活,性能上也有不少提升。來看看新的路由如何使用。
新路由
目前支持4種路由,靜態路由,命名路由,Catch-All路由,正則路由。下面分別說說4種路由:
靜態路由
靜態路由是最普遍的,默認的net/http目前只支持靜態路由,比如:
tango.Get("/", new(Action))
tango.Get("/public/bootstrap.min.css", new(Action))
命名路由
在0.4之前的版本中,命名路由的形式一般是 :name
,在0.4版本兼容以前的模式,并且新增了 (:name)
的形式。這個新的設計將允許使用字符或者數字作為分隔符。比如,新舊版本都支持這種形式:
tango.Get("/:name", new(Action))
tango.Get("/:name1-:name2", new(Action))
tango.Get("/:name1/:name2", new(Action))
而新版本增加了對下列形式的支持:
tango.Get("/(:name1)abc(:name2)", new(Action))
tango.Get("/(:name1)123(:name2)", new(Action))
Catch-All路由
Catch-All路由是0.4新增的一種路由形式。Catch-All路由和命名路由很相似,他們的的唯一區別在于 命名路由不能匹配/,而Catch-All路由可以匹配/。比如:
tango.Get("/*name", new(Action))
tango.Get("/*name/123", new(Action))
比如當訪問 /name1/name2/123
時,第二個路由會匹配出 *name = name1/name2
。當訪問 /name1/name2
時,則第一個路由會匹配出 *name = name1/name2
。
獲取Catch-All路由請通過 Params.Get("*name")
。
正則路由
注意:0.4版本的正則路由和老版本的正則路由不兼容
為了統一表達形式,0.4版本拋棄了以前版本中完全使用Go的正則的方式來進行匹配的方式,如:
0.3版本以前:
tango.Get("/(.*)", new(Action))
而獲取參數通過 Params.Get(”:0”)來獲取。
0.3版本到0.4版本之間:
tango.Get("/(?P<name>.*)", new(Action))
而獲取參數通過 Params.Get(”:name”)來獲取,同時也可以使用 Params.Get(":0")
來獲取。
0.4版本不兼容前面的語法,再次提醒注意,而采用如下方法,匿名的正則已不被允許, Params.Get(":0")
也不再受支持:
tango.Get("/(:name.*)", new(Action))
tango.Get("/(:name[0-9]+)", new(Action))
而獲取參數通過 Params.Get(”:name”)來獲取,也可以通過Params[0].Value來獲取,Params目前變成了一個Slice。
路由優先級
- 靜態路由和其它路由都匹配時,靜態路由優先,跟添加的順序無關;
- 其它路由之間根據添加的順序,先添加的優先。
例如:
t := tango.Classic()
t.Get("/:name", new(Others))
t.Get("/admin", new(Admin))
t.Run()
以上代碼,當請求 /admin
時, Admin
的 Get
方法將被執行。
t := tango.Classic()
t.Get("/:name", new(Admin))
t.Get("/*name", new(Others))
t.Run()
以上代碼,當請求 /admin
時, Admin
的 Get
方法將被執行;當請求 /admin/ui
, Others
的 Get
方法將被執行。
t := tango.Classic()
t.Get("/*name", new(Admin))
t.Get("/:name", new(Others))
t.Run()
以上代碼, Others
的 Get
方法將永遠不會被執行, 因為所有匹配的請求均會調用 Admin
的 Get
方法。
注意事項
關于新路由也有幾點需要注意的事項:
-
命名和正則等可以混合使用,如:
/:name1-(:name2[0-9]+)
,但是要注意,必須要有分隔符,沒有分隔符,在新增路由時會panic,比如如下形式就不受支持:/:name1:name2
-
命名理論上是可以相同的,并且程序不會報錯,但是不建議這樣使用。通過Params.Get(”:name”)只會返回第一個,可通過自己遍歷Params來獲取多個相同的名字。比如:
/:name-:name
,這種規則是允許的,但是不推薦。
收尾
新的路由形式上更加統一,相信可以滿足大家的絕大部分需求。希望大家多提寶貴意見,可加QQ群:369240307,或者在 github.com/lunny/tango 以及 git.oschina.net/lunny/tango 中提出issue。
</div> </div>