目录
hz 安装
hz 安装。
hz 是 Hertz 框架提供的一个用于生成代码的命令行工具。目前,hz 可以基于 thrift 和 protobuf 的 IDL 生成 Hertz 项目的脚手架。
安装
-
确保
GOPATH
环境变量已经被正确的定义(例如export GOPATH=~/go
)并且将$GOPATH/bin
添加到PATH
环境变量之中(例如export PATH=$GOPATH/bin:$PATH
);请勿将GOPATH
设置为当前用户没有读写权限的目录 -
安装 hz:
go install github.com/cloudwego/hertz/cmd/hz@latest
-
验证是否安装成功
hz -v
, 如果显示如下版本的信息,则说明安装成功hz version v0.x.x
注意,由于 hz 会为自身的二进制文件创建软链接,因此请确保 hz 的安装路径具有可写权限。
运行模式
要使用 thrift 或 protobuf 的 IDL 生成代码,需要安装相应的编译器:thriftgo 或 protoc 。
hz 生成的代码里,一部分是底层的编译器生成的(通常是关于 IDL 里定义的结构体),另一部分是 IDL 中用户定义的路由、method 等信息。用户可直接运行该代码。
从执行流上来说,当 hz 使用 thrift IDL 生成代码时,hz 会调用 thriftgo 来生成 go 结构体代码,并将自身作为 thriftgo 的一个插件(名为 thrift-gen-hertz)来执行并生成其他代码。当用于 protobuf IDL 时亦是如此。
$> hz ... --idl=IDL
|
| thrift-IDL
|---------> thriftgo --gen go:... -plugin=hertz:... IDL
|
| protobuf-IDL
---------> protoc --hertz_out=... --hertz_opt=... IDL
如何安装 thriftgo/protoc:
thriftgo:
GO111MODULE=on go install github.com/cloudwego/thriftgo@latest
protoc:
// brew 安装
$ brew install protobuf
// 官方镜像安装,以 macos 为例
$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/protoc-3.19.4-osx-x86_64.zip
$ unzip protoc-3.19.4-osx-x86_64.zip
$ cp bin/protoc /usr/local/bin/protoc
// 确保 include/google 放入 /usr/local/include下
$ cp -r include/google /usr/local/include/google
基本使用
new: 创建一个 Hertz 新项目
-
创建新项目
# 在 GOPATH 外执行,需要指定 go mod 名 hz new -module hertz/demo # 整理 & 拉取依赖 go mod tidy
执行后会在当前目录下生成 Hertz 项目的脚手架。
-
编译项目
go build
运行项目并测试
-
运行项目:
./{{your binary}}
测试:
curl 127.0.0.1:8888/ping
如果返回
{"message":"pong"}
,说明接口调通。
hz 使用 (thrift)
hz 使用 (thrift)。
基于 thrift IDL 创建项目
new: 创建一个新项目
-
在当前目录下创建 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"); }
-
创建新项目
# 不在`$GOPATH`下的项目通过工具提供的`-module`命令指定一个自定义 module 名称即可: hz new -module example.com/m -idl idl/hello.thrift # 整理 & 拉取依赖 go mod tidy # 查看 go.mod 中 github.com/apache/thrift 版本是否为 v0.13.0,如果不是则继续执行 2.2 小节剩余代码 go mod edit -replace github.com/apache/thrift=github.com/apache/thrift@v0.13.0 # 整理 & 拉取依赖 go mod tidy
-
修改 handler,添加自己的逻辑
// handler path: biz/handler/hello/example/hello_service.go // 其中 "hello/example" 是 thrift idl 的 namespace // "hello_service.go" 是 thrift idl 中 service 的名字,所有 service 定义的方法都会生成在这个文件中 // HelloMethod . // @router /hello [GET] func HelloMethod(ctx context.Context, c *app.RequestContext) { var err error var req example.HelloReq err = c.BindAndValidate(&req) if err != nil { c.String(400, err.Error()) return } resp := new(example.HelloResp) // 你可以修改整个函数的逻辑,而不仅仅局限于当前模板 resp.RespBody = "hello," + req.Name // 添加的逻辑 c.JSON(200, resp) }
-
编译项目
go build
-
运行项目并测试
运行项目:
./{{your binary}}
测试:
curl --location --request GET 'http://127.0.0.1:8888/hello?name=hertz'
如果返回
{"RespBody":"hello,hertz"}
,说明接口调通。
update: 更新一个已有的项目
-
如果你的 thrift idl 有更新,例如:
// idl/hello.thrift namespace go hello.example struct HelloReq { 1: string Name (api.query="name"); } struct HelloResp { 1: string RespBody; } struct OtherReq { 1: string Other (api.body="other"); } struct OtherResp { 1: string Resp; } service HelloService { HelloResp HelloMethod(1: HelloReq request) (api.get="/hello"); OtherResp OtherMethod(1: OtherReq request) (api.post="/other"); } service NewService { HelloResp NewMethod(1: HelloReq request) (api.get="/new"); }
-
切换到执行 new 命令的目录,更新修改后的 thrift idl
hz update -idl idl/hello.thrift
-
可以看到
在 “biz/handler/hello/example/hello_service.go” 下新增了新的方法
在 “biz/handler/hello/example” 下新增了文件 “new_service.go” 以及对应的 “NewMethod” 方法。下面我们来开发 “OtherMethod” 接口:
// OtherMethod . // @router /other [POST] func OtherMethod(ctx context.Context, c *app.RequestContext) { var err error // example.OtherReq 对应的 model 文件也会重新生成 var req example.OtherReq err = c.BindAndValidate(&req) if err != nil { c.String(400, err.Error()) return } resp := new(example.OtherResp) // 增加的逻辑 resp.Resp = "Other method: " + req.Other c.JSON(200, resp) }
-
编译项目
go build
-
运行项目并测试
运行项目:
./{{your binary}}
测试:
curl --location --request POST 'http://127.0.0.1:8888/other' \ --header 'Content-Type: application/json' \ --data-raw '{ "Other": "other method" }'
如果返回
{"Resp":"Other method: other method"}
,说明接口调通。