协议服务器
- 协议中间件: 请求到达业务之前的 处理
HTTP 协议(Gin中间件开发)
// r.Use()
// Use attaches a global middleware to the router. i.e. the middleware attached through Use() will be
// included in the handlers chain for every single request. Even 404, 405, static files...
// For example, this is the right place for a logger or error management middleware.
func (engine *Engine) Use(middleware ...HandlerFunc) IRoutes {
engine.RouterGroup.Use(middleware...)
engine.rebuild404Handlers()
engine.rebuild405Handlers()
return engine
}
如何定义一个中间件
// HandlerFunc defines the handler used by gin middleware as return value.
type HandlerFunc func(*Context)
// 这就是一个满足HandlerFunc 函数定义的函数值
func MyMiddleware(c *gin.Context) {
// 写我们的任务逻辑
// 1. 获取Token时(Cookie)
// 2. 调用user ValidateToken 校验Token合法性
// 3. 把User对象 放到Ctx中(请求的上下文), 后面CreateBlog需要从上下文中获取用户的身份信息
}
// 全局加载
root.Use(MyMiddleware)
认证中间件是按需加载
// 为这个业务单独生成一个子Router,不要和全局的Router混用
// "/vblog/api/v1/blogs" 就是URL的前缀
// 子Router的中间件加载时又顺序控制
sr := r.Group("/vblog/api/v1/blogs")
// 查询博客列表页, 不需要认证, 这个要放在加载中间件 之前
// prefgix + 当前定义的url
// /vblog/api/v1/blogs + ""
sr.GET("", h.QueryBlog)
// 后面的接口都需要认证
// 因为IRouter是全局
// 当前的r 是Root Router
// 和加载顺序有关系是子Router
sr.Use(middlewares.Auth)
ioc 中间件加载路由改造
ioc
// 对所有的对象统一执行 初始化
// 把所有 api handler 注册root 路由
func InitHttpApi(pathPrefix string, r gin.IRouter) error {
for k, v := range api {
err := v.Init()
if err != nil {
return fmt.Errorf("init %s error, %s", k, err)
}
// 每一模块生成一个子路由
// 子路由的Prefix 如何决定? "/vblog/api/v1/blogs"
// "/vblog/api/v1" + "blogs"
// project prefix + app prefix
// path.Join
v.Registry(r.Group(path.Join(pathPrefix, k)))
}
return nil
}
start.go
err = ioc.InitHttpApi("/vblog/api/v1", r)
使用
// 查询博客列表页, 不需要认证, 这个要放在加载中间件 之前
// prefgix + 当前定义的url
// SubRouter的前缀: /vblog/api/v1/blogs
r.GET("", h.QueryBlog)
user模块api重构: /vblog/api/v1/users/login
func (h *Handler) Registry(r gin.IRouter) {
// subrouter的前缀: "/vblog/api/v1/users"
// /vblog/api/v1/users/login
r.POST("/login", h.Login)
}