Hertz | 青训营笔记

27 阅读2分钟

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

Hertz

Hertz是一个字节跳动开发的一个微服务框架,他像gin一样可以提供基础的web服务,接收POST、GET、PUT等基础的web请求。相比Gin,它的特点是高性能、高扩展性、高可靠,专注于微服务通信与治理。

原来的Hertz是用于企业内部的微服务搭建的,但是现在他是一个开源框架,可以给其他开发者提供非常大的帮助。

GitHub: github.com/cloudwego/h…

安装

使用go get工具进行安装go get github.com/cloudwego/hertz/cmd/hz@latest

Demo代码

package main

import (
    "context"

    "github.com/cloudwego/hertz/pkg/app"
    "github.com/cloudwego/hertz/pkg/app/server"
    "github.com/cloudwego/hertz/pkg/common/utils"
    "github.com/cloudwego/hertz/pkg/protocol/consts"
)

func main() {
    h := server.Default()

    h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
            ctx.JSON(consts.StatusOK, utils.H{"message": "pong"})
    })

    h.Spin()
}

上面的代码展示了Hertz的基础的路由绑定和响应的功能。启动服务后访问/ping目录,即可对请求响应并返回json数据。

路由

Hertz提供了非常多的路由函数,他们有

  • StaticFS(用于路由静态文件)
  • GET
  • POST
  • PUT
  • DELETE
  • PATCH
  • HEAD
  • OPTIONS
  • Any
  • Handle

用他们可以快速的进行路由绑定。

路由分组

同时hertz提供了Group即路由分组功能,可以对同一个路径的路由进行统一管理。

func main(){
	h := server.Default(server.WithHostPorts("127.0.0.1:8080"))
	v1 := h.Group("/v1")
	v1.GET("/get", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "get")
	})
	v1.POST("/post", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "post")
	})
	v2 := h.Group("/v2")
	v2.PUT("/put", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "put")
	})
	v2.DELETE("/delete", func(ctx context.Context, c *app.RequestContext) {
		c.String(consts.StatusOK, "delete")
	})
	h.Spin()
}

例如上方代码中,将路由分组为/v1和/v2,如果后期需要添加中间件等进行鉴权,将会非常的方便。

路由参数

使用:name这样的参数来对路由路径上的变量进行预设,并通过c.Param来进行获取。例如下方的代码中,获取了路由中的version的数值。

h.GET("/hertz/:version", func(ctx context.Context, c *app.RequestContext) {
    version := c.Param("version")
    c.String(consts.StatusOK, "Hello %s", version)
})

无路由 无方法

对没有没有指定路由、方法的路径,可以设置无路由和无方法的响应函数。函数名分别是NoRouteNoMethod

h.NoRoute(func(c context.Context, ctx *app.RequestContext) {
    ctx.String(consts.StatusOK, "no route")
})
h.NoMethod(func(c context.Context, ctx *app.RequestContext) {
    ctx.String(consts.StatusOK, "no method")
})

中间件

中间件可以用来检查和过滤业务请求,比如对请求进行jwt鉴权,session判断等等。

实现一个中间件函数非常简单,只需要定义一个函数,返回app.HandlerFunc。参数分别是context.Context*app.RequestContext。该函数会在调用Next后,继续执行下一个中间件。

func MyMiddleware() app.HandlerFunc {
   return func(ctx context.Context, c *app.RequestContext) {
      // 前处理
      c.Next(ctx)
      // 后处理
   }
}

如果在你自己实现的中间件中,遇到需要立刻停止执行的情况,可以调用下面的函数进行中止。

  • Abort()
  • AbortWithMsg(msg string, statusCode int)
  • AbortWithStatus(code int)

要使用中间件也很容易,根据不同级别的中间件,有多种注册方式

全业务

使用下面的函数,中间件会对所有请求生效 h.Use(MyMiddleware())

分组

对Group使用Use,会对该分组下的所有请求生效。

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")
    })...)