golang中间件有什么作用

Golang中间件的责任是可插拔并且自足,其作用是:1、在处理请求的过程中,对请求进行拦截、处理或者过滤,并且可以在处理请求的前后进行一些操作,例如日志记录、身份验证、处理请求的参数等;2、中间件可以在代码结构上实现业务逻辑和处理请求的分离,使得代码更加清晰和易于维护;3、中间件可以被复用,减少了代码重复编写的工作量。

本教程操作环境:windows10系统、GO 1.20.1版本、Dell G3电脑。

Golang中间件有什么作用

Golang中间件的作用

中间件主要责任就是可插拔并且自足。在处理请求的过程中,对请求进行拦截、处理或者过滤,并且可以在处理请求的前后进行一些操作,例如日志记录、身份验证、处理请求的参数等。中间件可以在代码结构上实现业务逻辑和处理请求的分离,使得代码更加清晰和易于维护。同时,中间件可以被复用,减少了代码重复编写的工作量。

代码示例如下:

package main
import (
"
fmt"

"
github.com/devfeel/dotweb"

)

func main() {
app := dotweb.New()
// App注册中间件
app.Use(NewSessionAuth())
// 开启SESSION
app.HttpServer.SetEnabledSession(true)
// 设置路由 输出字符串 Hello Dotweb
app.HttpServer.GET("
/"
, func(ctx dotweb.Context) error {
method := ctx.Request().Method
return ctx.WriteString("
Hello Dotweb\n"
+ "
Method:"
+ method)
})

//开启服务 端口号
fmt.Println("
dotweb.StartServer =>
8080"
)
err := app.StartServer(8080)
fmt.Println("
dotweb.StartServer error =>
"
, err)
}

// SessionAuth 结构体
type SessionAuth struct {
dotweb.BaseMiddlware
}

// Handle 处理程序
func (m *SessionAuth) Handle(ctx dotweb.Context) error {
fmt.Println("
SessionID = "
, ctx.SessionID(), "
RequestURI = "
, ctx.Request().RequestURI)
return m.Next(ctx)
}

// NewSessionAuth New
func NewSessionAuth() *SessionAuth {
sAuth := new(SessionAuth)
return sAu
}

Handle是什么时候被调用的?

我们看看BaseMiddlWare的源码:

// BaseMiddleware is the base struct, user defined middleware should extend this
type BaseMiddleware struct {
next Middleware
excludeRouters map[string]struct{}
}

func (bm *BaseMiddleware) SetNext(m Middleware) {
bm.next = m
}

func (bm *BaseMiddleware) Next(ctx Context) error {
httpCtx := ctx.(*HttpContext)
if httpCtx.middlewareStep == "
"
{
httpCtx.middlewareStep = middleware_App
}
if bm.next == nil {
if httpCtx.middlewareStep == middleware_App {
httpCtx.middlewareStep = middleware_Group
if len(httpCtx.RouterNode().GroupMiddlewares()) >
0 {
return httpCtx.RouterNode().GroupMiddlewares()[0].Handle(ctx)
}
}

if httpCtx.middlewareStep == middleware_Group {
httpCtx.middlewareStep = middleware_Router
if len(httpCtx.RouterNode().Middlewares()) >
0 {
return httpCtx.RouterNode().Middlewares()[0].Handle(ctx)
}
}

if httpCtx.middlewareStep == middleware_Router {
return httpCtx.Handler()(ctx)
}
} else {
// check exclude config
if ctx.RouterNode().Node().hasExcludeMiddleware &
&
bm.next.HasExclude() {
if bm.next.ExistsExcludeRouter(ctx.RouterNode().Node().fullPath) {
return bm.next.Next(ctx)
}
}
return bm.next.Handle(ctx)
}
return n
}

通过这个代码我们大概能看出:BaseMiddleware其实是一个链表的node中间件组成了一个链表,并且有不同的类型,有group中间件和普通中间件,根据当前ctx所处的处理步骤决定调用哪一个中间件,最后调用ctx的handler

自定义的middleware要继承BaseMiddleware

并且实现handle

func (asm *ApiSignMiddleware) Handle(ctx dotweb.Context) error {
if sign := ctx.Request().QueryHeader("
Sign"
);
len(sign) <
= 0 {
return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil})
} else {
uri := ctx.Request().RequestURI
if index := strings.Index(uri, "
?"
);
index != -1 {
uri = uri[:index]
}
if ok := checkSign(sign, uri);
!ok {
return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil})
}
return asm.Next(ctx)
}
}

这样就可以对传进来的Contex进行解析

分析一下blogserver里面用到的middleware:

CrosMiddleware

func (cm *CrosMiddleware) Handle(ctx dotweb.Context) error {
if strings.Contains(ctx.Request().RequestURI, "
v1"
) &
&
ctx.Request().Method != "
OPTIONS"
{
if sign := ctx.Request().QueryHeader("
Sign"
);
len(sign) <
= 0 {
return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil})
} else {
uri := ctx.Request().RequestURI
if index := strings.Index(uri, "
?"
);
index != -1 {
uri = uri[:index]
}
if ok := checkSign(sign, uri);
!ok {
return ctx.WriteJsonC(http.StatusBadRequest, models.Response{Err: common.ErrSignParams, Data: nil})
}
return cm.Next(ctx)
}
}
return cm.Next(ctx)
} CrosMiddleware 对uri的非参数部分调用checkSign //验证签名 (requestUri(不含query)+secret)
func checkSign(sign, uri string) bool {
result := utils.Md5(uri + config.Config().SecretKey)
return result == sign
}

传过来得header里面得sign值应该跟uri + 配置文件里面的SecretKey取md5一致



作为一种高效且强大的编程语言,Golang在应用开发中有着广泛的应用。而中间件则是Golang开发中不可或缺的一部分。那么Golang中间件有什么作用呢?下面将由三个方面介绍它的作用。
一、拦截与转发
中间件在Golang中最常见的用途就是拦截HTTP请求。通过中间件,可以在请求到达处理函数之前进行拦截并进行一些处理,例如请求参数验证等。同时,中间件还可以实现请求的转发,将不同的请求分发到对应的处理函数中。这种拦截与转发的方式可以有效减少代码的复杂度,并提高代码的可复用性。
二、日志与统计
在实际的应用开发中,通常需要对请求进行统计和分析,例如统计每个接口的请求次数、请求时间等,这对于后期的性能优化有着非常重要的作用。中间件可以很方便地进行日志和统计的记录,同时也不会影响到原有的业务逻辑。
三、权限控制
当应用作为API服务器提供服务时,通常需要对接口进行鉴权操作,而中间件可以方便地实现这种权限控制功能。通过中间件,可以在请求处理之前进行用户验证和权限验证等操作,同时也能够有效地减少鉴权代码在业务逻辑中的重复出现,提高代码的可读性。
总结:
作为Golang中重要的组成部分,中间件在其应用开发中具有不可替代的作用。通过中间件的使用,可以方便地实现拦截与转发、日志与统计以及权限控制等功能,使得应用代码更加简洁并提高开发效率。