golang gin后端开发框架(三):路由组和中间件

1. 路由组

在实际的项目开发中,均是模块化开发

同一模块内的功能接口,往往会有相同的接口前缀,这种可以用路由组来进行分类处理。

比如下面这几组接口:

注册:http: //localhost:8080/user/register
登陆:http: //localhost:8080/user/login
用户信息:http: //localhost:8080/user/info

 

gin框架可以使用路由组来实现对路由的分类

路由组是router.Group中的一个方法,对于请求进行分组

func main() {
engine := gin.Default()
// 注册路由组
routerGroup := engine.Group("/user")
routerGroup.POST("/register", func(ctx *gin.Context) {})
routerGroup.POST("/login", func(ctx *gin.Context) {})
routerGroup.GET("/info", func(ctx *gin.Context) {})
engine.Run()
}

 

2. 中间件

 在实际的业务开发中,一个完整的系统可能要包含鉴权认证、权限管理、安全检查、日志记录等多个维度的系统支持

鉴权认证、权限管理、安全检查等业务都是属于全系统的业务,和具体的业务没有直接关联

因此在开发中,为了更好的梳理系统架构,可以将以上这些业务单独抽离出来,以插件化的方式进行对接

这种通用业务独立开发并灵活配置使用的组件,称之为中间件,其位于服务器和实际业务处理程序之间

 

2.1 gin的中间件

在gin中,中间件的类型定义如下:

// HandlerFunc defines the handler used by gin middleware as return value
type HandlerFunc func (*Context)

HandlerFunc是一个函数类型,接收一个Context参数。用于编写程序处理函数并返回HandleFunc类型,作为中间件定义

 

2.2 中间件Use用法

关于初始化gin engine的gin.Default()方法的实现中也使用了两个中间件

// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default() *Engine {
debugPrintWARNINGDefault()
engine := New()
engine.Use(Logger(), Recovery())
return engine
}

 

我们可以跳转到Logger()中间件的定义,去看看实现一个中间件的格式是什么

// Logger instances a Logger middleware that will write the logs to gin.DefaultWriter.
// By default, gin.DefaultWriter = os.Stdout.
func Logger() HandlerFunc {
return LoggerWithConfig(LoggerConfig{})
}

 

2.3 自定义中间件

根据上文关于中间件的描述中,我们可以自定义一个特殊需求的中间件,中间件类型是函数,有两条标准:

  • func函数
  • 返回值类型为HandlerFunc

比如我们现在有一个需求,实现一个中间件,其功能就是打印出请求的path和method:

// RequestInfos 实现一个中间件
func RequestInfos() gin.HandlerFunc {
return func (ctx *gin.Context) {
path := ctx.FullPath()
method := ctx.Request.Method
fmt.Println(path, method)
}
}

  

使用或者注册中间件时有两种方式,一种是直接使用engine.Use(),那么所有接口都会经过这个中间件处理

// 使用中间件,所有接口都经过这个中间件
engine.Use(RequestInfos())

  

或者为某一个处理注册一个中间件,那么只有这一个请求会经过该中间件

engine.GET( "/query" , RequestInfos(), func (ctx *gin.Context) {
ctx.JSON(http.StatusOK, map [string] interface {}{
"code" : 1,
"message" : ctx.FullPath(),
})
})

 

2.4 context.Next函数

在上面自定义中间件RequestInfos()中,打印了请求的路径和请求的method,接着去执行了正常的业务处理函数

如果我们想输出业务处理的结果,就应该使用context.Next来实现

context.Next可以将中间件代码一分为二:

  • Next()之前的代码会在请求处理之前执行
  • 当中间件执行流遇到context.Next时,会中断执行,转而执行业务逻辑
  • 当业务逻辑执行完之后,再次回到Next函数处,继续向下执行中间件逻辑,从而获取业务执行之后的结果

 具体用法如下:

func RequestInfos() gin.HandlerFunc {
return func(ctx *gin.Context) {
path := ctx.FullPath()
method := ctx.Request.Method
fmt.Println(path, method)
ctx.Next() // 在此处一分为二
fmt.Println(ctx.Writer.Status())
}
}

  

posted @   aganippe  阅读(812)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示