中间件设计
1. 中间件概念
· 在请求和响应之间执行一系列的操作,可以用于处理身份验证、异常处理及日志打印等任务
· 一个或一组函数,接受请求对象、响应对象和一个next回调函数作为参数。
2. 中间件需求
· 配合Hander实现一个完整的请求处理生命周期
· 拥有预处理逻辑和后处理逻辑
· 可以注册多中间件
· 对上层模块用户逻辑模块易用
3. 实例:打印每个请求的request和response
· 不使用中间件:在每个请求的开始和结束都加上logs.Infof()
· 使用中间件:
```go
func main(){
h := server.New()
//使用中间件来处理请求和响应
h.Use(func(c context.Context, ctx *app.RequestContext){
//打印接收到的原始请求信息
logs.Infof("Received RawRequest: %s", ctx.Request.RawRequest())
//将请求传递给下一个处理程序。该函数会暂停当前中间件函数的执行,并将控制权交给下一个中间件函数或目标处理程序。当目标处理程序执行完毕后会按照调用链的相反顺序继续执行。
ctx.Next(c)
//打印发送的原始响应信息
logs.Infof("Send RawResponse: %s", ctx.Response.RawResponse())
})
//定义一个处理登录请求的路由和处理函数
h.POST("/login", func(c context.Context, ctx *app.RequestContext){
//some biz logic
ctx.JSON(200, "OK")
})
//定义一个处理登出请求的路由和处理函数
h.POST("/logout", func(c context.Context, ctx *app.RequestContext){
//some biz logic
ctx.JSON(200, "OK")
})
//启动HTTP服务器并开始监听请求
h.Spin()
}
```
中间件函数的执行过程可以看作一个“洋葱模型”,请求从外部逐层向内部传递,然后再从内部逐层向外部传递。ctx.Next(c)函数的作用是将请求传递给下一个中间件函数或目标处理程序。它并不是一个跳转函数,而是一个将控制权传给下一个处理程序的方法。
4. 中间件设计
· 不调用Next:初始化逻辑且不需要在同一调用栈
· 调用Next:后处理逻辑或需要在同一调用栈上
路由设计
1. 框架路由实际上就是为URL匹配对应的处理函数
· 静态路由:/a/b/c
· 参数路由:/a/:id/c、/*all
· 路由修复:/a/b <-> /a/b/
· 冲突路由及优先级
· 匹配HTTP方法
· 多处理函数:方便添加中间件
2. 路由设计
· 前缀匹配树