Hertz的使用 | 青训营笔记

150 阅读2分钟

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

概览

Hertz是一个Golang 微服务HTTP框架,具有高易用性、高性能、高扩展性等特点,目前在字节跳动内部已广泛使用。

Hertz 架构设计

Hertz架构自底向上分为Transport,Protocol,Route,Application四层。

框架特点

  • 高易用性
  • 高性能
  • 高扩展性 采用分层设计,提供了较多的接口以及默认的扩展实现,用户也可以自行扩展。
  • 多协议支持 支持HTTP1.1、ALPN等协议,支持自定义构建协议解析逻辑
  • 网络层切换能力 Hertz实现了Netpoll和Golong原生网络库间按需切换的能力。

Hertz路由

  • hertz提供了GET、POST、PUT、DELETE、ANY等方法用于注册路由。

示例:

 func RegisterRoute(h server.Hertz) {
   h.GET("/get"func(ctx context.Context, c *app.RequestContext)) {
   c.String(consts.StatusOK, "get")
  }
 }
  • Hertz提供了路由组的组图,用于支持路由分组
 v1 := h.Group("/v1")
 v1.GET("/get", handler)
 v1.POST("/post", handler)
 ​
 v2 := h.Group("/v2")
 v2.POST("/post", handler)
  • Hertz 提供了参数路由和通配路由
  • 路由优先级为静态路由 > 命名路由 > 通配路由
 // 参数路由
 h.GET("/hertz/:version")
 // 通配路由
 h.GET("/hertz/:version/*action")

Hertz参数绑定

hertz提供了Bind,Validate,BindAndValidate函数用于参数绑定和校验。

 type Args struct {
   Query string `query:"query"` //绑定query参数
   QuerySlice []string `query:"q"`
   Path string `path:"path"` //path参数
   Header string `header:"header"` //header参数
   Json string `json:"json"` //Json参数
   Form string `form:"form"` //表单参数 
   Vd int `query:"vd" vd:"$==0||$==1"` //参数校验
 }
 ​
 func main() {
   s := server.Default(server.WithHostPorts("127.0.0.1:8080"))
   s.GET("/hello"func(c context.Context, ctx *app.RequestContext) {
   // BindAndValidate
   var args Args
   err := ctx.BindAndValidate(&args)
  })
 }

Hertz中间件

Hertz的中间件主要分为客户端中间件和服务端中间件

服务端中间件

服务端中间件是 HTTP 请求-响应周期中的一个函数,提供了一种方便的机制来检查和过滤进入应用程序的 HTTP 请求, 例如记录每个请求或者启用CORS。中间件可以在请求更深入地传递到业务逻辑之前或之后执行。

实现一个中间件

 // 方式一
 func MyMiddleware() app.HandlerFunc {
   return func(ctx context.Context, c *app.RequestContext) {
   // pre-handle
   // ...
   c.Next(ctx)
  }
 }
 ​
 // 方式二
 func MyMiddleware() app.HandlerFunc {
   return func(ctx context.Context, c *app.RequestContext) {
   c.Next(ctx) // call the next middleware(handler)
   // post-handle
   // ...
  }
 }

中间件会按定义的先后顺序依次执行,可以使用以下方法终止中间件调用,但当前中间件将执行

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

设置中间件的方式

  • Server级别中间件
 h := server.Default()
 h.Use(GlobalMiddleware())
  • 路由组级别中间件
 h := server.Default()
 group := h.Group("/group")
 group.Use(GroupMiddleware())
  • 单一路由级别中间件
 h.GET("/path"append(PathMiddleware(),
 func(ctx context.Context, c *app.RequestContext) {
 c.String(http.StatusOK, "path")
 })...)

Hertz Client

Hertz提供了HTTP Client用于发送HTTP请求

 c, err := client.NewClient()
 if err != nil {
   return
 }
 ​
 status, body, _ := c.Get(context.Background(), nil, url)