我像“小馬過河”一樣升級了我的開源系統
前言
我在升級之前做了比較充分的準備工作,深入研究了GoFrame V2新特性才決定升級的,并且總結了一篇文章:# ??站在開發者的角度理解框架的設計思想??。
區別于官方文檔,我是站在開發者的角度,總結分享了V2版本相比于V1版本的優勢,實踐了我的有著130多個接口的# ??開源電商項目的升級踩坑之旅??,希望對大家有幫助。
目前開源電商系統V2版正在開發中,歡迎Star:https://github.com/wangzhongyang007/goframe-shop-v2
基于Gin+Gorm+VUE的集五福營銷裂變項目也在脫敏中,后面會開源出來供大家學習使用。
先說結論
我決定用我的開源項目# ??開源電商前后臺API系統 實踐升級之旅??。
這是一個單體項目,適合新手入門,開發了超過了130個接口,不管是新手入門還是實踐升級之旅都比較有代表性:包括了傳統電商需要的基本功能,也有進階高并發的解決方案。
歡迎Star:https://github.com/wangzhongyang007/goframe-shop
我最終結合自己的項目情況,決定用V2重寫開源項目,而不是用V1升級到V2,因為我的工程設計思想和V2建議的工程結構差別很大。
經過仔細考量后,我認為V2的工程架構更好,雖然門檻稍高一點,但是在項目后期更易于維護。
實踐出真知
我調研實操的經歷,還是非常有參考價值的,我的項目不適合從V1升級到V2,而是用V2重寫,并不代表你的項目不適合。這個經歷真的就像“小馬過河”一樣。
升級之旅
下面就介紹一下我的升級之旅:
1. 首先查看之前的版本:
2. 替換依賴庫
在工程文件中進行替換,把所有的:github.com/gogf/gf/ 全部替換為:github.com/gogf/gf/v2/
3.按提示解決錯誤
替換之后嘗試運行,肯定會出錯,但是沒關系,提示什么錯誤就解決什么錯誤嘛:
我嘗試根據提示執行 go get 相關依賴,但是并沒有生效。
4.升級框架和CLI工具
突然想到我只是替換了項目中的依賴包,但是并沒有更新GoFrame框架和GoFrame CLI工具。
而且通過查閱官方文檔得知:GoFrame是支持v1和v2同時使用的,但是官方并不建議,因為同時使用會導致維護成本很高。
注意:框架是框架,cli是cli,兩者不要混淆在一起。官方文檔有詳細介紹,不再重復闡述:官方文檔[1]
在升級CLI工具時踩了很多坑,因為通過查閱官方文檔,發現了很多種升級方式,但我在實踐中前幾種均未生效,最終是通過下面的方式升級成功的。
注意:如果是MacOS下使用zsh的小伙伴可能會遇到別名沖突問題,可以通過alias gf=gf來解決,運行一次之后gf工具會自動修改profile中的別名設置,用戶重新登錄(或者重開終端)就好了。
5. CLI升級成功
CLI升級安裝成功的示例圖:
查看gf cli版本 已經更新到了v2.2.0 最新版:
6.及時備份
因為升級CLI我花了好長時間,做了各種嘗試,所以我決定及時提交git做好備份,養成好習慣:
在解決了CLI升級問題之后,我真的長舒了一口氣。準備迎接新的挑戰吧:
7.gtoken升級
解決gtoken的問題還是很簡單的,升級gtoken就可以了,正如官方文檔所說gtoken已經全面擁抱GoFrame V2版本了:
安裝升級gtoken的教程如下:
- gopath模式:go get github.com/goflyfox/gtoken
- 使用go.mod添加:require github.com/goflyfox/gtoken latest
我是使用gopath模式安裝的,很順利;我們再繼續解決新的報錯:
8.gmvc問題
通過查閱文檔得知,gmvc已經廢除,以后也不再支持了:
9.最新版的gf CLI生成dao
準備迎接新的挑戰吧,用最新版的gf CLI生成dao:
并沒有迎接到暴風雨, 而是卡住了。
原因是這樣的,正如我開篇說的:
V2版本的工程目錄做了調整,官方說:如果你的V1項目使用的是GoFrame官方推薦的工程目錄結構,可以參考最新的工程目錄結構手動調整即可:工程目錄設計[2]。
需要注意的是,最新的cli工具不再支持舊版工程目錄的項目創建。
10.調整項目的目錄結構
我們需要調整項目的目錄結構,參考鏈接如下:https://GoFrame.org/pages/viewpage.action?pageId=30740166
我在項目根目錄下,新建internal目錄,然后執行 gf gen dao 還是很絲滑的。
11.分析V2的gf gen dao
我發現v2版本的cli不僅給我們生成了dao層,在model層中還細分了do層和entity層。
為什么這么設計,大家有時間可以看官方文檔:https://GoFrame.org/pages/viewpage.action?pageId=30740166
在這里我只說結論:
- dao層用于數據訪問,這是一層抽象對象,用于和底層數據庫交互,僅包含最基礎的 CURD 方法
- model層是結構模型,是數據結構管理模塊,管理數據實體對象,以及輸入與輸出數據結構定義。
model中的do是領域對象,用于dao數據操作中業務模型與實例模型轉換,由工具維護,用戶不能修改。
model中的entity是數據模型,數據模型是模型與數據集合的一對一關系,由工具維護,用戶不能修改。
12.再次備份
為了方便找回資料,我在修改目錄結構之前也在本地做了備份,方便我一會復制粘貼代碼,小伙伴們也可以借鑒一下。
13.調整目錄結構
官方建議的工程目錄
目錄/文件名稱 | 說明 | 描述 |
api | 對外接口 | 對外提供服務的輸入/輸出數據結構定義。考慮到版本管理需要,往往以api/v1...存在。 |
hack | 工具腳本 | 存放項目開發工具、腳本等內容。例如,CLI工具的配置,各種shell/bat腳本等文件。 |
internal | 內部邏輯 | 業務邏輯存放目錄。通過Golang internal特性對外部隱藏可見性。 |
- cmd | 入口指令 | 命令行管理目錄。可以管理維護多個命令行。 |
- consts | 常量定義 | 項目所有常量定義。 |
- controller | 接口處理 | 接收/解析用戶輸入參數的入口/接口層。 |
- dao | 數據訪問 | 數據訪問對象,這是一層抽象對象,用于和底層數據庫交互,僅包含最基礎的 CURD 方法 |
- logic | 業務封裝 | 業務邏輯封裝管理,特定的業務邏輯實現和封裝。往往是項目中最復雜的部分。 |
- model | 結構模型 | 數據結構管理模塊,管理數據實體對象,以及輸入與輸出數據結構定義。 |
- do | 領域對象 | 用于dao數據操作中業務模型與實例模型轉換,由工具維護,用戶不能修改。 |
- entity | 數據模型 | 數據模型是模型與數據集合的一對一關系,由工具維護,用戶不能修改。 |
- service | 業務接口 | 用于業務模塊解耦的接口定義層。具體的接口實現在logic中進行注入。 |
manifest | 交付清單 | 包含程序編譯、部署、運行、配置的文件。常見內容如下: |
- config | 配置管理 | 配置文件存放目錄。 |
- docker | 鏡像文件 | Docker鏡像相關依賴文件,腳本文件等等。 |
- deploy | 部署文件 | 部署相關的文件。默認提供了Kubernetes集群化部署的Yaml模板,通過kustomize管理。 |
resource | 靜態資源 | 靜態資源文件。這些文件往往可以通過 資源打包/鏡像編譯 的形式注入到發布文件中。 |
go.mod | 依賴管理 | 使用Go Module包管理的依賴描述文件。 |
main.go | 入口文件 | 程序入口文件。 |
因為我之前的目錄結構也不是嚴格按照goFrame v1.xx示例設計的,而是根據項目的前后端需求自定義設計的。
所以意識到了:要想順利升級,工作量還是非常大的,應該需要修改很多代碼。
我參考文檔修改了自己項目的目錄:
13.1 遷移api層
我把之前寫的對外接口相關的代碼放到api層:
13.2 替換dao和model被引用的路徑
遷移之后遇到了新問題:
咱們來分析一下,目前做的操作只是:
- 通過最新的gf cli工具在項目根目錄的internal目錄下生成了新的dao和model層;
- 刪除了之前app目錄下的dao層和model層。
那咱們全局替換一下imports的目錄不就行了:
全局替換dao和model的目錄:
- 把shop/app/dao替換為:shop/internal/dao
- 把shop/app/model替換為:shop/internal/model
OK,順利的解決了上面的問題。
14.解決神奇的問題
又遇到了新的問題:提示我 xxx is not in GOROOT。
我嘗試通過用goland打開我的go/src目錄,而不是直接打開shop工程目錄,來解決問題:
這招比較好用,項目的依賴不再全部飄紅,并且goland也給出了提示:
15.解決構建約束問題
分析一下原因:新的工程目錄使用了internal目錄,進行了約束。意思也就是除了對外暴露接口的方法放在api目錄,其他不需要對外的邏輯都要放在internal中:
好吧,啥也別說了,繼續修改:
我將之前處理業務邏輯的app目錄中的文件遷移到internal目錄中。
溫馨提示:你的項目是哪個目錄不重要,總之,按照GoFrame V2的原則,只有api目錄用于暴露給外部,不需要暴露給外部的邏輯全部放在internal目錄中:
16.項目工程目錄和V2建議的工程目錄統一
我結合自己的項目情況,移動和重命名了業務邏輯文件和目錄,整體還是很順滑的:
我之前的項目以library作為公共程序包,官方建議使用utility目錄,還是以官方為準吧,這樣以后在社區中溝通也能降低理解難度:
經過目錄調整,修改后的目錄結構和官方建議的目錄結構基本一致了:
然后繼續各種運行,報錯,解決錯誤,整體上都比較好解決,就不做記錄了。
值得分享的經驗就是:不要怕報錯多,整體看一遍,找找共同特點。絕大多數都是可以根據提示順利解決的問題。
17.遷移業務邏輯
在遷移業務邏輯時發現了新問題:
我通過研究V2的官方示例得知,service層內部每個文件都以接口的方式定義,且service層是能夠通過代碼自動生產的:
如何預定義接口需要實現的方法呢?
答案是:在logic層編寫代碼,通過工具生成對應的service文件;在logic層的init()方法中調用service層的RegisterXXX()方法進行服務注冊,由此可見復雜的邏輯都是在logic層處理的。
18. 通過CLI生成service
通過cli生成service是非常重要的操作,因為這部分代碼必須工具生成,所以我們要先了解這個知識點,先說我的結論:
- 業務模塊之間的依賴通過接口化解耦,將原有的service分類調整為接口目錄。這樣每個業務模塊將會各自維護、更加靈活。
- 該命令通過分析給定的logic業務邏輯模塊目錄下的代碼,自動生成service目錄接口代碼。
- 生成接口及服務注冊文件
更多介紹可以查看官方文檔:接口維護-gen service[3]
19. 反思
寫到這里,目前的心得體會是一定要搞清楚v2版本的設計思想,再從v1升級到v2,否則升級到一半會導致無從下手。
因為通過V2版本的CLI工具生成的dao、model 和v1版本版本是不一致的。
同時V2版本也支持gf gen service的方式,統一我們的接口維護方式。
再次強烈大家看我這篇文章:# 站在開發者的角度理解框架的設計思想
從框架開發者和使用者兩個角度去學習升級V2的知識點。
20.“分水嶺”問題
到這里是一個重要的分水嶺了:是升級遷移,還是直接用V2重寫,這個沒有標準答案,咱們應該在吃透了V2新特性和工程設計思想后,結合已有的項目特點去決定。
我結合自己的項目特點,經過仔細分析,再加上和GoFrame社區大佬們的溝通,我決定用GoFrame V2版本直接重寫,而不是在已有項目上做遷移。
因為我的項目結構和v2的設計思想差別太大了,升級無異于重寫,甚至可能花費的精力更多。
我開源項目的工程設計是這樣的:
- 首先在app目錄新建了system目錄,用于管理多個終端:
backend對應電商平臺的后臺接口
frontend對應電商平臺的前臺接口。
- 在每個終端下又都是按照功能模塊做了區分,每個功能模塊都會創建一個單獨的目錄。我們以admin目錄舉例:
- admin.go:定義請求和響應的結構體
- admin_api.go:定義了對外api的方法,調用下方admin_service.go中封裝的邏輯
- admin_service.go:編寫業務邏輯,通過dao操作DB
顯然,我的架構設計和GoFrame V2的工程設計思路差別是很大的,經過慎重思考,我決定基于V2最新版本重寫開源項目,也歡迎小伙們加入我們。
總結
在遇到“分水嶺”問題之前,GoFrame從v1升級到v2的過程還是比較順滑的。
我也在社區中和大家溝通了升級問題:有的大佬表示自己是新開一個項目用V2重寫的;有的大佬表示升級很簡單,就是目錄變更一下,業務邏輯還是可以用的,費不了多長時間。
這個問題就像“小馬過河”的故事一樣,大家還是要結合自己的項目情況:
- 如果你是按照V1版本建議的工程目錄或者你的設計思想本身就和V2版本比較契合,那就直接升級。
- 如果你像我一樣,已有項目的工程目錄和設計思路和V2版本有較大區別,并且在認真學習v2版本的工程實踐和新特性之后,覺得V2版本更適合你項目的后期維護迭代,那就抓緊用V2直接重寫項目吧。
相關資料
[1] 官方文檔: https://GoFrame.org/pages/viewpage.action?pageId=1115790
[2] 工程目錄設計: https://GoFrame.org/pages/viewpage.action?pageId=30740166
[3] 接口維護-gen service: https://GoFrame.org/pages/viewpage.action?pageId=49770772
[4] Go開源電商項目教程-教程大綱+開源地址: https://b23.tv/hdOpOTp
本文轉載自微信公眾號「 程序員升級打怪之旅」,作者「王中陽Go」,可以通過以下二維碼關注。
轉載本文請聯系「 程序員升級打怪之旅」公眾號。