gRPC 服务要加 HTTP 接口?
go-zero 给大家带来极简的 RESTful 和 gRPC 服务开发体验的同时,社区又给咱们提出了新的冀望:
- 我想只写一次代码
- 既要 gRPC 接口
- 也要 HTTP 接口
- 既要。。。也要。。。
也有情理嘛!你看用户怎么说:
用户A:一套逻辑,api和rpc一起
用户B:go-zero要是能简化这一步我感觉会成为go生态中最好的微服务框架没有之一
于是,我陷入了深深的思考:用户素来是不会错的,然而咱们要不要提供呢?
于是,你看到了这篇文章。。。
咱们先提供 gRPC 服务
对于这种服务,咱们太熟了。新建一个目录,就叫 grpc-restufl
吧,外面放个 sum.proto
文件
syntax = "proto3";package sum;option go_package="./pb";message Numbers { int64 a = 1; int64 b = 2;}message SumRequest { Numbers numbers =1;}message SumResponse { int64 result = 1;}service Sum { rpc Add(SumRequest) returns (SumResponse) {}}
一键生成,你懂的。。。
$ goctl rpc protoc --go_out=. --go-grpc_out=. --zrpc_out=. sum.proto
看看都有了啥
.├── etc│ └── sum.yaml├── go.mod├── internal│ ├── config│ │ └── config.go│ ├── logic│ │ └── addlogic.go│ ├── server│ │ └── sumserver.go│ └── svc│ └── servicecontext.go├── pb│ ├── sum.pb.go│ └── sum_grpc.pb.go├── sum│ └── sum.go├── sum.go└── sum.proto
实现一下业务逻辑,将 internal/logic/addlogic.go
里的 Add
办法批改如下:
func (l *AddLogic) Add(in *pb.SumRequest) (*pb.SumResponse, error) { return &pb.SumResponse{ Result: in.Numbers.A+in.Numbers.B, }, nil}
能够跑了,业务逻辑也是有了的(尽管很简略,演示嘛。。。)
$ go mod tidy && go run sum.goStarting rpc server at 127.0.0.1:8080...
对于相熟 go-zero 的同学来说,至此无亮点(新常识),接下来 GET 新技能~
提供 HTTP 接口
更新 go-zero
首先,咱们更新 go-zero 至 master
版,因为 gateway
还没正式发版,八月初会正式跟大家见面
$ go get -u github.com/zeromicro/go-zero@master
批改 proto 文件
批改 sum.proto
,我新建了一个 sum-api.proto
,如下:
syntax = "proto3";package sum;option go_package="./pb";import "google/api/annotations.proto";message Numbers { int64 a = 1; int64 b = 2;}message SumRequest { Numbers numbers =1;}message SumResponse { int64 result = 1;}service Sum { rpc Add(SumRequest) returns (SumResponse) { option (google.api.http) = { post: "/v1/sum" body: "*" }; }}
生成 proto descriptor 文件
protoc --include_imports --proto_path=. --descriptor_set_out=sum.pb sum-api.proto
批改配置文件
批改后的 internal/config/config.go
如下(局部):
type Config struct { zrpc.RpcServerConf Gateway gateway.GatewayConf}
批改后的 etc/sum.yaml
如下:
Gateway: Name: gateway Port: 8081 Upstreams: - Grpc: Endpoints: - localhost:8080 ProtoSet: sum.pb
批改 main 函数
创立 gateway
并用 ServiceGroup
来治理 gRPC server
和 gateway server
,局部代码如下:
gw := gateway.MustNewServer(c.Gateway) group := service.NewServiceGroup() group.Add(s) group.Add(gw) defer group.Stop() fmt.Printf("Starting rpc server at %s...\n", c.ListenOn) fmt.Printf("Starting gateway at %s:%d...\n", c.Gateway.Host, c.Gateway.Port) group.Start()
功败垂成
让咱们来启动服务
$ go run sum.goStarting rpc server at 127.0.0.1:8080...Starting gateway at 0.0.0.0:8081...
用 curl
测试一下
$ curl -i -H "Content-Type: application/json" -d '{"numbers":{"a":2,"b":3}}' localhost:8081/v1/sumHTTP/1.1 200 OKContent-Type: application/json; charset=utf-8Traceparent: 00-ad5b7df7a834a1c05ee64999e3310811-195ba1f4f9956cc4-00Date: Mon, 18 Jul 2022 14:33:11 GMTContent-Length: 20{ "result": "5"}
再看咱们的 gateway
和 gRPC
的日志里的链路信息和客户端收到的都能对应上,赞!
{"@timestamp":"2022-07-18T22:33:11.437+08:00","caller":"serverinterceptors/statinterceptor.go:76","content":"127.0.0.1:61635 - /sum.Sum/Add - {\"numbers\":{\"a\":2,\"b\":3}}","duration":"0.0ms","level":"info","span":"b3c85cd32a76f8c9","trace":"ad5b7df7a834a1c05ee64999e3310811"}{"@timestamp":"2022-07-18T22:33:11.438+08:00","caller":"handler/loghandler.go:197","content":"[HTTP] 200 - POST /v1/sum - 127.0.0.1:61662 - curl/7.79.1","duration":"0.7ms","level":"info","span":"195ba1f4f9956cc4","trace":"ad5b7df7a834a1c05ee64999e3310811"}
结束语
你看,给咱们的 gRPC
服务加上 HTTP
接口是不是五分钟就能够实现了?是不是?
另外,不要小看这个简略的 gateway
,配置里如果是对接前面的 gRPC
服务发现的话,会主动负载平衡的,并且还能够自定义中间件,想怎么管制就怎么管制。
是不是有点心动了呢?
对了,这个示例的残缺代码在:
https://github.com/kevwan/grpc-restful
我的项目地址
https://github.com/zeromicro/go-zero
欢送应用 go-zero
并 star 反对咱们!
微信交换群
关注『微服务实际』公众号并点击 交换群 获取社区群二维码。