如果你只是想写一个自己用的小网站,或许你不需要框架,但如果你是要开发一个投入生产运营的网站,那么你肯定会需要一个框架,而且是需要一个好的 Web 框架。
如果你已经掌握所有必要的知识和经验,你会冒险自己去重新开发所有的功能么?你有时间去找满足生产级别要求的库来用于开发么?另外,你确定这个库可以满足你后续所有的要求?
这些都是促使我们去使用框架的原因,哪怕是那些最牛的开发者也不会一直想要重新造轮子,我们可以站在前人的肩膀上,走得更快更好。
介绍
Go 是一门正在快速增长的编程语言,专为构建简单、快速且可靠的软件而设计。 点击 此处 查看有哪些优秀的公司正在使用 Go 语言来驱动他们的业务。
本文包含了最详尽的框架比较,从流行度、社区支持及内建功能等多个不同角度出发做对比。
Beego:开源的高性能 Go 语言 Web 框架。
Buffalo:使用 Go 语言快速构建 Web 应用。
Echo:简约的高性能 Go 语言 Web 框架。
Gin:Go 语言编写的 Web 框架,以更好的性能实现类似 Martini 框架的 API。
Iris:全宇宙最快的 Go 语言 Web 框架。完备 MVC 支持,未来尽在掌握。
Revel:Go 语言的高效、全栈 Web 框架。
流行度
按照流行度排行(根据 GitHub Star 数量)
学习曲线
astaxie 和 kataras 分别为 Beego 和 Iris 做了超棒的工作,希望其他的框架也能迎头赶上,为开发者提供更多的例子。至少对于我来说,如果我要切换到一个新的框架,那些例子就是最丰富的资源,来获取尽可能多的有用信息。一个实例胜千言啊。
核心功能
根据功能支持的多寡排行
net/http
技术性词汇
路由:命名的路径参数和通配符
可以处理动态的路径。
命名的路径参数例子:
"/user/{username}" 匹配 "/user/me","/user/speedwheel" 等等
username"me""speedwheel"
通配符的例子:
"/user/{path *wildcard}" 匹配
"/user/some/path/here",
"/user/this/is/a/dynamic/multi/level/path" 等等
path"some/path/here""this/is/a/dynamic/multi/level/path"
macros/user/{username:string}/user/{username:int min(1)}
路由:正则表达式
过滤动态的路径。
例如:
"/user/{id ^[0-9]$}" 能匹配 "/user/42" ,但不会匹配 "/user/somestring"
id42
路由:分组
通过共用逻辑或中间件来处理有共同前缀的路径组。
例如:
myGroup := Group("/user", userAuthenticationMiddleware)
myGroup.Handle("GET", "/", userHandler)
myGroup.Handle("GET", "/profile", userProfileHandler)
myGroup.Handle("GET", "/signup", getUserSignupForm)
- /user
- /user/profile
- /user/signup
你甚至可以从一个组中创建子分组:
myGroup.Group("/messages", optionalUserMessagesMiddleware)
myGroup.Handle("GET', "/{id}", getMessageByID)
- /user/messages/{id}
路由:上述所有规则相结合而没有冲突
这是一个高级且有用的的功能,我们许多人都希望路由模块或 Web 框架能支持这点,但目前,在 Go 语言框架方面,只有 Iris 能支持这一功能。
/{path *wildcard}/user/{username}/user/static/user/{path *wildcard}/user/static/{path *wildcard}
路由:自定义 HTTP 错误
>=400NotFound 404
例如:
OnErrorCode(404, myNotFoundHandler)
404405500Iris,Beego 和 Revelany errorany error
100% 兼容 net/http
这意味著:
*http.Requesthttp.ResponseWriternet/http
中间件生态系统
框架会为你提供一个完整的引擎来定义流程、全局、单个或一组路由,而不需要你自己用不同的中间件来封装每一部分的处理器。框架会提供比如 Use(中间件)、Done(中间件) 等函数。
类 Sinatra 的 API 设计(译者注:Sinatra 是一门基于 Ruby 的领域专属语言)
可以在运行时中注入代码来处理特定的 HTTP 方法 (以及路径参数)。
例如:
.Get or GET("/path", gethandler)
.Post or POST("/path", postHandler)
.Put or PUT("/path", putHandler) and etc.
服务器程序:默认启用 HTTPS
框架的服务器支持注册及自动更新 SSL 证书来管理新传入的 SSL/TLS 连接 (https)。 最著名的默认启用 https 的供应商是 letsencrypt。
服务器程序:平滑关闭(Gracefully Shutdown)
CTRL + C
服务器程序:多重监听
net.Listener
完全支持 HTTP/2
Push
子域名
你可以直接在你的 Web 应用中注入子域名的路径。
辅助功能(secondary)
会话(Sessions)
支持 http sessions,且可以在自定义的处理程序中使用 sessions。
- 有一些 Web 框架支持后台数据库来储存 sessions,以便在服务器重启之后仍旧能获得持久的 sessions。
- Buffalo 使用 gorilla 的 sessions 库,它比其他框架的实现略微慢了一点。
例如:
func setValue(context http_context){
s := Sessions.New(http_context)
s.Set("key", "my value")
}
func getValue(context http_context){
s := Sessions.New(http_context)
myValue := s.Get("key")
}
func logoutHandler(context http_context){
Sessions.Destroy(http_context)
}
网络套接字(Websockets)
框架支持 websocket 通信协议。不同的框架对于这点有各自不同的实现方式。
你应该通过它们的例子来看看哪个适合你。我的一个同事,在试过了上述所有框架中的 websocket 功能之后告诉我:Iris 实现了最多的 websocket 特性,并且提供了相对更容易使用的 API 。
程序内嵌对视图(又名模版)的支持
[]byte
什么是视图引擎
框架支持模版加载、自定义及内建模版功能,以此来节省我们的开发时间。
视图引擎:STD
html/template
视图引擎:Pug
Pug
视图引擎:Django
Django
视图引擎:Handlebars
Handlebars
视图引擎:Amber
Amber
渲染:Markdown, JSON, JSONP, XML...
框架提供一个简单的方法来发送和自定义各种内容类型的响应。
MVC
Model–view–controller (MVC) 模型是一种用于在计算机上实现用户界面的软件架构模式,它将一个应用程序分为互相关联的三部分。这样做的目的是为了:将信息的内部处理逻辑、信息呈现给用户以及从用户获取信息三者分离。MVC 设计模式将这三个组件解耦合,从而实现高效的代码复用和并行开发。
- Iris 支持完备的 MVC 功能, 可以在运行时中注入。
- Beego 仅支持方法和数据模型的匹配,可以在运行时中注入。
- Revel 支持方法,路径和数据模型的匹配,只可以通过生成器注入(生成器是另外一个不同的软件用于构建你的 Web 应用)。
缓存
Web 缓存(或 http 缓存)是一种用于临时存储(缓存)网页文档,如 HTML 页面和图像,来减缓服务器延时。一个 Web 缓存系统缓存网页文档,使得后续的请求如果满足特定条件就可以直接得到缓存的文档。Web 缓存系统既可以指设备,也可以指软件程序。
文件服务器
可以注册一个(物理的)目录到一个路径,使得这个路径下的文件可以自动地提供给客户端。
文件服务器:内嵌入应用
[]byte
响应可以在发送前的生命周期中被多次修改
目前只有 Iris 通过 http_context 中内建的的响应写入器(response writer)支持这个功能。
net/http
Gzip
当你在一个路由的处理程序中,并且你可以改变响应写入器(response writer)来发送一个用 gzip 压缩的响应时,框架会负责响应的头部。如果发生任何错误,框架应该把响应重置为正常,框架也应该能够检查客户端是否支持 gzip 压缩。
gzip 是用于压缩和解压缩的文件格式和软件程序。
测试框架
可以使用框架特定的库,来帮助你轻松地编写更好的测试代码来测试你的 HTTP 。
例如(目前仅 Iris 支持此功能):
func TestAPI(t *testing.T) {
app := myIrisApp()
tt := httptest.New(t, app)
tt.GET("/admin").WithBasicAuth("name", "pass").Expect().
Status(httptest.StatusOK).Body().Equal("welcome")
}
myIrisApp/admin
"name""pass"/adminStatus OK"welcome"
TypeScript 转译器
TypeScript 的目标是成为 ES6 的超集。除了标准定义的所有新特性外,它还增加了静态类型系统。TypeScript 还有转换器用于将 TypeScript 代码(即 ES6 + 类型)转换为 ES5 或 ES3 JavaScript 代码,如此我们就可以在现今的浏览器中运行这些代码了。
在线编辑器
在在线编辑器的帮助下,你可以快速轻松地在线编译和运行代码。
日志系统
自定义日志系统通过提供有用的功能,如彩色日志输出、格式化、日志级别分离及不同的日志记录后端等,来扩展原生日志包。
维护和自动更新
以非侵入的方式通知框架的用户即时更新。
再见!
谢谢你的阅读,如果你喜欢这篇文章,请用表情符号和我互动哦