Kitex(二)和Hertz| 青训营笔记

442 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第14天

参数绑定与校验

Hertz提供了Bind、Validate、BindAndValidate函数用于进行参数绑定和校验

支持的tag

go tag说明
path绑定 url 上的路径参数,相当于 hertz 路由{:param}或{*param}中拿到的参数。例如:如果定义的路由为: /v:version/example,可以把 path 的参数指定为路由参数:path:"version",此时,url: http://127.0.0.1:8888/v1/example,可以绑定path参数"1"
form绑定请求的 body 内容。content-type -> multipart/form-dataapplication/x-www-form-urlencoded,绑定 form 的 key-value
query绑定请求的 query 参数
header绑定请求的 header 参数
json绑定请求的 body 内容 content-type -> application/json,绑定 json 参数
raw_body绑定请求的原始 body(bytes),绑定的字段名不指定,也能绑定参数
vd参数校验,校验语法

参数绑定优先级:path>form>query>cookie>header>json>raw_body

func main() {
    r := server.New()
​
    r.GET("/hello", func(c context.Context, ctx *app.RequestContext) {
        // 参数绑定需要配合特定的go tag使用
        type Test struct {
            A string `query:"a" vd:"$!='Hertz'"`
        }
​
        // BindAndValidate
        var req Test
        err := ctx.BindAndValidate(&req)
​
        ...
​
        // Bind
        req = Test{}
        err = ctx.Bind(&req)
​
        ...
​
        // Validate,需要使用 "vd" tag
        err = ctx.Validate(&req)
​
        ...
    })
...
}

中间件

服务端中间件

Hertz服务端中间件是HTTP请求-响应周期中的一个函数,提供了一种方便的机制来检查和过滤进入应用程序的HTTP请求

实现中间件

// 方式一
func MyMiddleware() app.HandlerFunc {
  return func(ctx context.Context, c *app.RequestContext) {
    // 初始化
    // ...
    c.Next(ctx)
  }
}
​
// 方式二
func MyMiddleware() app.HandlerFunc {
  return func(ctx context.Context, c *app.RequestContext) {
    c.Next(ctx) 
    // ...
  }
}

中间件会按定义的先后顺序依次执行,如果想快速终止中间件调用,可以使用以下方法,不过当前中间件仍将执行

  • Abort():终止后续调用
  • AbortWithMsg(msg string, statusCode int):终止后续调用,并设置 response中body,和状态码
  • AbortWithStatus(code int):终止后续调用,并设置状态码

Server级别中间件

会对整个server的路由生效

h := server.Default()
h.Use(GlobalMiddleware())

路由器级别中间件

对当前路由组下的路径生效

h := server.Default()
group := h.Group("/group")
group.Use(GroupMiddleware())

单一路由级别中间件

func PathMiddleware() []app.HandlerFunc {
    return []app.HandlerFunc{func(ctx context.Context, c *app.RequestContext) {
        fmt.Println("path middleware")
        c.Next(ctx)
    }}
}
​
func main() {
    h := server.Default(server.WithHostPorts("127.0.0.1:8888"))
​
    h.GET("/path", append(PathMiddleware(),
        func(ctx context.Context, c *app.RequestContext) {
            c.String(http.StatusOK, "path")
        })...)
​
    h.Spin()
}

使用默认中间件

server.Default():默认可以注册recover中间件

客户端中间件

客户端中间件可以在请求之前或获取相应之后执行

实现中间件

func MyMiddleware(next client.Endpoint) client.Endpoint {
  return func(ctx context.Context, req *protocol.Request, resp *protocol.Response) (err error) {
    // ...
    err = next(ctx, req, resp)
    if err != nil {
      return
    }
    // ...
  }
}

注册中间件

c, err := client.NewClient()
c.Use(MyMiddleware)

HZ

代码生成工具,通过定义IDL文件即可生成对应的基础服务代码