6 款最棒的 Go 語言 Web 框架簡介



https://twitter.com/ThePracticalDev/status/930878898245722112

如果你只是想寫一個自己用的小網站,或許你不需要框架,但如果你是要開發一個投入生產運營的網站,那么你肯定會需要一個框架,而且是需要一個好的 Web 框架。

如果你已經掌握所有必要的知識和經驗,你會冒險自己去重新開發所有的功能么?你有時間去找滿足生產級別要求的庫來用於開發么?另外,你確定這個庫可以滿足你后續所有的要求?

這些都是促使我們去使用框架的原因,哪怕是那些最牛的開發者也不會一直想要重新造輪子,我們可以站在前人的肩膀上,走得更快更好。

介紹

Go 是一門正在快速增長的編程語言,專為構建簡單、快速且可靠的軟件而設計。 點擊 此處 查看有哪些優秀的公司正在使用 Go 語言來驅動他們的業務。

本文將會提供一切必要的信息來幫助開發人員了解更多關於使用 Go 語言來開發 Web 應用程序的最佳選擇。

本文包含了最詳盡的框架比較,從流行度、社區支持及內建功能等多個不同角度出發做對比。

Beego開源的高性能 Go 語言 Web 框架。

Buffalo使用 Go 語言快速構建 Web 應用。

Echo簡約的高性能 Go 語言 Web 框架。

GinGo 語言編寫的 Web 框架,以更好的性能實現類似 Martini 框架的 API。

Iris全宇宙最快的 Go 語言 Web 框架。完備 MVC 支持,未來盡在掌握。

RevelGo 語言的高效、全棧 Web 框架。

流行度

按照流行度排行(根據 GitHub 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 分別為 Beego 和 Iris 做了超棒的工作,希望其他的框架也能迎頭趕上,為開發者提供更多的例子。至少對於我來說,如果我要切換到一個新的框架,那些例子就是最豐富的資源,來獲取盡可能多的有用信息。一個實例勝千言啊。

核心功能

根據功能支持的多寡排行

https://github.com/speedwheel/awesome-go-web-frameworks/blob/master/README.md#core-features

幾個知名的 Go 語言 Web 框架並不是真正意義上的框架,也就是說: EchoGin 和 Buffalo 並不是真正意義上的 Web 框架(因為沒有完備支持所有功能)但是大部分的 Go 社區認為它們是的,因此這些框架也可以和 IrisBeego 或 Revel 做比較。所以,我們有義務將這幾個框架(EchoGin 和 Buffalo)也列在這個表中。

以上所有這些框架,除了 Beego 和 Revel 之外,都可以適配任意 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"

Iris 也支持一個叫 macros 的功能,它可以被表示為 /user/{username:string} 或者 /user/{username:int min(1)}

路由:正則表達式

過濾動態的路徑。

例如:

"/user/{id ^[0-9]$}" 能匹配 "/user/42" ,但不會匹配 "/user/somestring"

這里的路徑參數 id 的值為 42

路由:分組

通過共用邏輯或中間件來處理有共同前綴的路徑組。

例如:

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 錯誤

指可以自行處理請求錯誤的情況。 Http 的錯誤狀態碼均 >=400 ,比如 NotFound 404,請求的資源不存在。

例如:

OnErrorCode(404, myNotFoundHandler) 

上述的大多數 Web 框架只支持 404405 及 500 錯誤狀態的處理,但是例如 Iris,Beego 和 Revel 等框架,它們完備支持 HTTP 錯誤狀態碼,甚至支持 any error 任意錯誤。( any error -- 任意錯誤,只有 Iris 能夠支持)。

100% 兼容 net/http

這意味著:

  • 這些框架能夠讓你直接獲取 *http.Request 和 http.ResponseWriter 的所有相關信息。
  • 各框架提供各自相應處理 net/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 服務和地址的 Web 應用。

完全支持 HTTP/2

框架可以很好地支持處理 https 請求的 HTTP/2 協議,並且支持服務器 Push 功能。

子域名

你可以直接在你的 Web 應用中注入子域名的路徑。

輔助功能(secondary) 意味着這個功能並不被這個框架原生支持,但是你仍舊可以通過啟用多個 http 服務器來實現。這樣做的缺點在於:主程序和子域名程序之間並不是連通的,默認情況下,它們不能共享邏輯。

會話(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) } 

Wiki: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#HTTP_session

網絡套接字(Websockets)

框架支持 websocket 通信協議。不同的框架對於這點有各自不同的實現方式。

你應該通過它們的例子來看看哪個適合你。我的一個同事,在試過了上述所有框架中的 websocket 功能之后告訴我:Iris 實現了最多的 websocket 特性,並且提供了相對更容易使用的 API 。

Wiki: https://en.wikipedia.org/wiki/WebSocket

程序內嵌對視圖(又名模版)的支持

通常情況下,你必須根據 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 應用)。

Wiki: https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

緩存

Web 緩存(或 http 緩存)是一種用於臨時存儲(緩存)網頁文檔,如 HTML 頁面和圖像,來減緩服務器延時。一個 Web 緩存系統緩存網頁文檔,使得后續的請求如果滿足特定條件就可以直接得到緩存的文檔。Web 緩存系統既可以指設備,也可以指軟件程序。

Wiki: https://en.wikipedia.org/wiki/Web_cache

文件服務器

可以注冊一個(物理的)目錄到一個路徑,使得這個路徑下的文件可以自動地提供給客戶端。

文件服務器:內嵌入應用

通常情況下,你必須將所有的靜態文件(比如靜態資產,assets:CSS,JavaScript 文件等)與應用程序的可執行文件一起傳輸。支持此項功能的框架為你提供了在應用中,以 []byte 的形式,內嵌所有這些數據的機會。由於服務器可以直接使用這些數據而無需在物理位置查找文件,它們的響應速度也將更快。

響應可以在發送前的生命周期中被多次修改

目前只有 Iris 通過 http_context 中內建的的響應寫入器(response writer)支持這個功能。

當框架支持此功能時,你可以在返回給客戶端之前檢索、重置或修改狀態碼、正文(body)及頭部(headers)。默認情況下,在基於 net/http 的 Web 框架中這是不可能的,因為正文和狀態碼一經寫定就不能被檢索或修改。

Gzip

當你在一個路由的處理程序中,並且你可以改變響應寫入器(response writer)來發送一個用 gzip 壓縮的響應時,框架會負責響應的頭部。如果發生任何錯誤,框架應該把響應重置為正常,框架也應該能夠檢查客戶端是否支持 gzip 壓縮。

gzip 是用於壓縮和解壓縮的文件格式和軟件程序。

Wiki: https://en.wikipedia.org/wiki/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 轉譯器

TypeScript 的目標是成為 ES6 的超集。除了標准定義的所有新特性外,它還增加了靜態類型系統。TypeScript 還有轉換器用於將 TypeScript 代碼(即 ES6 + 類型)轉換為 ES5 或 ES3 JavaScript 代碼,如此我們就可以在現今的瀏覽器中運行這些代碼了。

在線編輯器

在在線編輯器的幫助下,你可以快速輕松地在線編譯和運行代碼。

日志系統

自定義日志系統通過提供有用的功能,如彩色日志輸出、格式化、日志級別分離及不同的日志記錄后端等,來擴展原生日志包。

維護和自動更新

以非侵入的方式通知框架的用戶即時更新。

再見!

謝謝你的閱讀,如果你喜歡這篇文章,請用表情符號和我互動哦 :smile:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM