继续学习 hz 的例子
使用 hz 与 protobuf 生成服务端代码的示例
在当前文件夹里新建 idl 文件夹,然后在这个文件夹里面先放一个 api.proto 用来扩展 protobuf 的功能,比如支持 API 注解。
syntax = "proto2";
package api;
import "google/protobuf/descriptor.proto";
option go_package = "/api";
extend google.protobuf.FieldOptions {
optional string raw_body = 50101;
optional string query = 50102;
optional string header = 50103;
optional string cookie = 50104;
optional string body = 50105;
optional string path = 50106;
optional string vd = 50107;
optional string form = 50108;
optional string go_tag = 51001;
optional string js_conv = 50109;
}
extend google.protobuf.MethodOptions {
optional string get = 50201;
optional string post = 50202;
optional string put = 50203;
optional string delete = 50204;
optional string patch = 50205;
optional string options = 50206;
optional string head = 50207;
optional string any = 50208;
optional string gen_path = 50301;
optional string api_version = 50302;
optional string tag = 50303;
optional string name = 50304;
optional string api_level = 50305;
optional string serializer = 50306;
optional string param = 50307;
optional string baseurl = 50308;
}
extend google.protobuf.EnumValueOptions {
optional int32 http_code = 50401;
}
主要的 idl 文件放在单独的文件夹 hello 里,文件名也叫 hello.proto:
// idl/hello/hello.proto
syntax = "proto3";
package hello;
option go_package = "hertz/hello";
import "api.proto";
message HelloReq {
string Name = 1[(api.query)="name"];
}
message HelloResp {
string RespBody = 1;
}
service HelloService {
rpc Method1(HelloReq) returns(HelloResp) {
option (api.get) = "/hello";
}
}
然后回到 idl 文件夹的上一级,在这里创建新项目:
// 如果主 IDL 的依赖和主 IDL 不在同一路径下,需要加入 -I 选项,其含义为 IDL 搜索路径,等同于 protoc 的 -I 命令
hz new -I idl -idl idl/hello/hello.proto
// 整理 & 拉取依赖
go mod tidy
之后就是修改 handler 里面的逻辑了,对应的文件在 biz/handler/hello/hello_service.go,其中 /hello 是 protobuf idl 中 go_package 的最后一级,hello_service.go 是 protobuf idl 中 service 的名字,所有 service 定义的方法都会生成在这个文件中。
// Method1 .
// @router /hello [GET]
func Method1(ctx context.Context, c *app.RequestContext) {
var err error
var req hello.HelloReq
err = c.BindAndValidate(&req)
if err != nil {
c.String(400, err.Error())
return
}
resp := new(hello.HelloResp)
// 你可以修改整个函数的逻辑,而不仅仅局限于当前模板
resp.RespBody = "hello," + req.Name // 添加的逻辑
c.JSON(200, resp)
}
下一步编译项目:
go build
然后找到文件夹里的可执行文件运行,然后再开一个终端运行 curl --location --request GET 'http://127.0.0.1:8888/hello?name=hertz',如果返回 {"RespBody":"hello,hertz"},说明接口调通。