基于go语言gin框架的web项目骨架
前言
这里简单概述这个项目的大概的逻辑,以及使用的技术,后续分模块,分技术点去讲解,主要是达到整体理解。
项目结构目录
项目布局推荐:Go 项目标准布局(结构)
├─app
│ ├─aop // Aop切面demo代码段
│ │ └─users
│ │ destroy_after.go
│ │ destroy_before.go
│ │
│ ├─core // 程序容器部分、用于表单参数器注册、配置文件存储等
│ │ ├─container //构造一个键值对存储的容器 (存储验证器,管理配置文件的参数)
│ │ │ container.go
│ │ │
│ │ ├─destroy//优雅的退出
│ │ │ destroy.go
│ │ │
│ │ └─event_manage
│ │ event_manage.go
│ │
│ ├─global // 全局变量以及常量、程序运行错误定义
│ │ ├─consts //全局返回码与信息
│ │ │ consts.go
│ │ │
│ │ ├─my_errors //全局的错误信息
│ │ │ my_errors.go
│ │ │
│ │ └─variable //全局变量
│ │ variable.go
│ │
│ ├─http // http相关代码段,主要为控制器、中间件、表单参数验证器
| |-- http
│ │ ├─controller //控制器
│ │ │ ├─api //门户显示
│ │ │ │ home_controller.go
│ │ │ │
│ │ │ ├─chaptcha //验证码
│ │ │ │ chaptcha.go
│ │ │ │
│ │ │ ├─web //web控制器
│ │ │ │ upload_controller.go //上传下载
│ │ │ │ users_controller.go //user相关api控制器
│ │ │ │
│ │ │ └─websocket
│ │ │ ws.go
│ │ │
│ │ ├─middleware //中间件
│ │ │ ├─authorization //鉴权
│ │ │ │ auth.go
│ │ │ │
│ │ │ ├─cors //跨域
│ │ │ │ cors.go
│ │ │ │
│ │ │ └─my_jwt //创建jwt
│ │ │ custom_claims.go
│ │ │ my_jwt.go
│ │ │
│ │ └─validator //参数校验
│ │ ├─api //门户类校验
│ │ │ └─home
│ │ │ news.go
│ │ │
│ │ ├─common //
│ │ │ ├─data_type
│ │ │ │ common_data_type.go
│ │ │ │
│ │ │ ├─register_validator
│ │ │ │ api_register_validator.go
│ │ │ │ web_register_validator.go
│ │ │ │
│ │ │ ├─upload_files
│ │ │ │ upload_fiels.go
│ │ │ │
│ │ │ └─websocket
│ │ │ connect.go
│ │ │
│ │ ├─core
│ │ │ ├─data_transfer
│ │ │ │ data_transfer.go
│ │ │ │
│ │ │ ├─factory
│ │ │ │ factory.go
│ │ │ │
│ │ │ └─interf
│ │ │ interf.go
│ │ │
│ │ └─web
│ │ └─users
│ │ data_type.go
│ │ destroy.go
│ │ login.go
│ │ refresh_token.go
│ │ register.go
│ │ show.go
│ │ store.go
│ │ update.go
│ │
│ ├─model // 数据库表模型
│ │ base_model.go //选择数据库
│ │ users.go //操作数据
│ │ users_for_mysql.txt
│ │
│ ├─service // 常用的服务
│ │ ├─sys_log_hook //日志的处理(推送到阿里云日志管理面板、ElasticSearch 日志库)
│ │ │ zap_log_hooks.go
│ │ │
│ │ ├─upload_file //下载
│ │ │ upload_file.go
│ │ │
│ │ ├─users //y
│ │ │ ├─curd
│ │ │ │ users_curd.go
│ │ │ │
│ │ │ └─token
│ │ │ token.go
│ │ │
│ │ └─websocket
│ │ ws.go
│ │
│ └─utils // 第三方包封装层
│ ├─casbin_v2
│ │ casbin_v2.go
│ │
│ ├─data_bind
│ │ formdata_to_model.go
│ │
│ ├─files
│ │ baseInfo.go
│ │
│ ├─gorm_v2
│ │ client.go
│ │ config_params.go
│ │ custom_log.go
│ │
│ ├─md5_encrypt //密码加密
│ │ md5_encrypt.go
│ │
│ ├─observer_mode
│ │ observer.go
│ │ subject.go
│ │
│ ├─rabbitmq //消息代理
│ │ ├─hello_world
│ │ │ consumer.go
│ │ │ producer.go
│ │ │
│ │ ├─publish_subscribe
│ │ │ consumer.go
│ │ │ producer.go
│ │ │
│ │ ├─routing
│ │ │ consumer.go
│ │ │ producer.go
│ │ │
│ │ ├─topics
│ │ │ consumer.go
│ │ │ producer.go
│ │ │
│ │ └─work_queue
│ │ consumer.go
│ │ producer.go
│ │
│ ├─redis_factory
│ │ client.go
│ │
│ ├─response //对返回数据信息进行封装
│ │ response.go
│ │
│ ├─snow_flake //雪花算法
│ │ │ snow_flake.go //生产雪花算法对象的工厂
│ │ │
│ │ └─snowflake_interf //雪花算法工厂接口
│ │ InterfaceSnowFlake.go
│ │
│ ├─websocket
│ │ └─core
│ │ client.go
│ │ hub.go
│ │
│ ├─yml_config
│ │ │ yml_config.go //生产yml的对象的工厂
│ │ │
│ │ └─ymlconfig_interf //yml工厂的接口
│ │ yml_conf_interf.go
│ │
│ └─zap_factory // 创建zap对象
│ zap_factory.go
│
├─bootstrap // 项目启动初始化代码段
│ init.go
│
├─cmd // 项目入口,分别为门户站点、命令模式、web后端入口文件
│ ├─api
│ │ main.go
│ │
│ ├─cli
│ │ main.go
│ │
│ └─web
│ main.go
├─config // 项目、数据库参数配置
│ config.yml
│ gorm_v2.yml
│
├─database //数据库结构与数据文件
│ db_demo_mysql.sql
│
├─docs //文档
│
├─routers // 后台和门户网站路由
│ api.go
│ web.go
│
├─storage // 日志、资源存储目录
│
└─test //单元测试
1.项目初始化
// 这里主要介绍 init 函数的主要功能
func init() {
// 1.初始化 项目根路径
// 2.检查配置文件以及日志目录等非编译性的必要条件
// 3.初始化表单参数验证器,注册在容器
// 4.启动针对配置文件(confgi.yml、gorm_v2.yml)变化的监听
// 5.初始化全局日志句柄,并载入日志钩子处理函数
// 6.根据配置初始化 gorm mysql 全局 *gorm.Db
// 7.雪花算法全局变量
// 8.websocket Hub中心启动
}
gin框架是一个比较简单的web框架,大部分的功能和需求都需要去引用第三方库。这里需要一个初始化文件,将必要的第三方库进行初始化,方便后续使用。
不同第三方库会用不同的配置,推荐创建一个config 文件建立yaml 文件管理相关的配置。
推荐viper去进行管理配置
推荐学习博客:Go语言配置管理神器——Viper中文教程
2.一个 request 到 response 的生命周期
2.1路由
路由进行细分就可。
- 分角色
- 需要鉴权
- 不需要鉴权
这一块就看自己的思路。你觉得怎么来,路由清晰有条理,都是可以的。
2.2中间件
主要完成鉴权的功能。推荐使用jwt去验证用户权限。
推荐使用库:jwt-go
jwt学习博客:
// 选取一段代码说明
type HeaderParams struct {
authorization string `header:"authorization"`
}
// 本质上返回的代码段就是 gin 的标准回调函数形式 : func(c *gin.Context) { ... 省略代码 }
func CheckAuth() gin.HandlerFunc {
return func(context *gin.Context) {
// 模拟验证token
V_HeaderParams := HeaderParams{}
// 使用ShouldbindHeader 方式获取头参数
context.ShouldBindHeader(&V_HeaderParams)
// 对头参数中的token进行验证
if len(V_HeaderParams.authorization) >= 20 {
...
context.Next() // OK 下一步
}else{
context.Abort() // 不 OK 终止已注册代码执行
}
}
2.3表单验证
当一个request请求来的时候,第一件事情就是进行参数校验。(虽然前端进行安全校验,但是后端为了使用安全同样需要进行参数校验)。
推荐学习博客:validator库参数校验若干实用技巧
官方文档:官方tag查询
2.4控制器
尽量让控制器成为一个调度器的角色,而不是在这里处理业务🎉
在这里主要用来调用各种模块下的相关函数方法。达到需要完成的需求。业务相关代码不在这里码。
2.4.1model业务
在这里是直接与数据库进行交互的。进行常规操作,CURD等操作
2.4.2service业务
在这里完成业务的处理,同时调用model层,也提供数据给控制器层(最高层)。
response响应
因为每个请求之后,都会进行response响应,所以为了方便使用,以及管理,会对response进行封装。
常用的返回格式是json
对状态码,返回信息进行统一管理。对返回函数(语法糖)进行封装,精简代码。
3.优雅退出与重启
推荐学习博客:优雅地关机或重启
优雅关机就是服务端关机命令发出后不是立即关机,而是等待当前还在处理的请求全部处理完毕后再退出程序,是一种对客户端友好的关机方式。而执行Ctrl+C关闭服务端时,会强制结束进程导致正在访问的请求出现问题。
4.日志管理
推荐学习博客:使用zap接收gin框架默认的日志并配置日志归档
使用库:zap日志库
日志管理能够快速定位到发生bug的地方,同时也可以观测项目运行情况。日志管理对于项目来说必不可少。
5. 数据库
推荐学习:【GORM简明教程】
官方文档:GORM 指南
对于学生来说常用的就是mysql。gorm是一个对象关系映射的库,可以帮助你更好更方便的去管理数据库。
之前有学长说过,gorm没有形成一个规范,版本变更了,就会改很多,所以这个gorm学习不是看视频而是去看文档。同时原生的sql其实也不难,如果你喜欢原生,可以使用sqlx库。
6.权限管理
推荐使用库:casbin
官方文档:casbin
现在的网站不再像以前一样,能访问就行。现在会有不同身份的用户访问你的网站,而且权限不同,所以需要利用权限管理。
结束
项目整体脉络梳理清楚后,逐一分模块学习相关的第三方库以及这个项目的实现。
主要顺序:如上面顺序。
主要目的:学习web项目整体的架构和思路。