REST
GRPC服务一般用于集群内部通信,如果需要对外暴露服务一般会提供等价的REST接口。通过REST接口比较方便前端JavaScript和后端交互。开源社区中的grpc-gateway项目就实现了将GRPC服务转为REST服务的能力。
syntax = "proto3";
package main;
import "google/api/annotations.proto";
message StringMessage {
string value = 1;
}
service RestService {
rpc Get(StringMessage) returns (StringMessage) {
option (google.api.http) = {
get: "/get/{value}"
};
}
rpc Post(StringMessage) returns (StringMessage) {
option (google.api.http) = {
post: "/post"
body: "*"
};
}
}
import "google/api/annotations.proto";存储的仓库路径有区别,在网上找到
https://github.com/googleapis/googleapis/blob/master/google/api/annotations.proto
下载之后把它单独分开,并未在google目录结构:
自己的目录结构如下:
生成grpc代码和rest代码
protoc -I=F:\GoWeb\src\rpc\yuwei\rest -I=F:\GoWeb\src -I=F:\GoWeb\src\github.com\grpc-ecosystem\grpc-gateway\third_party\googleapis --go_out=plugins=grpc:F:\GoWeb\src\rpc\yuwei\rest F:\GoWeb\src\rpc\yuwei\rest\hello.proto
protoc -I=F:\GoWeb\src\rpc\yuwei\rest -I=F:\GoWeb\src -I=F:\GoWeb\src\github.com\grpc-ecosystem\grpc-gateway\third_party\googleapis --grpc-gateway_out=F:\GoWeb\src\rpc\yuwei\rest F:\GoWeb\src\rpc\yuwei\rest\hello.proto
grpc服务:
package main
import (
"context"
"log"
"net"
"rpc/yuwei/rest"
"google.golang.org/grpc"
)
// 定义服务
type HelloServiceImpl struct {
}
func (p *HelloServiceImpl) Get(ctx context.Context, args *rest.StringMessage) (*rest.StringMessage, error) {
reply := &rest.StringMessage{Value: args.GetValue()}
return reply, nil
}
func (p *HelloServiceImpl) Post(ctx context.Context, args *rest.StringMessage) (*rest.StringMessage, error) {
reply := &rest.StringMessage{Value: args.GetValue()}
return reply, nil
}
func main() {
grpcserver := grpc.NewServer()
rest.RegisterRestServiceServer(grpcserver, new(HelloServiceImpl))
lis, err := net.Listen("tcp", ":5000")
if err != nil {
log.Fatal(err)
}
grpcserver.Serve(lis)
}
rest服务:
package main
import (
"context"
"log"
"net/http"
"rpc/yuwei/rest"
"google.golang.org/grpc"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
)
func main() {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
mux := runtime.NewServeMux()
var opts []grpc.DialOption
opts = append(opts, grpc.WithInsecure())
err := rest.RegisterRestServiceHandlerFromEndpoint(
ctx, mux, "localhost:5000",
opts,
)
if err != nil {
log.Fatal(err)
}
http.ListenAndServe(":8080", mux)
}