Go Web项目 接口开发全流程
创始人
2024-02-10 07:53:03

风离不摆烂学习日志 Day5 — Go Web项目 接口开发全流程

接上篇地址 Web项目学习之项目结构

routes包分析

InitRoutes

package routesimport ("fmt""github.com/gin-gonic/gin""go-web-mini/common""go-web-mini/config""go-web-mini/middleware""time"
)// 初始化
func InitRoutes() *gin.Engine {//设置模式gin.SetMode(config.Conf.System.Mode)// 创建带有默认中间件的路由:// 日志与恢复中间件r := gin.Default()// 创建不带中间件的路由:// r := gin.New()// r.Use(gin.Recovery())// 启用限流中间件// 默认每50毫秒填充一个令牌,最多填充200个fillInterval := time.Duration(config.Conf.RateLimit.FillInterval)capacity := config.Conf.RateLimit.Capacityr.Use(middleware.RateLimitMiddleware(time.Millisecond*fillInterval, capacity))// 启用全局跨域中间件r.Use(middleware.CORSMiddleware())// 启用操作日志中间件r.Use(middleware.OperationLogMiddleware())// 初始化JWT认证中间件authMiddleware, err := middleware.InitAuth()if err != nil {common.Log.Panicf("初始化JWT中间件失败:%v", err)panic(fmt.Sprintf("初始化JWT中间件失败:%v", err))}// 路由分组apiGroup := r.Group("/" + config.Conf.System.UrlPathPrefix)// 注册路由InitBaseRoutes(apiGroup, authMiddleware)         // 注册基础路由, 不需要jwt认证中间件,不需要casbin中间件InitUserRoutes(apiGroup, authMiddleware)         // 注册用户路由, jwt认证中间件,casbin鉴权中间件InitRoleRoutes(apiGroup, authMiddleware)         // 注册角色路由, jwt认证中间件,casbin鉴权中间件InitMenuRoutes(apiGroup, authMiddleware)         // 注册菜单路由, jwt认证中间件,casbin鉴权中间件InitApiRoutes(apiGroup, authMiddleware)          // 注册接口路由, jwt认证中间件,casbin鉴权中间件InitOperationLogRoutes(apiGroup, authMiddleware) // 注册操作日志路由, jwt认证中间件,casbin鉴权中间件common.Log.Info("初始化路由完成!")return r
}

设置开发模式(debug/release/test,正式版改为release) => 加载中间件 => 注册路由

base_routes.go

package routesimport (jwt "github.com/appleboy/gin-jwt/v2""github.com/gin-gonic/gin"
)// 注册基础路由
func InitBaseRoutes(r *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) gin.IRoutes {router := r.Group("/base"){// 登录登出刷新token无需鉴权router.POST("/login", authMiddleware.LoginHandler)router.POST("/logout", authMiddleware.LogoutHandler)router.POST("/refreshToken", authMiddleware.RefreshHandler)}return r
}

menu_routes.go

package routesimport (jwt "github.com/appleboy/gin-jwt/v2""github.com/gin-gonic/gin""go-web-mini/controller""go-web-mini/middleware"
)func InitMenuRoutes(r *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) gin.IRoutes {menuController := controller.NewMenuController()router := r.Group("/menu")// 开启jwt认证中间件router.Use(authMiddleware.MiddlewareFunc())// 开启casbin鉴权中间件router.Use(middleware.CasbinMiddleware()){router.GET("/tree", menuController.GetMenuTree)router.GET("/list", menuController.GetMenus)router.POST("/create", menuController.CreateMenu)router.PATCH("/update/:menuId", menuController.UpdateMenuById)router.DELETE("/delete/batch", menuController.BatchDeleteMenuByIds)router.GET("/access/list/:userId", menuController.GetUserMenusByUserId)router.GET("/access/tree/:userId", menuController.GetUserMenuTreeByUserId)}return r
}

函数格式:

1. func 函数名(入参1 参数类型,入参2 参数类型) 返回类型

2. func 函数名(入参1 参数类型,入参2 参数类型)(返回值1 返回类型)

controller包分析

user_controller.go

大致流程:

定义接口

定义结构体 结构体里包含持久层的CRUD

然后实现这些接口 返回出去

对比Java 的 SpringBoot框架 Gin 没有自动注入 我们需要自己写构造函数 来初始化持久层 Controller层

type UserController struct {UserRepository repository.IUserRepository
}// 构造函数
func NewUserController() IUserController {userRepository := repository.NewUserRepository()userController := UserController{UserRepository: userRepository}return userController
}

然后上层调用这个构造函数来完成初始化

image-20221123111701951

repository包分析

大体流程与controller层逻辑一致

type UserRepository struct { //结构体为空
}

内存缓存go-cache

用户信息缓存 避免频繁读取数据库

地址: https://github.com/patrickmn/go-cache
一个基于内存的key-value存储/缓存项目,类似于Memcached,并且可选择定期的垃圾回收,适合单机程序。代码量不多,也不难懂。

"github.com/patrickmn/go-cache"// 当前用户信息缓存,避免频繁获取数据库  这里逻辑跟Redis差不多 增 删 改 时更新缓存 查优先走缓存 
var userInfoCache = cache.New(24*time.Hour, 48*time.Hour)

model包分析

package modelimport "gorm.io/gorm"type User struct {gorm.ModelUsername     string  `gorm:"type:varchar(20);not null;unique" json:"username"`Password     string  `gorm:"size:255;not null" json:"password"`Mobile       string  `gorm:"type:varchar(11);not null;unique" json:"mobile"`Avatar       string  `gorm:"type:varchar(255)" json:"avatar"`Nickname     string  `gorm:"type:varchar(20)" json:"nickname"`Introduction *string `gorm:"type:varchar(255)" json:"introduction"`Status       uint    `gorm:"type:tinyint(1);default:1;comment:'1正常, 2禁用'" json:"status"`Creator      string  `gorm:"type:varchar(20);" json:"creator"`Roles        []*Role `gorm:"many2many:user_roles" json:"roles"`
}

这里结构体 类似于Java中对象

需要首字母大写 指定 转 json 后的类型 对应长字段 类型存储为 指针 即取地址

dto包分析

user_dto.go

package dtoimport "go-web-mini/model"// 返回给前端的当前用户信息
type UserInfoDto struct {ID           uint          `json:"id"`Username     string        `json:"username"`Mobile       string        `json:"mobile"`Avatar       string        `json:"avatar"`Nickname     string        `json:"nickname"`Introduction string        `json:"introduction"`Roles        []*model.Role `json:"roles"`
}func ToUserInfoDto(user model.User) UserInfoDto {return UserInfoDto{ID:           user.ID,Username:     user.Username,Mobile:       user.Mobile,Avatar:       user.Avatar,Nickname:     user.Nickname,Introduction: *user.Introduction,Roles:        user.Roles,}
}// 返回给前端的用户列表
type UsersDto struct {ID           uint   `json:"ID"`Username     string `json:"username"`Mobile       string `json:"mobile"`Avatar       string `json:"avatar"`Nickname     string `json:"nickname"`Introduction string `json:"introduction"`Status       uint   `json:"status"`Creator      string `json:"creator"`RoleIds      []uint `json:"roleIds"`
}func ToUsersDto(userList []*model.User) []UsersDto {var users []UsersDtofor _, user := range userList {userDto := UsersDto{ID:           user.ID,Username:     user.Username,Mobile:       user.Mobile,Avatar:       user.Avatar,Nickname:     user.Nickname,Introduction: *user.Introduction,Status:       user.Status,Creator:      user.Creator,}roleIds := make([]uint, 0)for _, role := range user.Roles {roleIds = append(roleIds, role.ID)}userDto.RoleIds = roleIdsusers = append(users, userDto)}return users
}

当我们不需要将数据库的数据全部返回出去的时候 或者需要做字段转换 拼接 等操作 皆可在dto层完成


response包分析

封装统一返回格式

package responseimport ("github.com/gin-gonic/gin""net/http"
)// 返回前端
func Response(c *gin.Context, httpStatus int, code int, data gin.H, message string) {c.JSON(httpStatus, gin.H{"code": code, "data": data, "message": message})
}// 返回前端-成功
func Success(c *gin.Context, data gin.H, message string) {Response(c, http.StatusOK, 200, data, message)
}// 返回前端-失败
func Fail(c *gin.Context, data gin.H, message string) {Response(c, http.StatusBadRequest, 400, data, message)
}

config 包分析

这里结构体对应 config.yml 配置文件中对应的配置

type MysqlConfig struct { //mysql配置Username    string `mapstructure:"username" json:"username"`Password    string `mapstructure:"password" json:"password"`Database    string `mapstructure:"database" json:"database"`Host        string `mapstructure:"host" json:"host"`Port        int    `mapstructure:"port" json:"port"`Query       string `mapstructure:"query" json:"query"`LogMode     bool   `mapstructure:"log-mode" json:"logMode"`TablePrefix string `mapstructure:"table-prefix" json:"tablePrefix"`Charset     string `mapstructure:"charset" json:"charset"`Collation   string `mapstructure:"collation" json:"collation"`
}

在一个结构体里包含 各个配置的集合 mysql jwt...

type config struct {System    *SystemConfig    `mapstructure:"system" json:"system"`Logs      *LogsConfig      `mapstructure:"logs" json:"logs"`Mysql     *MysqlConfig     `mapstructure:"mysql" json:"mysql"`Casbin    *CasbinConfig    `mapstructure:"casbin" json:"casbin"`Jwt       *JwtConfig       `mapstructure:"jwt" json:"jwt"`RateLimit *RateLimitConfig `mapstructure:"rate-limit" json:"rateLimit"`
}

相关内容

热门资讯

猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...