什么是Hertz Hertz[həːts]是一个用于 Go的高性能、高可用性、可扩展的HTTP 框架。它旨在为开发人员简化构建微服务。 为什么选择Hertz Hertz的一大...

什么是Hertz

[həːts]

为什么选择Hertz

Hertz的一大亮点是其极高的性能。您可以通过查看以下有关回显请求的统计信息来对此有所了解。

另一点是它的易用性,我们将在下面讨论。

如何使用Hertz

在这里,我们将编写一个简单的演示,帮助您熟悉Hertz 框架的基本功能。

安装

在使用 Hertz 之前,您需要设置您的 Golang 开发环境并确保它 >= v1.15。

$GOPATH/src
mkdir userdemo
cd userdemo
hz
hzhz

您可以参考hz 工具包使用以获取更多信息。

go install github.com/cloudwego/hertz/cmd/hz@latest
hz -v
hz
hz version v0.2.0

定义 IDL

userdemo
hz
user.thrift
// idl/user.thrift
namespace go user

struct BaseResp {
    1: i64 StatusCode;
    2: string StatusMsg;
    3: string data;
}

struct RegisterRequest {
    1: string Username (api.body="username");
    2: string Password (api.body="password");
}

struct RegisterResponse {
    1: BaseResp BaseResp;
}

struct LoginRequest {
    1: string Username (api.body="username");
    2: string Password (api.body="password");
}

struct LoginResponse {
    1: BaseResp BaseResp;
}

struct InfoRequest {
    1: string Username (api.path="username");
}

struct InfoResponse {
    1: BaseResp BaseResp;
}

service UserService {
    RegisterResponse Register(1: RegisterRequest req) (api.post="/user/register");
    LoginResponse Login(1: LoginRequest req) (api.post="/user/login");
    InfoResponse Info(1: InfoRequest req) (api.get="/user/:username");
}

生成代码

hz
hz new -idl idl/user.thrift
go mod tidy

user.thrift
hz update -idl idl/user.thrift

user.thrift
.
├── biz                               // business layer, which stores business logic related processes
│   ├── handler                       // store handler file
│   │   ├── user                      // user corresponds to the namespace defined in thrift IDL; for protobuf IDL, it corresponds to the last level of go_package
│   │   │   |
│   │   │   |__  user_service.go      // the handler file, the user will implement the method defined by the IDL service in this file, it will search for the existing handler in the current file when "update" command, and append a new handler to the end
│   │   └── ping.go                   // ping handler carried by default, used to generate code for quick debugging, no other special meaning
│   ├── model                         // IDL content-related generation code
│   │   └── user                      // hello/example corresponds to the namespace defined in thrift IDL; for protobuf IDL, it corresponds to the last level of go_package 
│   │         └── user.go             // the product of thriftgo, It contains go code generated from the contents of hello.thrift definition. And it will be regenerated when use "update" command.
│   └── router                        // generated code related to the definition of routes in IDL
│       ├── user                      // hello/example corresponds to the namespace defined in thrift IDL; for protobuf IDL, it corresponds to the last level of go_package
│       │     ├── hello.go            // the route registration code generated for the routes defined in hello.thrift by hz; this file will be regenerated each time the relevant IDL is updated
│       │     └── middleware.go       // default middleware function, hz adds a middleware for each generated route group by default; when updating, it will look for the existing middleware in the current file and append new middleware at the end
│       └── register.go               // call and register the routing definition in each IDL file; when a new IDL is added, the call of its routing registration will be automatically inserted during the update; do not edit
├── go.mod                            // go.mod file, if not specified on the command line, defaults to a relative path to GOPATH as the module name
├── idl                               // user defined IDL, location can be arbitrary
│   └── user.thrift
├── main.go                           // program entry
├── router.go                         // user defined routing methods other than IDL
└── router_gen.go                     // the route registration code generated by hz, for calling user-defined routes and routes generated by hz

使用中间件

Hertz 支持许多常用的中间件。在这种情况下,我们将使用Session 中间件来帮助我们计算用户登录的次数。

hz_loginMwmiddleware.go
func _loginMw() []app.HandlerFunc {
   // your code...
   return []app.HandlerFunc{
      // use session middleware
      sessions.Sessions("usersession", cookie.NewStore([]byte("secret"))),
   }
}

嗯,这不是很容易吗?

改进处理程序

user_service.go

Hertz 负责数据绑定的简单验证和一些杂务。我们需要做的就是处理请求。

Register
PostFormStringJSON
// Register .
// @router /user/register/ [POST]
func Register(ctx context.Context, c *app.RequestContext) {
   var err error
   var req user.RegisterRequest
   err = c.BindAndValidate(&req)
   if err != nil {
      c.String(400, err.Error())
      return
   }

   resp := new(user.RegisterResponse)

   username := c.PostForm("username")
   password := c.PostForm("password")

   if dal.CheckUsername(username) {
      dal.CreateUser(username, password)

      resp.BaseResp = &user.BaseResp{
         StatusCode: 0,
         StatusMsg:  "register success",
      }

      c.JSON(200, resp.BaseResp)
      return
   }

   resp.BaseResp = &user.BaseResp{
      StatusCode: 1,
      StatusMsg:  "register failed",
   }
   c.JSON(400, resp.BaseResp)
}

Login
Register
sessions.DefaultGetSet
// Login .
// @router /user/login/ [POST]
func Login(ctx context.Context, c *app.RequestContext) {
   var err error
   var req user.LoginRequest
   err = c.BindAndValidate(&req)
   if err != nil {
      c.String(400, err.Error())
      return
   }

   resp := new(user.LoginResponse)

   username := c.PostForm("username")
   password := c.PostForm("password")

   if dal.CheckPassword(username, password) {
      session := sessions.Default(c)
      var count int
      cnt := session.Get(username)
      if cnt == nil {
         count = 0
         dal.SetFrequency(username, count)
      } else {
         count = cnt.(int)
         count++
         dal.SetFrequency(username, count)
      }
      session.Set(username, count)
      _ = session.Save()

      resp.BaseResp = &user.BaseResp{
         StatusCode: 0,
         StatusMsg:  "login success",
      }
      c.JSON(200, resp.BaseResp)
      return
   }

   resp.BaseResp = &user.BaseResp{
      StatusCode: 1,
      StatusMsg:  "login failed",
   }
   c.JSON(400, resp.BaseResp)
}

Info
:name
:usernameParam
// Info .
// @router /user/:username [GET]
func Info(ctx context.Context, c *app.RequestContext) {
   var err error
   var req user.InfoRequest
   err = c.BindAndValidate(&req)
   if err != nil {
      c.String(400, err.Error())
      return
   }

   resp := new(user.InfoResponse)

   username := c.Param("username")

   frequency := dal.GetFrequency(username)

   resp.BaseResp = &user.BaseResp{
      StatusCode: 0,
      StatusMsg:  "info success",
      Data:       strconv.Itoa(frequency),
   }

   c.JSON(200, resp)
}

其他功能

router/user/user.gohz
server.Defaultmain.go

既然我们已经介绍了一些主要的 Hertz 方法以及如何使用它们,我希望这将帮助您快速开始使用 Hertz。

概括

这个演示的代码在这里。