原文:Top 6 web frameworks for Go as of 2017
作者:Edward Marinescu
譯者:roy
譯者注:本文介紹截至目前(2017年)最好的6個Go語言Web框架。以下為譯文:
GO 語言愛好者的最佳Web框架
如果你是自己寫一個小應用程序,那你可能不需要Web框架。但是如果你要做產品,那么你肯定需要一個好的框架。
如果你認為你有相應的知識和經驗,你會自己編寫所有的這些代碼么?你有時間找到一個產品級的外部包來完成工作嗎?你確定這與你應用程序的其它部分一致嗎?
這些都是促使我們(即便是我們中最優秀的)使用框架的原因,如果其他人已經做了必要的艱苦的工作,我們不會想讓自己重復這些工作。
簡介
Go 是一個快速增長的開源編程語言,用於構建簡單、快速和可靠的軟件。點這里看有哪些大公司在使用Go語言來構建他們的服務。
本文提供了所有必要的信息,以幫助開發人員了解使用Go語言開發Web應用程序的最佳選項。。
本文包含了最詳細的框架比較,通過盡可能多的角度(人氣,社區支持,內置功能等)來比較最知名的幾個Web 框架。
Beego: 一個Go語言下開源的,高性能Web框架
* https://github.com/astaxie/beego
* https://beego.me
Buffalo: 一個Go語言下快速Web開發框架
* https://github.com/gobuffalo/buffalo
* https://gobuffalo.io
Echo: 一個高性能,極簡的Web框架
* https://github.com/labstack/echo
* https://echo.labstack.com
Gin: 一個Go語言寫的HTTP Web框架。它提供了Martini風格的API並有更好的性能。
* https://github.com/gin-gonic/gin
* https://gin-gonic.github.io/gin
Iris: 目前發展最快的Go Web框架。提供完整的MVC功能並且面向未來。
* https://github.com/kataras/iris
* https://iris-go.com
Revel: 一個高生產率,全棧Go語言的Web框架。
* https://github.com/revel/revel
* https://revel.github.io
人氣
按人氣排序(star收藏數)
https://github.com/speedwheel/awesome-go-web-frameworks/blob/master/README.md#popularity
學習曲線
https://github.com/speedwheel/awesome-go-web-frameworks/blob/master/README.md#learning-curve
感謝 astaxie 和 kataras 的精彩工作,同時希望其他的框架能夠趕上並提供更多的用例,至少對我來說,如果要我切換到一個新框架,用例是快速掌握更多知識的最豐富的資源。一個用例抵得上千言萬語。
核心功能
按功能由多到少排序
https://github.com/speedwheel/awesome-go-web-frameworks/blob/master/README.md#core-features
Go中最著名的“Web框架”並不是真正的框架,也就是說:Echo、Gin和Bufflo不是真正的(完整功能的)Web框架。但是Go社區的大多數人認為它們是。他們認為它們可以和Iris、Beego或Revel相比較。因此,我們有義務將它們也包括在這個列表中。
除了Beego和Revel之外,上述所有框架都可以適應任何為net/http創建的中間件。有些框架很容易,有些需要些編碼(即使有點痛苦也是一個選擇)。
名詞解釋
路由:命名路徑參數和通配符(Router: Named Path Parameters & Wildcard)
你可以注冊一個處理器(handler)並對應一個動態路徑路由(router)。
下面是命名路徑參數的例子:~
"/user/{username}" matches to "/user/me", "/user/speedwheel" etc
~
路徑參數 _username_ 的值分別是 _”me”_ 和 _”speedwheel”_。
下面是通配符的例子:~
"/user/{path *wildcard}" matches to
"/user/some/path/here",
"/user/this/is/a/dynamic/multi/level/path" etc
~
路徑參數 _path_ 的值分別是 _”some/path/here”_ 和 _”this/is/a/dynamic/multi/level/path”_。
Iris 也支持一種叫 _macros_ 的功能,可以描述為 _/user/{username:string}_ 或 _/user/{username:int min(1)}_
路由:正則表達式(Router: Regex)
你可以注冊一個處理器(handler)並對應一個包含過濾器(filter)的動態路徑路由(router)。過濾器會過濾掉一些傳給處理器的參數值。
下面是一個例子:~
"/user/{id ^[0-9]$}" matches to "/user/42" but not to "/user/somestring"
~
路徑參數 _id_ 的值是整數 _42_ (而不會是字符串)。
路由:分組(Router: Grouping)
你可以注冊通用邏輯或中間件/處理器(middlewar/handler)並對應一組共享相同路徑前綴的路由(router)。
下面是一個例子:~
myGroup := Group("/user", userAuthenticationMiddleware)
myGroup.Handle("GET", "/", userHandler)
myGroup.Handle("GET", "/profile", userProfileHandler)
myGroup.Handle("GET", "/signup", getUserSignupForm)
~
* /user
* /user/profile
* /user/signup
你甚至可以在分組(group)中再創建子分組(subgroup)~
myGroup.Group("/messages", optionalUserMessagesMiddleware)
myGroup.Handle("GET', "/{id}", getMessageByID)
~
* /user/messages/{id}
路由:隨意組合以上選項而不用擔心沖突(Router: All the above Mixed Without Conflict)
這是一個先進且很有用的功能,我們很多人希望路由或Web框架支持該功能,但目前在Go環境里只有Iris支持。
這意味着像 /{path *wildcard},/user/{username}, /user/static 和 /user/{path *wildcard} 可以注冊在同一個路由里而且可以被正確地映射到靜態路徑 (/user/static) 或 通配符 (/{path *wildcard})
路由:自定義HTTP錯誤(Router: Custom HTTP Errors)
你可以注冊一個處理器(handler)並對應一個’錯誤’代碼。 HTTP 錯誤代碼是一個 >=400 的狀態碼,例如 NotFound 404。
下面是一個例子:~
OnErrorCode(404, myNotFoundHandler)
~
上面的大多數Web框架只支持注冊 404,405 和 500 錯誤代碼,但是像 Iris,Beego和 Revel 這些提供完整功能的框架支持任何狀態代碼甚至 任何錯誤(any error)代碼(只有Iris支持 任何錯誤 )。
100%與 net/http 兼容(100% compatible with net/http)
這意味着:
* 框架提供了上下文(context)讓你可以直接訪問 *http.Request 和 http.ResponseWriter。
* 你可以把 net/http 處理器(handler)轉化到一個特定框架下的處理器(Handler)。
中間件生態系統(Middleware ecosystem)
你可以不用自己來為每個處理器包裝中間件,但是框架提供給你一個完整的引擎來定義流程,無論是全局的或每個路由或每組路由,例如 Use(middleware), Done(middleware) 等。
Sinatra風格的API(Sinatra-like API)
在運行時注冊處理器來處理特定HTTP方法的路由(和路徑參數)。
下面是一個例子:~
.Get or GET("/path", gethandler)
.Post or POST("/path", postHandler)
.Put or PUT("/path", putHandler) and etc.
~
服務器: 自動HTTPS(Server: Automatic HTTPS)
框架的服務器支持注冊和自動更新SSL證書來管理SSL/TLS傳入連接(https)。最着名的自動HTTPS提供者是letsencrypt。
服務器: 正常關機(Server: Gracefully Shutdown)
當按下 CTRL+C 關閉終端應用程序時,服務器將正常地停止,它會等待一些連接完成它們的工作(在設定的時間內),或者觸發一個自定義的事件來做清理(例如關閉數據庫)。
服務器: 多監聽器(Server: Multi Listeners)
框架的服務器支持注冊自定義 net.Listener 或者可以通過多個 http 服務器和地址來服務web應用。
完全支持HTTP/2(Full HTTP/2)
框架支持HTTP/2,包括https和服務器 Push 功能。
子域(Subdomains)
你可以直接在你的Web應用里按子域(subdomain) 直接注冊路由。
secondary 是指框架不支持該功能但是你依然可以通過啟用多個http服務器來實現。壞處是主應用程序和子域並不相連而且默認情況下它們並不直接共享邏輯。
會話(Sessions)
http會話被支持並可以在你的特定處理器中使用。
* 一些Web框架支持使用后台數據庫來存儲會話,以便在服務器重啟之間獲得持久性。
* Buffalo 使用 gorrila 會話,這比其他的實現要慢一點點。
- 1
- 2
下面是一個例子:
~~~
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)
}
~~~
Wiki: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#HTTP_session
Websockets
框架支持websocket通信協議。實現是各不相同的。
你應該搜索他們的例子,看看有什么適合你。我的同事嘗試了所有框架后告訴我,與其他框架相比,Iris實現了功能更強大且更簡單的webosocket連接。
Wiki: https://en.wikipedia.org/wiki/WebSocket
App 內置視圖/模板(View/Templates)
通常情況下,你必須將所有模板文件與你的Web應用程序的可執行文件一起打包。應用程序App 內置意味着該框架支持與go-bindata的集成,所以最終的可執行文件包含模板,表示為 []byte。
什么是視圖引擎
框架支持模板加載,模板自定義和自帶模板並能在一些關鍵工作上幫助我們。
視圖引擎:STD(View Engine: STD)
框架支持標准 html/template 解析器來加載模板。
視圖引擎:Pug(View Engine: Pug)
框架支持 Pug 解析器來加載模板。
視圖引擎:Django(View Engine: Django)
框架支持 Django 解析器來加載模板。
視圖引擎:Handlebars(View Engine: Handlebars)
框架支持 Handlebars 解析器來加載模板。
視圖引擎:Amber(View Engine: Amber)
框架支持 Amber 解析器來加載模板。
渲染器:Markdown, JSON, JSONP, XML…
框架的上下文為你提供了一種輕松地發送和定制各種內容類型的響應結果的簡便方法。
MVC
模型-視圖-控制器(MVC)是在計算機上實現用戶界面的軟件架構模式。它將一個給定的應用程序分成三個相互關聯的部分。這樣做是為了將信息的內部表示與信息呈現給用戶並讓用戶接受的方式分離開來。MVC設計模式分離了這些主要成分並允許高效的代碼重用和並行開發。
* Iris支持完整的MVC功能,可以在運行時注冊。
* Beego僅支持方法和模型匹配,可以在運行時注冊。
* Revel支持方法、路徑和模型匹配,只能通過一個生成器注冊(一個用於構建Web應用程序的必要軟件)。
- 1
- 2
- 3
Wiki: https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
緩存(Caching)
Web緩存(或HTTP緩存)是一種信息技術,用於臨時存儲(緩存)Web文檔,如HTML頁面和圖像,以減少服務器延遲。Web緩存系統記錄了網絡通信,如果滿足某些條件,后續請求的結果可以直接取自Web緩存。Web緩存系統既可以指設備,也可以指計算機程序。
Wiki: https://en.wikipedia.org/wiki/Web_cache
文件服務器(File Server)
你可以把一個(物理)目錄注冊到一個路由表,該路由表會自動將目錄下的文件服務給客戶程序。
文件服務器: 內置入APP(File Server: Embedded Into App)
通常你必須將所有靜態文件(如資源文件、CSS、JavaScript文件…)和應用程序的可執行文件一起傳輸。支持此特性的框架使你有機會將所有這些數據嵌入到應用程序中,表示為 []byte,它們的響應時間也更快,因為服務器可以不用在物理位置上查找文件而直接服務。
響應可以在發送之前在生命周期內多次修改(Response can be Modified Many times through lifecycle before sent)
目前僅Iris可以通過http_context內置的 response writer 支持該功能。
當框架支持這一功能時,你可以在發送給客戶端之前檢索,重置或修改的狀態代碼、正文和頭文件(在基於net/http的Web框架中,默認情況下這是不可能的,因為正文和狀態代碼在寫入后無法檢索或更改)。
Gzip
你可以在路由的處理器里改變響應writer來使用gzip壓縮,框架應該設置返回結果的頭(header),並在出現任何錯誤時重置writer,也應該檢查客戶端是否支持gzip。
gzip是一種文件格式(也可以是一個軟件應用),用於文件的壓縮和解壓縮軟件。
Wiki: https://en.wikipedia.org/wiki/Gzip
測試框架(Testing Framework)
你可以使用特定的框架測試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 返回一個你假定的Web應用程序,
針對路徑 /admin 它有一個GET處理器並有基本的身份驗證保護。
上面簡單的測試檢查 /admin 請求是否返回狀態碼 Status OK 並驗證特定的用戶名和密碼,最后檢查正文內容是 “welcome”。
Typescript Transpiler
Typescript的目標是成為一個ES6超集,除了標准定義的所有新東西,它將添加一個靜態類型系統(static type system)。Typescript也有一個轉換器(transpiler)將我們的Typescript代碼(即6 +類型)轉換到ES5或ES3標准上的JavaScript代碼,以便在目前的瀏覽器上運行。
在線編輯器(Online Editor)
有了在線編輯器,你可以快速方便地編譯和運行Go代碼。
日志系統(Logging System)
自定義日志系統系統可以擴展原始日志包的功能,比如代碼配色、格式、日志級別的分隔,不同的登錄后台等等。
維護和自動更新(Maintenance & Auto-Updates)
以非侵入性的方式通知用戶“即時更新”。
這篇文章最早發布在:https://medium.com/@MarinescuEdwar1/top-6-web-frameworks-for-go-as-of-2017-23270e059c4b
PS:推薦一個容器技術線上直播,講師來自騰訊、華為、思科、58同城、蘑菇街、當當等6位一線專家,議題涵蓋容器雲、微服務、servicemesh等最新實踐,歡迎報名參加