本实践方案是一年前我整理的,当时是Go项目的技术选型方案,经过一年多的沉淀,我们团队基于这套方案成功上线了多个项目,而且基于这套方案团队开发效率大幅提升。
当然正如预计的我们现在的很多项目,上线后也在向微服务架构慢慢拆分一些功能模块
本实践方案算是已经得到了充足的验证,现在分享给大家,喜欢拿走
技术选型
项目由0-1,前期上线时最好是做成单体架构应用,然后上线后,根据业务调整与拆分系统架构,向微服务架构逐步转型演化,当然我的理解这才是一个正常项目的架构演化之路,架构不可能一步到位。
最终决定使用go-zero开发一个单体应用, 选择它的主要原因有两个:
- goctl工具
- 考虑业务可能快速上升的情况下, 微服务拆分扩展方便
goctl工具是主要原因, 听说它可以大大提高开发效率, 这个也在后面的实践中得到了验证, 向go-zero团队致敬,送出大写的牛.
目前达到的效果
- 根据sql文件生成model文件,不做任何更改; sql调整重新生成
- 编写API配置,生成handler/logic/router, handler/router里的不做任何更改,支持重新生成; 只编写logic业务逻辑部署的代码和调整svc/servicecontext.go注入model
如何做
步骤如下
- goctl模板修改
- 全局异常处理
- 解决跨域问题
- 基于数据模型做模块划分
- 前后端接口文件隔离
- swagger接口文档生成
goctl的模板修改
模板使用: https://github.com/vmee/goctl-template
模板修改主要有两处:
一是, api的handler.tpl模板, 这个主要是为了统一接口返回数据格式, 具体请参考
二是, model下的模板, 因为官方默认的模板太简单了, 想少写些sql操作相关的代码;
全局错误处理
首先 pkg包的代码我是从这里直接拷贝过来的https://github.com/zhoushuguang/lebron/blob/main/pkg
下面几个我用到的
- errx: 错误定义
- tool: md5
- result: 全局错误处理和统一返回数据格式
如何实现参考了以下:
解决跨域问题
我用的方法, app.go
server := rest.MustNewServer(c.RestConf,
rest.WithCors(), // 加上它就可以跨域了
rest.WithUnauthorizedCallback(middleware.NewUnauthorizedMiddleware().Handler()),
)
defer server.Stop()
其他方案
注意:
在实际开发中,只会编写以下业务逻辑代码,其他代码全部自动生成
- 编写api配置
- yaml配置文件和config.go
- middware中间件
- 通用中间件
基于数据模型分类做模块划分
-- 数据库表前缀说明
-- cms_*:内容管理模块相关表
-- oms_*:订单管理模块相关表
-- pms_*:商品模块相关表
-- sms_*:营销模块相关表
-- ums_*:会员模块相关表
-- sys_*:系统模块相关表
目录结构如下
- api
- cms
- sys
- ums
生成的handler和logic也都是这个目录结构
前后端接口文件隔离
api文件如结构如下
- api
- cms
- sys
- ums
- user
- user.api
- back.api
- front.api
- user
说明
- user.api 是定义通用的type块
- back.api 是定义后台的api
- front.api 是定义h5/app的api
swagger文档生成
生成swagger.json
goctl api plugin -plugin goctl-swagger=“swagger -filename app.json -host localhost:8888/ -basepath /” -api app/api/app.api -dir ./doc/swagger
用docker启动swagger-ui
docker run --rm -p 8083:8080 -e SWAGGER_JSON=/foo/doc/swagger/app.json -v $PWD:/foo swaggerapi/swagger-ui
访问http://localhost:8083就可以查看swagger文档和调试了