項目中要不要使用 Go?我是這么思考的
我最近決定在一個新項目中使用 GoLang 來實現(xiàn)一組增刪改查的 API。在此之前,我較為熟悉 Java,Groovy,了解一些 Python。
我大部分的經(jīng)驗都是使用 Java 或者 Groovy 加上 Spring Boot。這讓我感到有些無聊,所以為什么不來學點兒東西找找樂子呢?
要求
以下是一些要求。
- 設(shè)計并實現(xiàn)領(lǐng)域數(shù)據(jù)模型
- 實現(xiàn)增刪改查 API
- 在后端使用 Mongo 數(shù)據(jù)庫
- 必須有 Swagger 文檔 API 定義并且能方便的用多種語言生成客戶端
- 運行在 Docker 容器中
- 能被部署在 Kubernetes 中
非功能性要求
- 需要能很容易的調(diào)用其它語言的 API
- 需要能夠快速迭代(可能要突破常規(guī))
- 必須有單元測試
加分項
- 保守的內(nèi)存消耗
- 這對于當我想在一個內(nèi)存受限的環(huán)境中(如一個 512 MB 內(nèi)存的樹莓派)運行程序時,是很重要的。
- 要有趣也要有學習體驗
使用的模塊和庫
作用模塊訪問數(shù)據(jù)庫mongo-go-drive路由go-chiREST API JSON Patch( 譯者注:RFC6902[1] 和 RFC7396[2])json-patch單元測試testifySwagger API 定義go-swagger
優(yōu)點
Go 語言與 C 和 Java 十分的相像。有 C 和 Java 的基礎(chǔ)能很容易的熟練掌握 Go 語言,完成一個入門項目。
我特別喜歡 Go 代碼的簡單明了。
公平來說,我也喜歡樣板代碼盡可能少的,備受好評的框架。我就十分喜歡 Java 11+ 或者 Groovy 與 Spring Boot,Spring Data,Lombok 項目,可能還有 Spring Data REST 的聯(lián)合使用。當然,有時候 Spring Boot Data REST 的魔法有點兒過猶不及了。
Go 的 'defer' 關(guān)鍵字可以說是我最喜歡的特性之一了。推遲一些操作直到函數(shù)退出才執(zhí)行這一特性,在關(guān)閉資源并記錄函數(shù)退出動作的日志方面十分有用。
不同點與不合適點
錯誤處理有點兒繁瑣。
錯誤處理對于 Java 背景的人來說有些不同。我發(fā)現(xiàn)在 Go 中它需要更明確。
在 Java 中,一個方法能拋出一個異常,也可以捕獲一個或多個異常,忽略它們(這樣做可能是錯誤的),或者重新拋出給調(diào)用者來處理。Go 需要使用先調(diào)用方法,然后判斷是否有錯誤發(fā)生這種模式。我們可以討論下這樣做好不好。
我發(fā)現(xiàn)對于 Go 的錯誤檢測和傳遞需要一段時間來適應(yīng)而且覺得有點繁瑣,但這樣肯定是能行的。
- // 我經(jīng)常在代碼中看到這樣的模式
- obj1, err := doohickey.doSomething(someArg)
- if err !=nil {
- log.Println("doohickey.doSomething got error error: ", err)
- return
- }
- obj2, err2 := widget.doSomethingElse(otherArg)
- if err2 !=nil {
- log.Println("Widget doSomethingElse returned error: ", err2)
- return
- }
- //...
JSON 響應(yīng)類型以及映射到結(jié)構(gòu)體
對于 Go,JSON 和 靜態(tài)類型,我發(fā)現(xiàn) Go 在如何處理動態(tài) JSON 和將其解析為結(jié)構(gòu)體方面有些笨拙和令人困惑。
這在 Groovy 和 Python 中相當容易,他們完全可以動態(tài)的把 JSON 轉(zhuǎn)換成其他東西的映射。
在 Go 中,將 JSON 反序列化為一個結(jié)構(gòu)并將其序列化回來,這與其他語言中的做法并沒有本質(zhì)上的不同。
成熟度進展
實際上,我在這方面并沒有發(fā)現(xiàn)它有什么不好的。正相反,我發(fā)現(xiàn)了一些期待的地方。因為 Go 仍然是一門相對比較新的語言,在一些領(lǐng)域它正在迎頭趕上。
Go 依賴和版本化模塊庫
因為以前使用過依賴管理和構(gòu)建工具,如 Java 的 Gradle 和 Maven,自然而然的我就想 Go 有同種水平的依賴管理。
在我寫本文時,GoLang 1.13[3] 支持谷歌的模塊代理,文檔上是這樣說的:
- 從 Go 1.13 開始,go 命令在默認情況下將使用由 Google 運行的 Go 模塊鏡像、 Go 檢驗和數(shù)據(jù)庫來進行模塊的下載與認證。參看 https://proxy.golang.org/privac[4] 來了解有關(guān)這些服務(wù)的隱私信息,參看 go 命令文檔[5] 了解怎么停止使用這些服務(wù)或者使用另外的服務(wù)的詳細配置。如果你依賴于一個不公開的模塊,參見 環(huán)境配置文檔[6]
結(jié)束語
令人驚訝的是,很容易地就可以掌握 GoLang 到實際生產(chǎn)的程度。我覺得它令人愉快而且很有趣。增強 REST API,精煉數(shù)據(jù)模型,生成 Swagger 文檔和創(chuàng)建單元測試都是很流行并舒服的體驗。
基于這次的經(jīng)歷,我越發(fā)的想學習 GoLang 了。