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

Hertz---基础使用

1.server.Default()server.New()

两者都可以设置不同的配置,包括超时、端口等

前者默认继承一个recover中间件,后者没有继承。如果有自定义recover中间件格式的需求就使用后者。

Hertz也支持不同的HOOK。

2 .func(c context.Context, ctx *app.RequestContext)

Hertz有两个上下文,前者专注于处理原信息,后者专注于请求的处理

两个上下文都有储值能力,使用时具体选择哪一个的简单依据:所储存值的生命周期和所选择的上下文要匹配。

ctx 主要用来存储请求级别的变量,请求结束就回收了,特点是查询效率高(底层是 map),协程不安全,且未实现 context.Context 接口。 c 作为上下文在中间件 /handler 之间传递。拥有 context.Context 的所有语义,协程安全。所有需要 context.Context 接口作为入参的地方,直接传递 c 即可。

3. 路由

3.1 路由注册

Hertz 提供了 GETPOSTPUTDELETEANY 等方法用于注册路由。

    h.GET("/get", func(ctx context.Context, c *app.RequestContext) {
        c.String(consts.StatusOK, "get")
    })
    h.POST("/post", func(ctx context.Context, c *app.RequestContext) {
        c.String(consts.StatusOK, "post")
    })
    h.PUT("/put", func(ctx context.Context, c *app.RequestContext) {
        c.String(consts.StatusOK, "put")
    })
    h.DELETE("/delete", func(ctx context.Context, c *app.RequestContext) {
        c.String(consts.StatusOK, "delete")
    })
    h.PATCH("/patch", func(ctx context.Context, c *app.RequestContext) {
        c.String(consts.StatusOK, "patch")
    })
    h.HEAD("/head", func(ctx context.Context, c *app.RequestContext) {
        c.String(consts.StatusOK, "head")
    })
    h.OPTIONS("/options", func(ctx context.Context, c *app.RequestContext) {
        c.String(consts.StatusOK, "options")
    })
    //自定义method
    h.Handle("LOAD","/load", func(ctx context.Context, c *app.RequestContext) {
        c.String(consts.StatusOK, "load")
    })

3.2 路由组

Hertz 提供了路由组( Group )的能力,用于支持路由分组的功能,同时中间件也可以注册到路由组上。

func main() {
   h := server.Default()
   //使用路由组并注册中间件到路由组上
   v1 := h.Group("/v1", basic_auth.BasicAuth(map[string]string{"test": "test"}))
       {
        v1.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
            ctx.JSON(consts.StatusOK, utils.H{"ping": "pong"})
        })
        v1.POST("/post", func(c context.Context, ctx *app.RequestContext) {
            ctx.JSON(consts.StatusOK, utils.H{"post": "ok"})
        })
    }
   h.Spin()
}

3.3 路由类型

Hertz 支持丰富的路由类型用于实现复杂的功能,包括静态路由、参数路由、通配路由。

路由的优先级:静态路由 > 命名路由 > 通配路由

func main() {
    h := server.Default()
    //命名路由
    //  /hertz/xxx
    h.GET("/hertz/:version", func(c context.Context, ctx *app.RequestContext) {
        //获得参数
        version := ctx.Param("version")
        ctx.String(consts.StatusOK, version)
    })

    //通配路由
    //  /hertz/xxx/xxx/xxx...  
    h.GET("/hertz/:version/*action", func(c context.Context, ctx *app.RequestContext) {
        mess := ctx.Param("version") + " " + ctx.Param("action")
        ctx.String(consts.StatusOK, mess)
    })
    h.Spin()
}

4. 参数绑定

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

参数绑定的作用就是把http中请求的参数转到结构体里面。

5. 中间件

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

定义在全局上的中间件在返回404页面时也会执行,而定义在路由组上的中间件不会执行

func MyMiddleware1() app.HandlerFunc {
    return func(c context.Context, ctx *app.RequestContext) {
        fmt.Println("mw 1 start")
        //调用下一个中间件
        ctx.Next(c)
        fmt.Println("mw 1 end")
    }
}
func main() {
    h := server.Default()
    h.Use(MyMiddleware1())
}

6. 代码生成工具---Hz

go install github.com/cloudwego/hertz/cmd/hz@latest

hz 是 Hertz 框架提供的一个用于生成代码的命令行工具。目前,hz 可以基于 thrift 和 protobuf 的 IDL 生成 Hertz 项目的脚手架。

6.1 基于 thrift IDL 创建项目

// idl/hello.thrift
namespace go hello.example

struct HelloReq {
    1: string Name (api.query="name"); // 添加 api 注解为方便进行参数绑定
}

struct HelloResp {
    1: string RespBody;
}


service HelloService {
    HelloResp HelloMethod(1: HelloReq request) (api.get="/hello");
}
  • 创建:hz new -idl idl/hello.thrift -mod example //需要在win开启开发者选项
  • 修改 handler,添加自己的逻辑
  • 更新:hz update -idl idl/hello.thrift

参考链接

[Hertz | CloudWeGo](

最后修改:2023 年 06 月 07 日
如果觉得我的文章对你有用,请随意赞赏