grpc-gateway是protoc的一个插件。它读取gRPC服务定义,并生成一个反向代理服务器,将RESTful JSON API转换为gRPC。此服务器是根据gRPC定义中的自定义选项生成的。
安装
安装插件
go get \github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \google.golang.org/protobuf/cmd/protoc-gen-go \google.golang.org/grpc/cmd/protoc-gen-go-grpc
下载需要使用到的proto
google/protobuf下载参考https://www.yuque.com/jw-go/mqm3eb/gy8npv
google/api 下载地址https://github.com/googleapis/googleapis
文件相互依赖,一次性下载后比较省心
lxdeMacBook-Pro-2:src lx$ pwd/Users/lx/gopath/srclxdeMacBook-Pro-2:src lx$ tree google/google/├── api│ ├── BUILD.bazel│ ├── README.md│ ├── annotations.proto│ ├── auth.proto│ ├── backend.proto│ ├── billing.proto│ ├── client.proto│ ├── config_change.proto│ ├── consumer.proto│ ├── context.proto│ ├── control.proto│ ├── distribution.proto│ ├── documentation.proto│ ├── endpoint.proto│ ├── error_reason.proto│ ├── expr│ │ ├── BUILD.bazel│ │ ├── cel.yaml│ │ ├── v1alpha1│ │ │ ├── BUILD.bazel│ │ │ ├── checked.proto│ │ │ ├── conformance_service.proto│ │ │ ├── eval.proto│ │ │ ├── explain.proto│ │ │ ├── syntax.proto│ │ │ └── value.proto│ │ └── v1beta1│ │ ├── BUILD.bazel│ │ ├── decl.proto│ │ ├── eval.proto│ │ ├── expr.proto│ │ ├── source.proto│ │ └── value.proto│ ├── field_behavior.proto│ ├── http.proto│ ├── httpbody.proto│ ├── label.proto│ ├── launch_stage.proto│ ├── log.proto│ ├── logging.proto│ ├── metric.proto│ ├── monitored_resource.proto│ ├── monitoring.proto│ ├── quota.proto│ ├── resource.proto│ ├── service.proto│ ├── serviceconfig.yaml│ ├── servicecontrol│ │ ├── BUILD.bazel│ │ ├── README.md│ │ └── v1│ │ ├── BUILD.bazel│ │ ├── check_error.proto│ │ ├── distribution.proto│ │ ├── http_request.proto│ │ ├── log_entry.proto│ │ ├── metric_value.proto│ │ ├── operation.proto│ │ ├── quota_controller.proto│ │ ├── service_controller.proto│ │ ├── servicecontrol.yaml│ │ └── servicecontrol_gapic.yaml│ ├── servicemanagement│ │ ├── BUILD.bazel│ │ ├── README.md│ │ └── v1│ │ ├── BUILD.bazel│ │ ├── resources.proto│ │ ├── servicemanagement_gapic.legacy.yaml│ │ ├── servicemanagement_gapic.yaml│ │ ├── servicemanagement_grpc_service_config.json│ │ ├── servicemanagement_v1.yaml│ │ └── servicemanager.proto│ ├── source_info.proto│ ├── system_parameter.proto│ └── usage.proto└── protobuf├── any.proto├── api.proto├── compiler│ └── plugin.proto├── descriptor.proto├── duration.proto├── empty.proto├── field_mask.proto├── source_context.proto├── struct.proto├── timestamp.proto├── type.proto└── wrappers.proto
跑通流程

1.准备proto文件
syntax = "proto3";package protobuf;import "google/api/annotations.proto";option go_package = "protobuf;protobuf";message StringMessage{string value = 1;}service EchoService{rpc Echo(StringMessage) returns (StringMessage){option (google.api.http) = {post: "/v1/example/echo"};}}
2.生成grpc存根
protoc --proto_path=/Users/lx/gopath/src --proto_path=. \--go_out=plugins=grpc,paths=source_relative:. \test.proto
3.生成代理文件
protoc --proto_path=/Users/lx/gopath/src --proto_path=. \--grpc-gateway_out . \--grpc-gateway_opt logtostderr=true \--grpc-gateway_opt paths=source_relative \test.proto
4.service端
package mainimport ("log""net"pb "commons/grpc/protobuf""golang.org/x/net/context""google.golang.org/grpc")const (RPCPORT = ":9192")type server struct{}func (s *server) Echo(ctx context.Context, in *pb.StringMessage) (*pb.StringMessage, error) {log.Println("request: ", in.Value)return &pb.StringMessage{Value: "Hello " + in.Value}, nil}func main() {lis, err := net.Listen("tcp", RPCPORT)if err != nil {log.Fatalf("failed to listen: %v", err)}s := grpc.NewServer()pb.RegisterEchoServiceServer(s, &server{})log.Println("rpc服务已经开启")s.Serve(lis)}
5.gateway
package mainimport ("context""flag""log""net/http"gw "commons/grpc/protobuf""github.com/grpc-ecosystem/grpc-gateway/v2/runtime""google.golang.org/grpc")var (echoEndpoint = flag.String("echo_endpoint", "localhost:9192", "endpoint of Gateway"))func run() error {ctx := context.Background()ctx, cancel := context.WithCancel(ctx)defer cancel()mux := runtime.NewServeMux()opts := []grpc.DialOption{grpc.WithInsecure()}err := gw.RegisterEchoServiceHandlerFromEndpoint(ctx, mux, *echoEndpoint, opts)if err != nil {return err}log.Println("服务开启")return http.ListenAndServe(":8080", mux)}func main() {flag.Parse()if err := run(); err != nil {log.Fatal(err)}}
- 测试
- 404

- ok

- methmod not allowed

