Golang是一門快速增長的語言,專為構建簡單、快速且可靠的軟件而設計。它提供的net/http庫對於HTTP協議實現非常好,基於此再構造框架會更容易,因此生態中出現了很多框架。本文將從流行度、社區支持及內建功能等角度對六款知名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 高性能、極簡Go語言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
流行度
學習曲線
astaxie 和 kataras 分別為 Beego 和 Iris 整理了許多例子供開發者參考學習
核心功能
幾個知名的Go語言Web框架(Echo、Gin和Buffalo)由於沒有完備支持所有功能,並不能算是真正意義上的Web框架,但大部分go社區認為它們是的,因此,有必要將這幾個框架也列在表格中可以和Iris、Beego、Revel做比較。以上這些框架,除了Beego和Revel之外,都可以適配任意net/http中間件,其中一部分框架可以輕鬆地做適配,另外一些可能就需要額外的努力
詞彙解析
路由: 命名參數和通配符 支持註冊動態路徑
命名路徑參數示例
// 路徑參數 username 取值分別是 me,speedwheel
"/user/{username}" 匹配到 "/user/me", "/user/speedwheel" 等等
通配符示例
// 路徑參數 path 對應的分別是 /user/some/path/here 和 /user/this/is/a/dynamic/multi/level/path
"/user/{path *wildcard}" 匹配到
"/user/some/path/here",
"/user/this/is/a/dynamic/multi/level/path" 等等
Iris也支持一個叫micros的功能,它可以被表示為 /user/{username: string} 或 /user/{username: int min(1)}
路由: 正則表達式 支持過濾動態路徑
"/user/{id ^[0-9]$}" 匹配到 "/user/42" 但不會匹配 "/user/somestring"
路由: 分組 通過共用邏輯或中間件來處理有共同前綴的路徑組
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}
路由: 以上所有規則相結合而不產生衝突 這是一個高級且有用的功能,目前在Go語言框架方面只有Iris能支持這一功能。這意味著類似如 /{path wildcard}, /user/{username}和/user/static以及/user/{path wildcard}等路徑都可以在同一個路由中通過靜態路徑/user/static或通配符/user/{path *wildcard}來正確匹配
路由: 自定義HTTP異常 指可以自行處理請求錯誤的情況。HTTP的錯誤狀態碼>=400,例如,請求的資源不存在 NotFound 404
OnErrorCode(404, myNotFoundHandler)
上述大多數Web框架只支持404,405及500錯誤狀態的處理,Iris能夠支持任意錯誤,Beego和Revel也能支持完備的HTTP錯誤狀態碼
100%兼容net/http包 這意味著
- 這些框架能夠直接訪問 *http.Request 和 http.ResponseWriter 的上下文信息
- 一種將net/http handler轉換為特定框架類型handler的方法
中間件生態系統 框架會為你提供一個完整的引擎來定義流程、全局、單個或一組路由,而不需要自己用不同的中間件來封裝每一部分的handlers
類Sinatra風格API 可以在運行時中注入代碼來處理特定的 HTTP 方法(以及路徑參數)
.Get or GET("/path", gethandler)
.Post or POST("/path", postHandler)
.Put or PUT("/path", putHandler) and etc.
服務器程序: 自動啟用HTTPS 框架的服務器支持註冊及自動更新SSL證書來管理新傳入的SSL/TLS連接(https)
服務器程序: 優雅關閉 當按下CTRL+C關閉終端應用程序時,服務器將等待(特定的超時時間)其他的連接完成相關任務或觸發一個自定義事件來做清理工作(比如: 關閉數據庫),最後優雅的終止服務
服務器程序: 多重監聽 框架的服務器支持自定義的net.Listener或使用多個http服務器和地址為web應用程序提供服務
完全支持HTTP/2 框架可以很好的處理https請求的http/2協議,並支持服務器push功能子域名 可以直接在Web應用中注入子域名的路徑
- 輔助功能 意味著這個功能並不被這個框架原生支持,但是你仍舊可以通過啟用多個 http 服務器來實現。缺點在於:主程序和子域名程序之間並不是連通的,默認情況下,它們不能共享邏輯
會話(Sessions) 支持HTTP Sessions,且可以在自定義的handlers中使用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通信協議,不同框架有不同的實現方式,其中Iris實現了websocket最多功能並提供了相對更容易使用的API
程序內嵌對視圖(模版)的支持 通常情況下,你必須根據 Web 應用的可執行文件一一對應地轉換模版文件。內嵌到應用中意味著這個框架集成了 go-bindata ,因此在最終的可執行文件中可以以 []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 緩存是一種用於臨時存儲(緩存)網頁文檔,如 HTML 頁面和圖像,來減緩服務器延時。一個 Web 緩存系統緩存網頁文檔,使得後續的請求如果滿足特定條件就可以直接得到緩存的文檔。Web 緩存系統既可以指設備,也可以指軟件程序
文件服務器 可以註冊一個(物理的)目錄到一個路徑,使得這個路徑下的文件可以自動地提供給客戶端
文件服務器: 內嵌入應用 通常情況下,必須將所有的靜態文件(比如assets: CSS, JavaScript 文件等)與應用程序的可執行文件一起傳輸。支持此項功能的框架為你提供了在應用中,以 []byte 的形式,內嵌所有這些數據的機會。由於服務器可以直接使用這些數據而無需在物理位置查找文件,它們的響應速度也將更快
響應在發送前可以在整個生命週期中修改多次 當框架支持此功能時,可以在返回給客戶端之前檢索、重置或修改狀態碼、body及headers。默認情況下,在基於 net/http 的 Web 框架中這是不可能的,因為正文和狀態碼一經寫定就不能被檢索或修改。目前只有 Iris 通過 http_context 中內建的的響應寫入器(response writer)支持這個功能
Gzip 在一個路由的handler中,並且可以改變響應寫入器(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返回虛構的Web應用,它有一個針對/admin路徑的GET方法,及基本的身份驗證邏輯保護。上面的簡單測試用例,用name和pass通過身份驗證並訪問GET /admin,檢查它的響應狀態是否為Status OK及響應體是否為welcome
TypeScript轉譯器
日誌系統 自定義日誌系統通過提供有用的功能,如日誌輸出、格式化、日誌級別分離及不同的日誌記錄後端等,來擴展原生日誌包
維護和自動更新 以非侵入的方式通知框架的用戶即時更新
小結
框架一直是敏捷開發中的利器,能讓開發者很快上手並作出應用。成長不會一蹴而就,會經歷從入門到深入,再到精通框架的過程,找到學習和應用它的價值,便不會入門就放棄了
閱讀更多 數字智能之能 的文章