爆肝5千字实践出来的干货经验,希望对大家有帮助。
我在升级之前做了比较充分的准备工作,深入研究了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重写,并不代表你的项目不适合。这个经历真的就像“小马过河”一样。
下面就介绍一下我的升级之旅:
在工程文件中进行替换,把所有的:github.com/gogf/gf/
全部替换为:github.com/gogf/gf/v2/
替换之后尝试运行,肯定会出错,但是没关系,提示什么错误就解决什么错误嘛:
我尝试根据提示执行 go get 相关依赖,但是并没有生效。
突然想到我只是替换了项目中的依赖包,但是并没有更新GoFrame框架和GoFrame CLI工具。
而且通过查阅官方文档得知:GoFrame是支持v1和v2同时使用的,但是官方并不建议,因为同时使用会导致维护成本很高。
注意:框架是框架,cli是cli,两者不要混淆在一起。官方文档有详细介绍,不再重复阐述:官方文档[1]
在升级CLI工具时踩了很多坑,因为通过查阅官方文档,发现了很多种升级方式,但我在实践中前几种均未生效,最终是通过下面的方式升级成功的。
wget -O gf https://github.com/gogf/gf/releases/latest/download/gf_$(go env GOOS)_$(go env GOARCH) && chmod +x gf && ./gf install -y && rm ./gf
注意:如果是MacOS下使用zsh的小伙伴可能会遇到别名冲突问题,可以通过alias gf=gf来解决,运行一次之后gf工具会自动修改profile中的别名设置,用户重新登录(或者重开终端)就好了。
CLI升级安装成功的示例图:
查看gf cli版本 已经更新到了v2.2.0 最新版:
因为升级CLI我花了好长时间,做了各种尝试,所以我决定及时提交git做好备份,养成好习惯:
在解决了CLI升级问题之后,我真的长舒了一口气。准备迎接新的挑战吧:
解决gtoken的问题还是很简单的,升级gtoken就可以了,正如官方文档所说gtoken已经全面拥抱GoFrame V2版本了:
安装升级gtoken的教程如下:
我是使用gopath模式安装的,很顺利;我们再继续解决新的报错:
通过查阅文档得知,gmvc已经废除,以后也不再支持了:
准备迎接新的挑战吧,用最新版的gf CLI生成dao:
并没有迎接到暴风雨, 而是卡住了。
原因是这样的,正如我开篇说的:
V2版本的工程目录做了调整,官方说:如果你的V1项目使用的是GoFrame官方推荐的工程目录结构,可以参考最新的工程目录结构手动调整即可:工程目录设计[2]。
需要注意的是,最新的cli工具不再支持旧版工程目录的项目创建。
我们需要调整项目的目录结构,参考链接如下:https://GoFrame.org/pages/viewpage.action?pageId=30740166
我在项目根目录下,新建internal目录,然后执行 gf gen dao 还是很丝滑的。
我发现v2版本的cli不仅给我们生成了dao层,在model层中还细分了do层和entity层。
为什么这么设计,大家有时间可以看官方文档:https://GoFrame.org/pages/viewpage.action?pageId=30740166
在这里我只说结论:
为了方便找回资料,我在修改目录结构之前也在本地做了备份,方便我一会复制粘贴代码,小伙伴们也可以借鉴一下。
官方建议的工程目录
目录/文件名称 | 说明 | 描述 |
---|---|---|
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示例设计的,而是根据项目的前后端需求自定义设计的。
所以意识到了:要想顺利升级,工作量还是非常大的,应该需要修改很多代码。
我参考文档修改了自己项目的目录:
我把之前写的对外接口相关的代码放到api层:
迁移之后遇到了新问题:
咱们来分析一下,目前做的操作只是:
那咱们全局替换一下imports的目录不就行了:
全局替换dao和model的目录:
OK,顺利的解决了上面的问题。
又遇到了新的问题:提示我 xxx is not in GOROOT。
我尝试通过用goland打开我的go/src目录,而不是直接打开shop工程目录,来解决问题:
这招比较好用,项目的依赖不再全部飘红,并且goland也给出了提示:
分析一下原因:新的工程目录使用了internal目录,进行了约束。意思也就是除了对外暴露接口的方法放在api目录,其他不需要对外的逻辑都要放在internal中:
好吧,啥也别说了,继续修改:
我将之前处理业务逻辑的app目录中的文件迁移到internal目录中。
温馨提示:你的项目是哪个目录不重要,总之,按照GoFrame V2的原则,只有api目录用于暴露给外部,不需要暴露给外部的逻辑全部放在internal目录中:
我结合自己的项目情况,移动和重命名了业务逻辑文件和目录,整体还是很顺滑的:
我之前的项目以library作为公共程序包,官方建议使用utility目录,还是以官方为准吧,这样以后在社区中沟通也能降低理解难度:
经过目录调整,修改后的目录结构和官方建议的目录结构基本一致了:
然后继续各种运行,报错,解决错误,整体上都比较好解决,就不做记录了。
值得分享的经验就是:不要怕报错多,整体看一遍,找找共同特点。绝大多数都是可以根据提示顺利解决的问题。
在迁移业务逻辑时发现了新问题:
我通过研究V2的官方示例得知,service层内部每个文件都以接口的方式定义,且service层是能够通过代码自动生产的:
如何预定义接口需要实现的方法呢?
答案是:在logic层编写代码,通过工具生成对应的service文件;在logic层的init()方法中调用service层的RegisterXXX()方法进行服务注册,由此可见复杂的逻辑都是在logic层处理的。
通过cli生成service是非常重要的操作,因为这部分代码必须工具生成,所以我们要先了解这个知识点,先说我的结论:
更多介绍可以查看官方文档:接口维护-gen service[3]
写到这里,目前的心得体会是一定要搞清楚v2版本的设计思想,再从v1升级到v2,否则升级到一半会导致无从下手。
因为通过V2版本的CLI工具生成的dao、model 和v1版本版本是不一致的。
同时V2版本也支持gf gen service的方式,统一我们的接口维护方式。
再次强烈大家看我这篇文章:# 站在开发者的角度理解框架的设计思想
从框架开发者和使用者两个角度去学习升级V2的知识点。
到这里是一个重要的分水岭了:是升级迁移,还是直接用V2重写,这个没有标准答案,咱们应该在吃透了V2新特性和工程设计思想后,结合已有的项目特点去决定。
我结合自己的项目特点,经过仔细分析,再加上和GoFrame社区大佬们的沟通,我决定用GoFrame V2版本直接重写,而不是在已有项目上做迁移。
因为我的项目结构和v2的设计思想差别太大了,升级无异于重写,甚至可能花费的精力更多。
我开源项目的工程设计是这样的:
显然,我的架构设计和GoFrame V2的工程设计思路差别是很大的,经过慎重思考,我决定基于V2最新版本重写开源项目,也欢迎小伙们加入我们。
在遇到“分水岭”问题之前,GoFrame从v1升级到v2的过程还是比较顺滑的。
我也在社区中和大家沟通了升级问题:有的大佬表示自己是新开一个项目用V2重写的;有的大佬表示升级很简单,就是目录变更一下,业务逻辑还是可以用的,费不了多长时间。
这个问题就像“小马过河”的故事一样,大家还是要结合自己的项目情况:
就业环境不好,更要努力提高自己,一起拥抱开源,一起抱团取暖,我也在B站分享了免费的视频教程,欢迎大家学起来。
Go开源电商项目教程-教程大纲+开源地址[4]:https://b23.tv/hdOpOTp
[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