Hertz框架入门
概述
Hertz[ 是一个 Golang 微服务 HTTP 框架,在设计之初参考了其他开源框架 fasthttp、gin、echo 的优势, 并结合字节跳动内部的需求,使其具有高易用性、高性能、高扩展性等特点,目前在字节跳动内部已广泛使用。 如今越来越多的微服务选择使用 Golang,如果对微服务性能有要求,又希望框架能够充分满足内部的可定制化需求,Hertz 会是一个不错的选择。
安装Hertz与测试
创建一个main.go文件
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()
}
生成 go.mod 文件
go mod init
整理 & 拉取依赖。
go mod tidy
就可以运行代码
hz命令行工具安装
hz 是 Hertz 框架提供的一个用于生成代码的命令行工具。目前,hz 可以基于 thrift 和 protobuf 的 IDL 生成 Hertz 项目的脚手架。
1.确保 GOPATH 环境变量已经被正确的定义(例如 export GOPATH=~/go)并且将$GOPATH/bin添加到 PATH 环境变量之中(例如 export PATH=$GOPATH/bin:$PATH);请勿将 GOPATH 设置为当前用户没有读写权限的目录
一定要注意是否配置好环境变量,安装后否则会出现找不到hz命令
安装hz
go install github.com/cloudwego/hertz/cmd/hz@latest
验证是否安装成功
hz -v
运行使用thrift的IDL通过hz的代码生成工具,需要安装对应的编译器。
thriftgo:
GO111MODULE=on go install github.com/cloudwego/thriftgo@latest
使用
# 在 GOPATH 外执行,需要指定 go mod 名
hz new -module hertz/demo
# 整理 & 拉取依赖
go mod tidy
初始化服务
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()
}
curl http://127.0.0.1:8888/ping
//会得到这样的输出{"message":"pong"}
并未为设置对应的ip地址和端口号,就可以在http://127.0.0.1:8888/ping访问到服务,应该是server.Default()做了一些初始化工作。可以通过server的配置传入对应的参数,来自定义服务。
Hertz 提供了一些关于server的配置
Hertz 提供了 Spin 函数用于启动服务器。
和 route.Engine 中提供的 Run 不同,除非有特殊需求,不然一般使用 Spin 函数用于运行服务。
在使用 服务注册发现 的功能时,Spin 会在服务启动时将服务注册进入注册中心,并使用 signalWaiter 监测服务异常。 只有使用 Spin 来启动服务才能支持 优雅退出 的特性。
路由
与gin框架的写法大致一样
package main
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/app/server"
"github.com/cloudwego/hertz/pkg/protocol/consts"
)
func main(){
h := server.Default(server.WithHostPorts("127.0.0.1:8080"))
h.StaticFS("/", &app.FS{Root: "./", GenerateIndexPages: true})
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.Spin()
}
提供了参数绑定可以从请求中获取到对应类型的请求信息
func (ctx *RequestContext) BindAndValidate(obj interface{}) erro
func HelloMethod(ctx context.Context, c *app.RequestContext) {
var err error
var req example.HelloReq\HelloReq类型
fmt.Println(req)
err = c.BindAndValidate(&req)//将req地址传入与c请求做绑定,省去了从c中再获取对应的参数
fmt.Println(req)
if err != nil {
c.String(400, err.Error())
return
}
resp := new(example.HelloResp)
// 你可以修改整个函数的逻辑,而不仅仅局限于当前模板
resp.RespBody = "hello," + req.Name // 添加的逻辑
c.JSON(200, resp)
}
type HelloReq struct {
Name string `thrift:"Name,1" json:"Name" query:"name"`
}