gin-framework

command module
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 17, 2022 License: MIT Imports: 10 Imported by: 0

README

⚡🚀 以gin框架为基础,封装一套基于go1.18+的适用于面向api编程的快速开发框架

 ██████╗ ██╗███╗   ██╗      ███████╗██████╗  █████╗ ███╗   ███╗███████╗██╗    ██╗ ██████╗ ██████╗ ██╗  ██╗
██╔════╝ ██║████╗  ██║      ██╔════╝██╔══██╗██╔══██╗████╗ ████║██╔════╝██║    ██║██╔═══██╗██╔══██╗██║ ██╔╝
██║  ███╗██║██╔██╗ ██║█████╗█████╗  ██████╔╝███████║██╔████╔██║█████╗  ██║ █╗ ██║██║   ██║██████╔╝█████╔╝
██║   ██║██║██║╚██╗██║╚════╝██╔══╝  ██╔══██╗██╔══██║██║╚██╔╝██║██╔══╝  ██║███╗██║██║   ██║██╔══██╗██╔═██╗
╚██████╔╝██║██║ ╚████║      ██║     ██║  ██║██║  ██║██║ ╚═╝ ██║███████╗╚███╔███╔╝╚██████╔╝██║  ██║██║  ██╗
 ╚═════╝ ╚═╝╚═╝  ╚═══╝      ╚═╝     ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝     ╚═╝╚══════╝ ╚══╝╚══╝  ╚═════╝ ╚═╝  ╚═╝╚═╝  ╚═╝

GoDoc Go Report Card codebeat badge GitHub license GitHub stars

一、目录结构

├── app                         # 模块存放目录
│   ├── controller              # 控制器
│   └── service                 # 服务层
├── bootstrap                   # 初始化程序加载服务
│   ├── rbac_model.conf         # rbac配置文件
├── cmd                         # command命令
├── config                      # 解析配置文件
├── types                       # 存放表对应的实体 / 请求参数的结构体
├── global                      # 一些全局变量和全局方法
├── main.go                     # 主进程启动文件
├── middleware                  # 中间件
├── migrations                  # 数据迁移的sql文件目录
├── models                      # 对应数据库的模型
├── pkg                         # 自定义的常用服务,JWT,助手函数等
│   ├── auth                    # jwt
│   ├── lib                     # 日志服务,数据库服务,redis服务
│   ├── paginator               # 分页器
│   ├── response                # http请求返回的状态和格式化
│   ├── util                    # 助手函数
│   └── validator               # 验证器
├── config.dev.yaml             # 开发环境配置文件
├── config.test.yaml            # 测试环境配置文件
├── config.prod.yaml            # 正式环境配置文件
├── router                      # 路由配置
├── runtime                     # 运行时文件 如日志
目前已集成和实现:
  • 支持 jwt Authorization token验证组件
  • 支持 cors 接口跨域组件
  • 支持 gorm 数据库操作组件
  • 支持 gorm-model 自主实现的基于gorm生成的映射数据表的model结构体
  • 支持 logrus 日志收集组件
  • 支持 go-redis redis连接组件
  • 支持 migrate 数据库迁移组件
  • 支持 controller、service 命令行方式生成代码工具
  • 支持 go-websocket 基于 gorilla/websocket 实现的即时通讯组件(单个客户端,多个客户端,群组,广播推送等)
  • 支持 go-rabbitmq 消息队列组件 基于rabbitmq官方 amqp 组件封装实现的消费者和生产者
  • 支持 casbin rbac权限 集成于中间件中 casbin_auth.go
  • 支持 requestId 中间件 实现了方便链路追踪日志记录中间件 requestid_auth.go
  • 支持 viper yaml、json、toml等配置文件解析组件
  • 支持 validator 数据字段验证器组件,同时支持中文
  • 支持 snowflake 生成雪花算法全局唯一ID
  • 实现 ip白名单配置 集成于中间件中 ip_auth.go
  • 实现 ticker 定时器组件
  • 实现 基于gorm的 pagination 分页构造器组件
  • 实现 code 统一定义的返回码,exception 统一错误返回处理组件
下一步计划:
  • 支持 定时任务 cron
  • 支持 pprof 性能剖析组件
  • 支持 trace 项目内部链路追踪
  • 支持 rate 接口限流组件
  • 支持 grpc rpc组件

二、启动服务

注意启动前需要将 mysql服务和redis服务开启,并配置config.dev.yaml文件(默认读取dev环境)中的mysql和redis配置

1、安装依赖和初始化

go mod tidy 

2、服务启动

go run main.go 

# 查看 main.go的参数
go run main.go --help

3、访问如下表示成功启动

请求:http://127.0.0.1:9527/ping

{
    "status": 200,
    "errcode": 0,
    "requestid": "9ac7f4f2-1271-4f87-8df7-599a478af9cb",
    "message": "Pong!",
    "data": ""
}

4、安装热更新

go install github.com/cosmtrek/air@latest

命令行敲入:air 即可执行热更新 代码编辑即更新

5、部署casbin权限(重要!(按以下步骤执行))

此步骤针对于backend接口进行权限访问
1)执行migrate
go run main.go migrate -s=all

# 具体参数查看help
go run main.go migrate -help
2)请求 /routes 接口
此接口会创建一个基于casbin的超级管理员权限

6、打包上线

# 查看make命令行
make help

# 基础打包,生成可执行文件
make build

# 打包windows
make windows

# 打包darwin
make darwin

# 打包linux
make linux

在releases中查看打包的文件

三、组件使用

1、基于gorm的查询分页构造器

引用包

import "github.com/MQEnergy/gin-framework/pkg/paginator"
一、基础用法
1)单表分页基础用法:
var memberList = make([]models.GinAdmin, 0)
paginator, err := paginator.NewBuilder().
    WithDB(global.DB).
    WithModel(models.GinAdmin{}).
    WithField([]string{"password", "salt", "updated_at", "_omit"}).
    WithCondition("id = ?", 1).
    Pagination(memberList, 1, 10)
return paginator, err
2)连表joins查询用法:

定义接收struct

type BaseUser models.GinUser
type GinUserInfo models.GinUserInfo

// UserList 获取关联列表
type UserList struct {
	BaseUser
	GinUserInfo `gorm:"foreignKey:user_id" json:"user_info"`
}

用法一:

var userList = make([]user.UserList, 0)
pagination, err := paginator.NewBuilder().
    WithDB(global.DB).
    WithModel(models.GinUser{}).
    WithFields(models.GinUser{}, models.GinUserTbName, []string{"password", "salt", "_omit"}).
    WithFields(models.GinUserInfo{}, models.GinUserInfoTbName, []string{"id", "user_id", "role_ids"}).
    WithJoins("left", []paginator.OnJoins{{
        LeftTableField:  paginator.JoinTableField{Table: models.GinUserTbName, Field: "id"},
        RightTableField: paginator.JoinTableField{Table: models.GinUserInfoTbName, Field: "user_id"},
    }}).
    Pagination(&userList, requestParams.Page, global.Cfg.Server.DefaultPageSize)
return pagination, err

用法二:

var userList = make([]user.UserList, 0)
multiFields := []paginator.SelectTableField{
    {Model: models.GinUser{}, Table: models.GinUserTbName, Field: []string{"password", "salt", "_omit"}},
    {Model: models.GinUserInfo{}, Table: models.GinUserInfoTbName, Field: []string{"user_id", "role_ids"}},
}	
pagination, err := paginator.NewBuilder().
    WithDB(global.DB).
    WithModel(models.GinUser{}).
    WithMultiFields(multiFields).
    WithJoins("left", []paginator.OnJoins{{
        LeftTableField:  paginator.JoinTableField{Table: models.GinUserTbName, Field: "id"},
        RightTableField: paginator.JoinTableField{Table: models.GinUserInfoTbName, Field: "user_id"},
    }}).
    Pagination(&userList, requestParams.Page, global.Cfg.Server.DefaultPageSize)
return pagination, err
3)预加载preload查询用法(强烈建议用法):
注意:
与joins查询方式定义的struct有些许差别,preload方式定义struct名称必须与model当前表的struct名称一致,
且关联表的struct名称不能跟model对于的struct名称一样 例如:定义的`UserInfo` 写法如下

定义接收struct

type BaseUser models.GinUser
type GinUserInfo models.GinUserInfo

type GinUser struct {
	BaseUser
	UserInfo GinUserInfo `gorm:"foreignKey:user_id" json:"user_info"`
}

用法如下:

var userList = make([]user.GinUser, 0)
pagination, err := paginator.NewBuilder().
    WithDB(global.DB).
    WithModel(models.GinUser{}).
    WithPreload("UserInfo").
    Pagination(&userList, requestParams.Page, global.Cfg.Server.DefaultPageSize)
return pagination, err
此写法不建议使用WithFields、WithField查询字段,建议直接定义接收struct规定的查询字段即可

访问地址:http://127.0.0.1:9527/user/index?page=1 返回数据格式如下:

{
  "status": 200,
  "errcode": 0,
  "requestid": "9ac7f4f2-1271-4f87-8df7-599a478af9cb",
  "message": "请求成功",
  "data": {
    "list": [],
    "current_page": 1,
    "total": 2,
    "last_page": 1,
    "per_page": 10
  }
}
4)案例查看:

1)用法如下 获取用户列表:

entities/user/gin_user.go
app/controller/backend/user.go
app/service/backend/user.go
router/routes/common.go
二、具体方法
查看使用
1)必须在链式操作中 db连接方法
WithDB(db *gorm.DB) *PageBuilder

传入全局global.DB

2)必须在链式操作中 model连接方法
WithModel(model interface{}) *PageBuilder

传入查询主表model 例如:models.GinAdmin 参数不能传结构体取地址方式 如:&models.GinAdmin

3)非必须在链式操作中 单表查询或过滤字段方法
WithField(fields []string) *PageBuilder 

fields 最后一个参数默认为_select(可不传),如传_omit为过滤前面传输的字段。

注意:

  • _select / _omit 必须在最后
  • WithModel 参数不能传结构体取地址 例如:&models.GinAdmin 必须 models.GinAdmin 不然 _omit 参数失效
  • 此注意事项适用于 WithFields方法、WithMultiFields方法

用法如下:

// 表示过滤前面字段
WithField([]string{"created_at", "updated_at", "_omit"})

// 表示查询前面的字段
WithField([]string{"created_at", "updated_at", "_select"})
WithField([]string{"created_at", "updated_at"})
4)非必须在链式操作中 多表查询或过滤字段方法(preload模式下 关联表查询有问题,preload关联查询不建议使用此方法)
WithFields(model interface{}, table string, fields []string) *PageBuilder

fields 最后一个参数默认为_select(可不传),如传_omit为过滤前面传输的字段。

用法如下:

// 表示过滤前面字段
WithFields(models.GinUser{}, models.GinUserTbName, []string{"password", "salt", "_omit"})

// 表示查询前面的字段
WithFields(models.GinUserInfo{}, models.GinUserInfoTbName, []string{"id", "user_id", "role_ids", "_select"})
WithFields(models.GinUserInfo{}, models.GinUserInfoTbName, []string{"id", "user_id", "role_ids"})
5)非必须在链式操作中 多表多字段查询(可替代WithFields方法)
WithMultiFields(fields []SelectTableField) *PageBuilder

用法如下:

WithMultiFields([]paginator.SelectTableField{
    {Model: models.GinUser{}, Table: models.GinUserTbName, Field: []string{"password", "salt", "_omit"}},
    {Model: models.GinUserInfo{}, Table: models.GinUserInfoTbName, Field: []string{"id", "user_id", "role_ids"}},
})
6)非必须在链式操作中 多表关联查询主动预加载(暂不支持条件)
 WithPreloads(querys []string) *PageBuilder 

用法如下:

WithPreloads([]string{"UserInfo", "UserRecord"})
7)非必须在链式操作中 关联查询主动预加载(可传条件,条件参考gorm)
WithPreload(query string, args ...interface{}) *PageBuilder

用法如下:

WithPreload("UserInfo", "user_id = ?", "1")
8)非必须在链式操作中 数据查询条件方法
WithCondition(query interface{}, args ...interface{}) *PageBuilder

传入查询条件 支持gorm中where条件中的查询方式(非struct方式) query, args参数参照gorm的where条件传入方式

9)非必须在链式操作中 数据查询条件方法
WithJoins(joinType string, joinFields []OnJoins) *PageBuilder

joinType:join类型 可传入:left、right、inner,joinFields结构体: LeftTableField:如:主表.ID RightTableField:如:关联表.主表ID

用法如下:

WithJoins("left", []paginator.OnJoins{{
    LeftTableField:  paginator.JoinTableField{Table: models.GinUserTbName, Field: "id"},
    RightTableField: paginator.JoinTableField{Table: models.GinUserInfoTbName, Field: "user_id"},
}})
10)必须在链式操作中最后一环 分页返回方法
Pagination(dst interface{}, currentPage, pageSize int) (Page, error)

dst 传入接收数据的struct结构体 注意:必须是应用方式传递 如:&userList, model,currentPage 为当前页码,pageSize为每页查询数量

11)非必须在链式操作中 对接原生查询方式
 NewDB() *gorm.DB

用此方法之后的链式操作下pagination里面的方法均不可用,后面跟gorm原生方法即可

用法如下:

NewDB().Where("id = ?", id).First(&userList)
12)获取当前页码
paginator.CurrentPage
13)获取分页列表
paginator.List
14)获取数据总数
paginator.Total
15)获取最后一页页码
paginator.LastPage
16)获取每页数据条数
paginator.PerPage

2、基于gin上传组件

UploadFile(path string, r *gin.Context) (*FileHeader, error)

默认存储在项目中upload目录,如果没有会自动创建 path:upload目录模块目录 如:user 则目录是:upload/user/{yyyy-mm-dd}/...

用法如下:

app/controller/backend/attachment.go
pkg/util/upload.go
router/routes/common.go

3、rabbitmq组件使用

配置yaml配置文件中的amqp参数

1)启动消费者

测试案例

go run command/test/consumer.go
2)启动生产者

测试案例

go run command/test/producer.go

四、工具

运行 go run main.go --help 可查看到以下命令集

COMMANDS:
  migrate     Create a migration command
  account     Create a new admin account
  model       Create a new model class
  controller  Create a new controller class
  service     Create a new service class
  help, h     Shows a list of commands or help for one command

1、执行migrate

查看使用
# 安装migrate cli工具
curl -L https://github.com/golang-migrate/migrate/releases/download/$version/migrate.$platform-amd64.tar.gz | tar xvz

# MacOS安装
brew install golang-migrate

# Window 使用scoop安装 https://scoop.sh/
scoop install migrate

# 创建迁移文件语法例如:
migrate create -ext sql -dir migrations -seq create_users_table

# 第一种方式执行迁移
# 执行迁移操作:
migrate -database 'mysql://root:123456@tcp(127.0.0.1:3306)/gin_framework' -path ./migrations up
# 执行回滚操作:
migrate -database 'mysql://root:123456@tcp(127.0.0.1:3306)/gin_framework' -path ./migrations down

# 第二种方式执行迁移
# 查看help命令
go run main.go migrate --help

# 格式如下:
go run main.go migrate -s {step} -e {env}
# env: dev, test, prod与config.*.yaml文件保持一致 默认是dev
# step:执行的迁移文件数量(回滚的文件数量)例如:1,2,3... 如果执行所有传 all

# 执行所有迁移操作:
go run main.go migrate -s all

# 执行部分迁移操作:
# 如:go run main.go migrate -s 1

# 执行回滚操作:
# 如:go run main.go migrate -s -1

2、自动生成model

# 执行生成所有model
go run main.go model -tb=all {env}

# 具体参数查看help
go run main.go model -help

3、自动生成controller

go run main.go controller -c={controller名称} -m={module名称}
# 例如:go run main.go controller -c=admin -m=backend

# 具体参数查看help
go run main.go controller -help

4、自动生成service

go run main.go service -s={service名称} -m={module名称}
# module名称是app/controller目录下的模块名称
# 例如:go run main.go service -s=admin -m=backend

# 具体参数查看help
go run main.go service -help

5、创建后台管理员账号(基于gin_admin表的,可自行修改代码基于其他表)

go run main.go account -c={账号名称} -p={密码}  

# 具体参数查看help
go run main.go account -help

五、参考

查看使用

初始化一个接口项目需要安装的依赖包(主要)

初始化go.mod
go mod init github.com/MQEnergy/gin-framework
go mod tidy
安装gin框架
go get -u github.com/gin-gonic/gin
安装model自动生成包
go get -u github.com/MQEnergy/gorm-model
安装gorm
go get -u gorm.io/gorm
# 如果下载不了 十之八九是因为 GOSUMDB的原因 
export GOSUMDB=
# GOSUMDB置空就行
安装命令行工具
go get -u github.com/urfave/cli/v2
安装log日志
go get -u github.com/sirupsen/logrus
go get -u github.com/lestrrat-go/file-rotatelogs
安装redis
go get -u github.com/go-redis/redis/v8
go get -u github.com/go-redsync/redsync/v4
安装jwt
go get -u github.com/dgrijalva/jwt-go
安装cors跨域
go get -u github.com/gin-contrib/cors
安装casbin
go get -u github.com/casbin/casbin/v2
go get -u github.com/casbin/gorm-adapter/v3
安装snowflake
go get -u github.com/bwmarrin/snowflake
安装golang-migrate迁移组件
go get -u github.com/golang-migrate/migrate/v4

# 安装migrate cli工具
curl -L https://github.com/golang-migrate/migrate/releases/download/$version/migrate.$platform-amd64.tar.gz | tar xvz

# MacOS安装
brew install golang-migrate

# Window 使用scoop安装 https://scoop.sh/
scoop install migrate

# 创建迁移文件语法例如:
migrate create -ext sql -dir migrations -seq create_users_table

# 执行迁移操作:
migrate -database 'mysql://root:123456@tcp(127.0.0.1:3306)/gin_framework' -path ./migrations up
# 执行回滚操作:
migrate -database 'mysql://root:123456@tcp(127.0.0.1:3306)/gin_framework' -path ./migrations down
安装热更新
go install github.com/cosmtrek/air@latest
基于Go 1.18+泛型的Lodash风格的Go库
go get -u github.com/samber/lo
配置文件解析库
go get -u github.com/spf13/viper

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL