GO 語言愛好者的最佳Web框架
如果你是自己寫一個(gè)小應(yīng)用程序,那你可能不需要Web框架。但是如果你要做產(chǎn)品,那么你肯定需要一個(gè)好的框架。
如果你認(rèn)為你有相應(yīng)的知識(shí)和經(jīng)驗(yàn),你會(huì)自己編寫所有的這些代碼么?你有時(shí)間找到一個(gè)產(chǎn)品級(jí)的外部包來完成工作嗎?你確定這與你應(yīng)用程序的其它部分一致嗎?
這些都是促使我們(即便是我們中最優(yōu)秀的)使用框架的原因,如果其他人已經(jīng)做了必要的艱苦的工作,我們不會(huì)想讓自己重復(fù)這些工作。
簡(jiǎn)介
Go 是一個(gè)快速增長(zhǎng)的開源編程語言,用于構(gòu)建簡(jiǎn)單、快速和可靠的軟件。點(diǎn)這里看有哪些大公司在使用Go語言來構(gòu)建他們的服務(wù)。
本文提供了所有必要的信息,以幫助開發(fā)人員了解使用Go語言開發(fā)Web應(yīng)用程序的最佳選項(xiàng)。。
本文包含了最詳細(xì)的框架比較,通過盡可能多的角度(人氣,社區(qū)支持,內(nèi)置功能等)來比較最知名的幾個(gè)Web 框架。
Fiber(感謝評(píng)論區(qū)的同學(xué)補(bǔ)充): Fiber是一個(gè)受到Express啟發(fā)的Web框架,基于使用Go語言編寫的最快的HTTP引擎Fasthttp構(gòu)建。旨在通過零內(nèi)存分配和高性能服務(wù),使快速開發(fā)更加簡(jiǎn)便。
https://github.com/gofiber/fiber
Beego: 一個(gè)Go語言下開源的,高性能Web框架
https://github.com/astaxie/beego
https://beego.me
Buffalo: 一個(gè)Go語言下快速Web開發(fā)框架
https://github.com/gobuffalo/buffalo
https://gobuffalo.io
Echo: 一個(gè)高性能,極簡(jiǎn)的Web框架
https://github.com/labstack/echo
https://echo.labstack.com
Gin: 一個(gè)Go語言寫的HTTP Web框架。它提供了Martini風(fēng)格的API并有更好的性能。
https://github.com/gin-gonic/gin
https://gin-gonic.github.io/gin
Iris: 目前發(fā)展最快的Go Web框架。提供完整的MVC功能并且面向未來。
https://github.com/kataras/iris
https://iris-go.com
Revel: 一個(gè)高生產(chǎn)率,全棧Go語言的Web框架。
https://github.com/revel/revel
https://revel.github.io
人氣
按人氣排序(star收藏?cái)?shù))
學(xué)習(xí)曲線
感謝 astaxie 和 kataras 的精彩工作,同時(shí)希望其他的框架能夠趕上并提供更多的用例,至少對(duì)我來說,如果要我切換到一個(gè)新框架,用例是快速掌握更多知識(shí)的最豐富的資源。一個(gè)用例抵得上千言萬語。
核心功能
按功能由多到少排序
Go中最著名的“Web框架”并不是真正的框架,也就是說:Echo、Gin和Bufflo不是真正的(完整功能的)Web框架。但是Go社區(qū)的大多數(shù)人認(rèn)為它們是。他們認(rèn)為它們可以和Iris、Beego或Revel相比較。因此,我們有義務(wù)將它們也包括在這個(gè)列表中。
除了Beego和Revel之外,上述所有框架都可以適應(yīng)任何為net/http創(chuàng)建的中間件。有些框架很容易,有些需要些編碼(即使有點(diǎn)痛苦也是一個(gè)選擇)。
名詞解釋
路由:命名路徑參數(shù)和通配符(Router: Named Path Parameters & Wildcard)
你可以注冊(cè)一個(gè)處理器(handler)并對(duì)應(yīng)一個(gè)動(dòng)態(tài)路徑路由(router)。
下面是命名路徑參數(shù)的例子:
"/user/{username}" matches to "/user/me", "/user/speedwheel" etc
路徑參數(shù) "username"的值分別是 "/me"和 "speedwheel"。
下面是通配符的例子:
"/user/{path *wildcard}" matches to
"/user/some/path/here",
"/user/this/is/a/dynamic/multi/level/path" etc
路徑參數(shù) path 的值分別是 "some/path/here" 和 "
this/is/a/dynamic/multi/level/path"。
Iris 也支持一種叫 macros 的功能,可以描述為 /user/{username:string} 或 /user/{username:int min(1)}
路由:正則表達(dá)式(Router: Regex)
你可以注冊(cè)一個(gè)處理器(handler)并對(duì)應(yīng)一個(gè)包含過濾器(filter)的動(dòng)態(tài)路徑路由(router)。過濾器會(huì)過濾掉一些傳給處理器的參數(shù)值。
下面是一個(gè)例子:
"/user/{id ^[0-9]$}" matches to "/user/42" but not to "/user/somestring"
路徑參數(shù) id 的值是整數(shù) 42 (而不會(huì)是字符串)。
路由:分組(Router: Grouping)
你可以注冊(cè)通用邏輯或中間件/處理器(middlewar/handler)并對(duì)應(yīng)一組共享相同路徑前綴的路由(router)。
下面是一個(gè)例子:
- /user
- /user/profile
- /user/signup
你甚至可以在分組(group)中再創(chuàng)建子分組(subgroup)
myGroup.Group("/messages", optionalUserMessagesMiddleware)
myGroup.Handle("GET', "/{id}", getMessageByID)
- /user/messages/{id}
路由:隨意組合以上選項(xiàng)而不用擔(dān)心沖突(Router: All the above Mixed Without Conflict)
這是一個(gè)先進(jìn)且很有用的功能,我們很多人希望路由或Web框架支持該功能,但目前在Go環(huán)境里只有Iris支持。
這意味著像 /{path *wildcard},
/user/{username}, /user/static
和 /user/{path *wildcard} 可以注冊(cè)在同一個(gè)路由里而且可以被正確地映射到靜態(tài)路徑 (/user/static) 或 通配符 (/{path *wildcard})
路由:自定義HTTP錯(cuò)誤(Router: Custom HTTP Errors)
你可以注冊(cè)一個(gè)處理器(handler)并對(duì)應(yīng)一個(gè)’錯(cuò)誤’代碼。 HTTP 錯(cuò)誤代碼是一個(gè) >=400 的狀態(tài)碼,例如 NotFound 404。
下面是一個(gè)例子:
上面的大多數(shù)Web框架只支持注冊(cè) 404,405 和 500 錯(cuò)誤代碼,但是像 Iris,
Beego和 Revel 這些提供完整功能的框架支持任何狀態(tài)代碼甚至 任何錯(cuò)誤(any error)代碼(只有Iris支持 任何錯(cuò)誤 )。
100%與 net/http 兼容(100%
compatible with net/http)
這意味著:
- 框架提供了上下文(context)讓你可以直接訪問 *http.Request和 和 http.ResponseWriter。
- 你可以把 net/http 處理器(handler)轉(zhuǎn)化到一個(gè)特定框架下的處理器(Handler)。
中間件生態(tài)系統(tǒng)(Middleware ecosystem)
你可以不用自己來為每個(gè)處理器包裝中間件,但是框架提供給你一個(gè)完整的引擎來定義流程,無論是全局的或每個(gè)路由或每組路由,例如 Use(middleware), Done(middleware) 等。
Sinatra風(fēng)格的API(Sinatra-like API)
在運(yùn)行時(shí)注冊(cè)處理器來處理特定HTTP方法的路由(和路徑參數(shù))。
下面是一個(gè)例子:
服務(wù)器: 自動(dòng)HTTPS(Server: Automatic HTTPS)
框架的服務(wù)器支持注冊(cè)和自動(dòng)更新SSL證書來管理SSL/TLS傳入連接(https)。最著名的自動(dòng)HTTPS提供者是letsencrypt。
服務(wù)器: 正常關(guān)機(jī)(Server: Gracefully Shutdown)
當(dāng)按下 CTRL+C 關(guān)閉終端應(yīng)用程序時(shí),服務(wù)器將正常地停止,它會(huì)等待一些連接完成它們的工作(在設(shè)定的時(shí)間內(nèi)),或者觸發(fā)一個(gè)自定義的事件來做清理(例如關(guān)閉數(shù)據(jù)庫)。
服務(wù)器: 多監(jiān)聽器(Server: Multi Listeners)
框架的服務(wù)器支持注冊(cè)自定義 net.Listener 或者可以通過多個(gè) http 服務(wù)器和地址來服務(wù)web應(yīng)用。
完全支持HTTP/2(Full HTTP/2)
框架支持HTTP/2,包括https和服務(wù)器 Push 功能。
子域(Subdomains)
你可以直接在你的Web應(yīng)用里按子域(subdomain) 直接注冊(cè)路由。
secondary 是指框架不支持該功能但是你依然可以通過啟用多個(gè)http服務(wù)器來實(shí)現(xiàn)。壞處是主應(yīng)用程序和子域并不相連而且默認(rèn)情況下它們并不直接共享邏輯。
會(huì)話(Sessions)
http會(huì)話被支持并可以在你的特定處理器中使用。
- 一些Web框架支持使用后臺(tái)數(shù)據(jù)庫來存儲(chǔ)會(huì)話,以便在服務(wù)器重啟之間獲得持久性。
- Buffalo 使用 gorrila 會(huì)話,這比其他的實(shí)現(xiàn)要慢一點(diǎn)點(diǎn)。
下面是一個(gè)例子:
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通信協(xié)議。實(shí)現(xiàn)是各不相同的。
你應(yīng)該搜索他們的例子,看看有什么適合你。我的同事嘗試了所有框架后告訴我,與其他框架相比,Iris實(shí)現(xiàn)了功能更強(qiáng)大且更簡(jiǎn)單的webosocket連接。
Wiki: https://en.wikipedia.org/wiki/WebSocket
App 內(nèi)置視圖/模板(View/Templates)
通常情況下,你必須將所有模板文件與你的Web應(yīng)用程序的可執(zhí)行文件一起打包。應(yīng)用程序App 內(nèi)置意味著該框架支持與go-bindata的集成,所以最終的可執(zhí)行文件包含模板,表示為 []byte。
什么是視圖引擎
框架支持模板加載,模板自定義和自帶模板并能在一些關(guān)鍵工作上幫助我們。
視圖引擎:STD(View Engine: STD)
框架支持標(biāo)準(zhǔn) 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…
框架的上下文為你提供了一種輕松地發(fā)送和定制各種內(nèi)容類型的響應(yīng)結(jié)果的簡(jiǎn)便方法。
MVC
模型-視圖-控制器(MVC)是在計(jì)算機(jī)上實(shí)現(xiàn)用戶界面的軟件架構(gòu)模式。它將一個(gè)給定的應(yīng)用程序分成三個(gè)相互關(guān)聯(lián)的部分。這樣做是為了將信息的內(nèi)部表示與信息呈現(xiàn)給用戶并讓用戶接受的方式分離開來。MVC設(shè)計(jì)模式分離了這些主要成分并允許高效的代碼重用和并行開發(fā)。
- Iris支持完整的MVC功能,可以在運(yùn)行時(shí)注冊(cè)。
- Beego僅支持方法和模型匹配,可以在運(yùn)行時(shí)注冊(cè)。
- Revel支持方法、路徑和模型匹配,只能通過一個(gè)生成器注冊(cè)(一個(gè)用于構(gòu)建Web應(yīng)用程序的必要軟件)。
Wiki: https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
緩存(Caching)
Web緩存(或HTTP緩存)是一種信息技術(shù),用于臨時(shí)存儲(chǔ)(緩存)Web文檔,如HTML頁面和圖像,以減少服務(wù)器延遲。Web緩存系統(tǒng)記錄了網(wǎng)絡(luò)通信,如果滿足某些條件,后續(xù)請(qǐng)求的結(jié)果可以直接取自Web緩存。Web緩存系統(tǒng)既可以指設(shè)備,也可以指計(jì)算機(jī)程序。
Wiki: https://en.wikipedia.org/wiki/Web_cache
文件服務(wù)器(File Server)
你可以把一個(gè)(物理)目錄注冊(cè)到一個(gè)路由表,該路由表會(huì)自動(dòng)將目錄下的文件服務(wù)給客戶程序。
文件服務(wù)器: 內(nèi)置入APP(File Server: Embedded Into App)
通常你必須將所有靜態(tài)文件(如資源文件、css、JAVAScript文件…)和應(yīng)用程序的可執(zhí)行文件一起傳輸。支持此特性的框架使你有機(jī)會(huì)將所有這些數(shù)據(jù)嵌入到應(yīng)用程序中,表示為 []byte,它們的響應(yīng)時(shí)間也更快,因?yàn)榉?wù)器可以不用在物理位置上查找文件而直接服務(wù)。
響應(yīng)可以在發(fā)送之前在生命周期內(nèi)多次修改(Response can be Modified Many times through lifecycle before sent)
目前僅Iris可以通過http_context內(nèi)置的 response writer 支持該功能。
當(dāng)框架支持這一功能時(shí),你可以在發(fā)送給客戶端之前檢索,重置或修改的狀態(tài)代碼、正文和頭文件(在基于net/http的Web框架中,默認(rèn)情況下這是不可能的,因?yàn)檎暮蜖顟B(tài)代碼在寫入后無法檢索或更改)。
Gzip
你可以在路由的處理器里改變響應(yīng)writer來使用gzip壓縮,框架應(yīng)該設(shè)置返回結(jié)果的頭(header),并在出現(xiàn)任何錯(cuò)誤時(shí)重置writer,也應(yīng)該檢查客戶端是否支持gzip。
gzip是一種文件格式(也可以是一個(gè)軟件應(yīng)用),用于文件的壓縮和解壓縮軟件。
Wiki: https://en.wikipedia.org/wiki/Gzip
測(cè)試框架(Testing Framework)
你可以使用特定的框架測(cè)試HTTP,測(cè)試框架就是幫助你輕松地編寫更好的測(cè)試。
下面是一個(gè)例子(目前僅Iris支持)
myirisapp 返回一個(gè)你假定的Web應(yīng)用程序,
針對(duì)路徑 /admin 它有一個(gè)GET處理器并有基本的身份驗(yàn)證保護(hù)。
上面簡(jiǎn)單的測(cè)試檢查 /admin 請(qǐng)求是否返回狀態(tài)碼 Status OK 并驗(yàn)證特定的用戶名和密碼,最后檢查正文內(nèi)容是 “welcome”。
Typescript Transpiler
Typescript的目標(biāo)是成為一個(gè)ES6超集,除了標(biāo)準(zhǔn)定義的所有新東西,它將添加一個(gè)靜態(tài)類型系統(tǒng)(static type system)。Typescript也有一個(gè)轉(zhuǎn)換器(transpiler)將我們的Typescript代碼(即6 +類型)轉(zhuǎn)換到ES5或ES3標(biāo)準(zhǔn)上的JavaScript代碼,以便在目前的瀏覽器上運(yùn)行。
在線編輯器(Online Editor)
有了在線編輯器,你可以快速方便地編譯和運(yùn)行Go代碼。
日志系統(tǒng)(Logging System)
自定義日志系統(tǒng)系統(tǒng)可以擴(kuò)展原始日志包的功能,比如代碼配色、格式、日志級(jí)別的分隔,不同的登錄后臺(tái)等等。
維護(hù)和自動(dòng)更新(Maintenance & Auto-Updates)
以非侵入性的方式通知用戶“即時(shí)更新”。