gRPC-Gateway helps you to provide your APIs in both gRPC and RESTful style at the same time.
官方网站:https://github.com/grpc-ecosystem/grpc-gateway
官方文档:https://grpc-ecosystem.github.io/grpc-gateway/

image.png

配置插件

下载

  1. $ go get github.com/grpc-ecosystem/grpc-gateway
  2. go: downloading github.com/grpc-ecosystem/grpc-gateway v1.16.0
  3. go: github.com/grpc-ecosystem/grpc-gateway upgrade => v1.16.0

进入

  1. cd $GOPATH/pkg/mod/github.com/grpc-ecosystem/grpc-gateway@v1.16.0/protoc-gen-grpc-gateway
  2. $ go install

proto

  1. syntax = "proto3";
  2. package user;
  3. //引入google api实现http转rpc
  4. import "google/api/annotations.proto";
  5. message UserRequest{
  6. // [修饰符] 类型 字段名 = 标识符
  7. string name = 1;
  8. }
  9. message UserResponse{
  10. int32 id = 1;
  11. string name = 2;
  12. int32 age = 3;
  13. repeated string title = 4; // 可变数组,即 slice 类型
  14. }
  15. service userInfoService {
  16. rpc GetUserInfo(UserRequest) returns (UserResponse){
  17. option (google.api.http) = {
  18. post: "/v1/userInfo"
  19. body: "*"
  20. };
  21. }
  22. }

执行

  1. protoc -I/usr/local/include -I. \
  2. -I$GOPATH/src \
  3. -I$GOPATH/pkg/mod/github.com/grpc-ecosystem/grpc-gateway\@v1.16.0/third_party/googleapis/ \
  4. --go_out=plugins=grpc:. \
  5. proto/user.proto

生成pb代理文件

  1. protoc -I/usr/local/include -I. \
  2. -I$GOPATH/src \
  3. -I$GOPATH/pkg/mod/github.com/grpc-ecosystem/grpc-gateway\@v1.16.0/third_party/googleapis/ \
  4. --grpc-gateway_out=logtostderr=true:. \
  5. proto/user.proto

图片.png

user 服务代码

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "google.golang.org/grpc"
  6. proto "github.com/baxiang/go-note/grpc_gateway_service/proto"
  7. "log"
  8. "net"
  9. )
  10. //定义服务端 实现 约定的接口
  11. type UserInfoService struct{}
  12. //实现 interface
  13. func (s *UserInfoService) GetUserInfo(ctx context.Context, req *proto.UserRequest) (resp *proto.UserResponse, err error) {
  14. resp = &proto.UserResponse{
  15. Id: 1,
  16. Name: req.Name,
  17. Age: 25,
  18. Title: []string{"Java", "Go"},
  19. }
  20. return
  21. }
  22. func main() {
  23. port := ":6666"
  24. l, err := net.Listen("tcp", port)
  25. if err != nil {
  26. log.Fatalf("listen error: %v\n", err)
  27. }
  28. fmt.Printf("listen %s\n", port)
  29. s := grpc.NewServer()
  30. // 将 UserInfoService 注册到 gRPC
  31. // 注意第二个参数 UserInfoServiceServer 是接口类型的变量
  32. // 需要取地址传参
  33. proto.RegisterUserInfoServiceServer(s, &UserInfoService{})
  34. s.Serve(l)
  35. }

执行服务

  1. go run cmd/server/server.go

网关代码

  1. package main
  2. import (
  3. "context"
  4. "github.com/grpc-ecosystem/grpc-gateway/runtime"
  5. "google.golang.org/grpc"
  6. "log"
  7. //多个服务引入多个包
  8. proto "github.com/baxiang/go-note/grpc_gateway_service/proto"
  9. "net/http"
  10. )
  11. var userPoint = "localhost:6666"
  12. func main() {
  13. ctx, cancel := context.WithCancel(context.Background())
  14. defer cancel()
  15. // Register gRPC server endpoint
  16. // Note: Make sure the gRPC server is running properly and accessible
  17. mux := runtime.NewServeMux()
  18. //多个服务注册多次即可
  19. err := proto.RegisterUserInfoServiceHandlerFromEndpoint(ctx, mux, userPoint, []grpc.DialOption{grpc.WithInsecure()})
  20. if err != nil {
  21. log.Fatal(err)
  22. }
  23. // Start HTTP server (and proxy calls to gRPC server endpoint)
  24. log.Fatal(http.ListenAndServe(":8081", mux))
  25. }

执行网关

  1. go run cmd/gateway/gateway.go

测试

  1. curl -H "Content-Type:application/json" -X POST --data '{"name":"test"}' http://127.0.0.1:8081/v1/userInfo

参考

https://blog.csdn.net/NikoKVCS/article/details/94568057
https://blog.csdn.net/zoeou/article/details/107593875