Does gRPC service need to add HTTP interface?
While go-zero brings you a minimalist RESTful and gRPC service development experience, the community has put forward new expectations for us:
- I want to write code only once
- Both the gRPC interface
- also HTTP interface
- both. . . also. . .
Makes sense too! See what users say:
User A: a set of logic, api and rpc together
User B: If go-zero can simplify this step, I feel that it will become one of the best microservice frameworks in the go ecosystem
So, I fell into deep thinking: users can never be wrong, but should we provide it?
So, you saw this article. . .
We first provide gRPC services
We are all too familiar with this kind of service. Create a new directory, call grpc-restufl
it , and put a sum.proto
file in it
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) {}
}
One-click generation, you know. . .
$ goctl rpc protoc --go_out=. --go-grpc_out=. --zrpc_out=. sum.proto
look what's there
.
├── 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
To implement the business logic internal/logic/addlogic.go
, Add
modify the method in as follows:
func (l *AddLogic) Add(in *pb.SumRequest) (*pb.SumResponse, error) {
return &pb.SumResponse{
Result: in.Numbers.A+in.Numbers.B,
}, nil
}
It can be run, and the business logic is also available (although it is very simple, it is a demonstration...)
$ go mod tidy && go run sum.go
Starting rpc server at 127.0.0.1:8080...
For students who are familiar with go-zero, there is no bright spot (new knowledge) so far, and then GET new skills~
Provide HTTP interface
Update go-zero
First of all, we update go-zero to master
version , because it gateway
has not been officially released yet, we will officially meet you in early August
$ go get -u github.com/zeromicro/go-zero@master
Modify the proto file
Modification sum.proto
, I created a new one sum-api.proto
, as follows:
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: "*"
};
}
}
Generate proto descriptor file
protoc --include_imports --proto_path=. --descriptor_set_out=sum.pb sum-api.proto
Modify the configuration file
The modified is internal/config/config.go
as follows (in part):
type Config struct {
zrpc.RpcServerConf
Gateway gateway.GatewayConf
}
The modified is etc/sum.yaml
as follows :
Gateway:
Name: gateway
Port: 8081
Upstreams:
- Grpc:
Endpoints:
- localhost:8080
ProtoSet: sum.pb
Modify the main function
Create gateway
and use ServiceGroup
to manage gRPC server
and gateway server
, part of the code is as follows:
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()
you're done
Let's start the service
$ go run sum.go
Starting rpc server at 127.0.0.1:8080...
Starting gateway at 0.0.0.0:8081...
curl
test it with
$ curl -i -H "Content-Type: application/json" -d '{"numbers":{"a":2,"b":3}}' localhost:8081/v1/sum
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Traceparent: 00-ad5b7df7a834a1c05ee64999e3310811-195ba1f4f9956cc4-00
Date: Mon, 18 Jul 2022 14:33:11 GMT
Content-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
服务发现的话,会自动负载均衡的,并且还可以自定义中间件,想怎么控制就怎么控制。
是不是有点心动了呢?
对了,这个示例的完整代码在:
项目地址
欢迎使用 go-zero
并 star 支持我们!
微信交流群
关注『微服务实践』公众号并点击 交流群 获取社区群二维码。