【阅读 GinSkeleton】简介

617 阅读6分钟

基于go语言gin框架的web项目骨架

地址:gitee.com/daitougege/…

前言

这里简单概述这个项目的大概的逻辑,以及使用的技术,后续分模块,分技术点去讲解,主要是达到整体理解。

项目结构目录

项目布局推荐: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学习博客:

JSON Web Token 入门教程

Cookie和Session

  // 选取一段代码说明
    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项目整体的架构和思路。