目录
入围的router
http.ServeMux
julienschmidt/httprouter
go-chi/chi
gorilla/mux
荣誉提名 bmizerany/pat 和 matryer/way
流程图
其他router
平时你是不是也纠结该用哪个router呢?土拨鼠今天带来一篇router比较的文章,土拨鼠翻译这篇文章也收获了很多(了解router的特性、优秀的代码欣赏等),同时希望能给大家在选择router的时候提供一些参考意见。本文主要翻译自https://www.alexedwards.net/blog/which-go-router-should-i-use。由于土拨鼠翻译水平有限,不足之处烦请指出。另外作者也出书了。书名《Let’s Go》[1] 和 《Let’s Go Further》[2]。主要介绍了如何去使用 Go 构建专业的生产级 web 应用程序和 api。感兴趣的同学可以看看。
本文外链较多,想要更好体验的话可以阅读原文跳转到Go招聘网站上进行阅读。
当你开始使用 Go 构建 web 应用程序时,你可能会问的第一个问题就是“我应该使用哪个router?”.
这也不是一个容易回答的问题。可能有超过100种不同的router[3],它们都有不同的 api、特性和行为。因此,在这篇博客文章中,评估了30个受欢迎的案例,并评估出了一个最佳选项的名单列表,以及一个流程图,可以用来帮助指导你作出选择。
在我们开始之前,有几个关于术语的注意事项:
GET
、POST
等)将不同的 HTTP 请求分发给不同的handler。/movies/{ id }
这样的路由,其中{ id }
是 URL 路径中的动态变量值。/movies/{[ a-z-] + }
这样的路由,其中[ a-z-] +
是 URL 路径中必需的 regexp 匹配。www.example. com
)而不仅仅是 URL 路径向不同的handler发送 HTTP 请求。Authorization
的值路由到不同的handler)。/blog/{ slug }
和/blog/new
,那么带有路径/blog/new
的 HTTP 请求将会匹配这两个路由。注意: 从软件工程的角度来看,路由冲突并不是件好事。它可能就是 bug 和混乱的来源,我们应该在应用程序中尽量避免它们。
有四种不同的router进入了入围名单。它们是 http.ServeMux
[4], julienschmidt/httprouter
[5], go-chi/chi
[6] 和 gorilla/mux
[7]. 。这四个router都经过了充分的测试,文档也写得很友好,并且到现在还在积极地维护中。它们(大多数)有稳定的 api,并且与 http.Handler
, http.HandlerFunc
兼容。标准库的中间件模式[8]。
在性能方面,所有四个router对于(几乎)每个应用程序来说都足够快,建议你可以根据需要的特定功能而不是性能来选择它们。我个人曾不同时间在生产应用程序中使用过这四个router,并且对它们感到非常满意。
我首先要说的是,如果你可以使用 http.ServeMux
[9],就近可能应该使用它。
作为 Go 标准库的一部分,它经过了严格的实战测试并有详细的文档记录。使用它意味着不需要导入任何第三方依赖项,而且大多数其他 Go 开发人员也会熟悉它的工作原理。Go 1 兼容性承诺还意味着应该能够http.ServeMux
长期依靠相同的方式工作。所有这些在应用程序维护方面都是很大的积极因素。
与其他大多数router不同,它还支持基于主机的路由,传入请求的 url 会自动清理,并且它匹配路由的方式也很聪明: 较长的路由模式总是优先于较短的路由。这是一个很好的副作用,您可以以任何顺序注册,并且它不会改变应用程序的行为。
两个主要限制http.ServeMux
的是它不支持基于方法的路由或 URL 路径中的变量。但是缺乏对基于方法的路由的支持并不总是避免使用它的好理由——可以使用下面这样的代码解决:
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", index)
err := http.ListenAndServe(":3000", mux)
log.Fatal(err)
}
func index(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
// Common code for all requests can go here...
switch r.Method {
case http.MethodGet:
// Handle the GET request...
case http.MethodPost:
// Handle the POST request...
case http.MethodOptions:
w.Header().Set("Allow", "GET, POST, OPTIONS")
w.WriteHeader(http.StatusNoContent)
default:
w.Header().Set("Allow", "GET, POST, OPTIONS")
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
}
}
在上面几行代码中就可以实现了基于方法的路由,以及定制的404和405响应和对 OPTIONS
请求的支持。
随着时间的推移,我逐渐意识到这http.ServeMux
有很多优秀的地方,而且在很多情况下已经足够了。事实上,我唯一建议不要使用它的时候是需要支持 URL 路径中的变量或自定义路由规则。在这些情况下,尝试使用http.ServeMux
可能会有点麻烦,我认为选择第三方router通常会更好。
我认为这julienschmidt/httprouter
[10]的行为和对 HTTP 规范的合规性方面,是任何第三方router最接近“完美”的。它支持基于方法的路由和动态 URL。它还自动处理OPTIONS
请求并正确地发送405
响应码,而且允许为404
和 405
响应设置自定义的handler。
它不支持基于主机的路由、自定义路由规则或 regexp 路由模式。需要注意的是,httprouter
也不允许有冲突的路由,比如/post/create
和 /post/:id
。这在客观上是一件好事,因为它有助于避免 bug,但如果您需要使用冲突的路由(例如与现有系统使用的路由保持一致) ,则可能会出现问题。
httprouter
的一个缺点是,API和文档有点混乱。这个包是在Go 1.7中引入请求上下文之前就已发布,很多当前的API仍然存在,以支持这些旧版本的Go。现在,你可以使用常规的http.Handler
和http.HandlerFunc
签名来写你的handler,你所需要的是要注册router.Handler()
和router.HandlerFunc()
方法。例如:
func main() {
router := httprouter.New()
router.HandlerFunc("GET", "/", indexGet)
router.HandlerFunc("POST", "/", indexPost)
err := http.ListenAndServe(":3000", mux)
log.Fatal(err)
}
func indexGet(w http.ResponseWriter, r *http.Request) {
// Handle the GET request...
}
func indexPost(w http.ResponseWriter, r *http.Request) {
// Handle the POST request...
}
go-chi/chi
[11] 包支持基于方法的路由、 URL 路径中的变量和 regexp 路由模式。像 · 一样,它也允许你为404和405个响应设置自定义handler。
但我最喜欢的是,在chi
中可以创建使用特定中间件的路由 "组",比如下面的代码片段。这对于有很多中间件和路由需要管理的大型应用来说非常有用。
r := chi.NewRouter()
// Middleware used on all routes
r.Use(exampleMiddlewareOne)
r.Use(exampleMiddlewareTwo)
r.Get("/one", exampleHandlerOne)
r.Group(func(r chi.Router) {
// Middleware only used in this route group
r.Use(exampleMiddlewareThree)
r.Get("/two", exampleHandlerTwo)
})
值得注意的是,chi
允许冲突的路由,路由是按照声明的顺序进行匹配的。
chi
的两个缺点是它不能自动处理OPTIONS请求,而且它不能在405响应中设置Allow
header。如果你正在建立一个网络应用程序或私人API,那么这些东西可能不是一个大问题--但如果你正在建立一个公共API,这就是需要注意的事情了。和httprouter
一样,它也不支持基于主机的路由.
值得注意的是,在过去的6年里,chi
已经有了5个主要的版本增量,其中大部分都包含了破坏性的变化。历史并不一定能预测未来,但确实表明,对于 chi
来说,向后兼容性和不进行性更改并不像这个短名单上的其他一些router那么重要。相比之下,httprouter
和 gorilla/mux
在这段时间里并没有做出任何突破性的改变。
值得注意的是,在过去的6年中,chi
已经有5个主要的版本增量--其中大部分都包括重大变化。历史不一定是未来的预测,但确实表明,与这个入围名单上的其他一些路由器相比,向后兼容和不做破坏性的修改对chi
来说不是那么重要。相比之下,httprouter
和gorilla/mux
在这段时间内没有做任何破坏性的改动。
gorilla/mux
包可能是最著名的Go router,这是有原因的。它包括了各种功能,包括支持基于方法的路由、动态URL、regexp路由模式和基于主机的路由。重要的是,它是这个入围名单上唯一支持自定义路由规则和路由 "反转 "的router(就像你在Django、Rails或Laravel中看到的那样)。它还允许你为404和405响应设置自定义handler。
它的缺点基本上和 chi
一样ーー它不会像 httprouter
那样自动处理 OPTIONS
请求,也不会在405响应中包含 Allow
header。同样,和 chi
一样,它也允许相互冲突的路由,会按声明的顺序进行匹配。
鉴于chi
和gorilla/mux
的缺点很相似,在两者之间你可以直接选择:如果你需要支持自定义路由规则、基于主机的路由或路由 "反转",选择gorilla/mux
。如果你不需要这些 "高级 "功能,那么最好选择chi
,因为它有很好的管理中间件的功能,特别是如果你正在构建一个大型应用。
我认为值得一提的另外两个router是bmizerany/pat
[12] 和 matryer/way
[13]。我对这两个都情有独钟,因为它们都是故意简单化的。它们拥有很小的 api 和非常清晰易懂的代码,这使得我们可以很容易准确地掌握router在幕后是如何工作的。尤其是matryer/way
背后的代码,非常值得一读。
虽然它们的功能不如入围名单中的其他router,但我认为它们的简单性使它们很适合用于教程(尤其是针对入门gopher的教程),如果你想建立自己的自定义router,可以把它们作为一个起点/灵感。
考虑到各种利弊和支持的功能,这个流程图应该可以帮助你在四个入围的router之间做出选择。
下面列出了评估的其他router,以及一个简短的说明,解释了为什么它们没有进入名单中。
注意: 使用这个问题“代码库是否包含 go.mod 文件?”作为一个代理来测量一个代码库当前是否在维护。这似乎是合理的——如果维护者仍然参与Go生态并关注代码,他们应该会在过去几年的某个时候使用modules来更新代码库。
Repository | Notes |
---|---|
celrenheit/lion[14] | 目前尚未维护 |
claygod/Bxog[15] | 目前尚未维护 |
clevergo/clevergo[16] | 使用自定义handler签名(不是 http.Handler 或 http.HandlerFunc)。 |
dimfeld/httptreemux[17] | 不完全支持 http.Handler。需要中间件来设置自定义 404/405 handler。 |
donutloop/mux[18] | 目前尚未维护 |
gernest/alien[19] | 目前尚未维护 |
go-ozzo/ozzo-routing[20] | 使用自定义handler签名(不是 http.Handler 或 http.HandlerFunc)。 |
go-playground/lars[21] | 目前尚未维护 |
go-zoo/bone[22] | 很好,但与 chi 有类似的用例(提供的更多)。但是测试不够完整的。 |
go101/tinyrouter[23] | 详细的路由说明。不会自动发送 405 响应。 |
gocraft/web[24] | 目前尚未维护 |
goji/goji[25] | 稍微有点不寻常但具备灵活的 API,支持自定义匹配程序。需要中间件来设置自定义 404/405 handler。也很好,但我认为 gorilla/mux 提供了类似的功能并且更易于使用。 |
goroute/route[26] | 使用自定义handler签名(不是 http.Handler 或 http.HandlerFunc)。 |
gowww/router[27] | 很好,但是有类似 chi 的用例(提供更多)。没有办法设置自定义405handler。 |
GuilhermeCaruso/bellt[28] | 无法设置自定义404或405 handlers. |
husobee/vestigo[29] | 目前尚未维护 只支持http.HandlerFunc. |
naoina/denco[30] | 目前尚未维护 |
nbari/violetear[31] | 很好,但是和 chi 有类似的用例(它提供更多)。wrap http.ResponseWriter 用自己的定制类型,这在某些情况下可能会出现问题。 |
nbio/hitch[32] | 缺乏文档 |
nissy/bon[33] | 目前尚未维护 |
razonyang/fastrouter[34] | 目前尚未维护 |
rs/xmux[35] | 目前尚未维护 使用自定义handler签名(不是 http.Handler 或 http.HandlerFunc)。 |
takama/router[36] | 目前尚未维护 |
vardius/gorouter[37] | 很好,但是和 chi 有类似的用例(它提供更多)。5年的4个主要版本表明这个 API 可能并不是很可靠。 |
VividCortex/siesta[38] | 很好,但是有类似 chi 的用例(提供更多)。没有办法设置自定义405handler。 |
xujiajun/gorouter[39] | 目前尚未维护 |
[1]《Let’s Go》: https://lets-go.alexedwards.net/
[2]《Let’s Go Further》: https://lets-go-further.alexedwards.net/
[3]100种不同的router: https://github.com/search?l=Go&p=5&q=http+router&type=Repositories
[4]http.ServeMux
: https://pkg.go.dev/net/http#ServeMux
[5]julienschmidt/httprouter
: https://github.com/julienschmidt/httprouter
[6]go-chi/chi
: https://github.com/go-chi/chi
[7]gorilla/mux
: https://github.com/gorilla/mux
[8]标准库的中间件模式: https://www.alexedwards.net/blog/making-and-using-middleware
[9]http.ServeMux
: https://pkg.go.dev/net/http#ServeMux
[10]julienschmidt/httprouter
: https://github.com/julienschmidt/httprouter
[11]go-chi/chi
: https://github.com/go-chi/chi
[12]bmizerany/pat
: https://github.com/bmizerany/pat
[13]matryer/way
: https://github.com/matryer/way
[14]celrenheit/lion: https://github.com/celrenheit/lion
[15]claygod/Bxog: https://github.com/claygod/Bxog
[16]clevergo/clevergo: https://github.com/clevergo/clevergo
[17]dimfeld/httptreemux: https://github.com/dimfeld/httptreemux
[18]donutloop/mux: https://github.com/donutloop/mux
[19]gernest/alien: https://github.com/gernest/alien
[20]go-ozzo/ozzo-routing: https://github.com/go-ozzo/ozzo-routing
[21]go-playground/lars: https://github.com/go-playground/lars
[22]go-zoo/bone: https://github.com/go-zoo/bone
[23]go101/tinyrouter: https://github.com/go101/tinyrouter
[24]gocraft/web: https://github.com/gocraft/web
[25]goji/goji: https://github.com/goji/goji
[26]goroute/route: https://github.com/goroute/route
[27]gowww/router: https://github.com/gowww/router
[28]GuilhermeCaruso/bellt: https://github.com/GuilhermeCaruso/bellt
[29]husobee/vestigo: https://github.com/husobee/vestigo
[30]naoina/denco: https://github.com/naoina/denco
[31]nbari/violetear: https://github.com/nbari/violetear
[32]nbio/hitch: https://github.com/nbio/hitch
[33]nissy/bon: https://github.com/nissy/bon
[34]razonyang/fastrouter: https://github.com/razonyang/fastrouter
[35]rs/xmux: https://github.com/rs/xmux
[36]takama/router: https://github.com/takama/router
[37]vardius/gorouter: https://github.com/vardius/gorouter
[38]VividCortex/siesta: https://github.com/VividCortex/siesta
[39]xujiajun/gorouter: https://github.com/xujiajun/gorouter
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。