gRPC

高性能、开源的通用RPC框架,支持C#,C++,Dart,Go,Java,Kotlin,Node,Objective-C,PHP,Python,Ruby。

官方网站:https://www.grpc.io/

官方文档(Go):https://www.grpc.io/docs/languages/go/quickstart/

Protobuf生成gRPC、rest API、Swagger

安装

安装protoc

https://github.com/protocolbuffers/protobuf/releases

安装依赖

	#protoc生成Go
	go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
	#protoc生成grpc
	go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
	#protoc生成grpc gateway
	go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
	#protoc生成swagger文档,之后swagger editor查看
	go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger

定义proto

syntax = "proto3";
package test;

import "google/protobuf/timestamp.proto";
import "google/api/annotations.proto";

option go_package  =  "github.com/user" ;

message User {
  int32 id = 1;  // Unique ID number for this person.
  string name = 2;
  string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
  }

  repeated PhoneNumber phones = 4;

  google.protobuf.Timestamp last_updated = 5;
}

// The greeting service definition.
service Gint {
  // Sends a greeting
  rpc FindUser (FindUserRequest) returns (FindUserResponse) {
    option (google.api.http) = {
      post: "/v1/user/find"
      body: "*"
    };
  }
}

// The request message containing the user's name.
message FindUserRequest {
  int32 id = 1;
}

// The response message containing the greetings
message FindUserResponse {
  User user = 1;
}

生成gRPC、grpc-gateway、swagger

protoc  -I. --go_out=user --go-grpc_out=user -I$(GOPATH)/pkg/mod  \
	-I$(GOPATH)/pkg/mod/github.com/grpc-ecosystem/grpc-gateway@v1.16.0/third_party/googleapis \
	--grpc-gateway_out=logtostderr=true:user --swagger_out=logtostderr=true:user user.proto

实现service接口,并启动服务

// 启动grpc server
package main

import (
	"context"
	"flag"
	"fmt"
	"log"
	"net"
	"google.golang.org/grpc"
	pb "test/user/github.com/user"
)

// server is used to implement helloworld.GreeterServer.
type server struct {
	pb.UnimplementedGintServer
}

// SayHello implements helloworld.GreeterServer
func (s *server) FindUser(c context.Context, in *pb.FindUserRequest) (*pb.FindUserResponse, error) {
	return &pb.FindUserResponse{User: &pb.User{Name: "xixi"}}, nil
}

func main() {
	flag.Parse()
	lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 8000))
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}

	s := grpc.NewServer()
	pb.RegisterGintServer(s, &server{})
	log.Printf("server listening at %v", lis.Addr())
	if err := s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}
// 启动gateway server
package main

import (
	"context"
	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	"google.golang.org/grpc"
	"log"
	"net/http"
	pb "test/user/github.com/user"
)

func main() {
	ctx := context.Background()
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()
	mux := runtime.NewServeMux()
	opts := []grpc.DialOption{grpc.WithInsecure()}
	err := pb.RegisterGintHandlerFromEndpoint(ctx, mux, "0.0.0.0:8000", opts)
	if err != nil {
		panic(err)
	}

	log.Println("服务开启")
	http.ListenAndServe(":8080", mux)
}

查看swagger文档

生成的swagger.json如下:

{
  "swagger": "2.0",
  "info": {
    "title": "user.proto",
    "version": "version not set"
  },
  "consumes": [
    "application/json"
  ],
  "produces": [
    "application/json"
  ],
  "paths": {
    "/v1/user/find": {
      "post": {
        "summary": "Sends a greeting",
        "operationId": "Gint_FindUser",
        "responses": {
          "200": {
            "description": "A successful response.",
            "schema": {
              "$ref": "#/definitions/testFindUserResponse"
            }
          },
          "default": {
            "description": "An unexpected error response.",
            "schema": {
              "$ref": "#/definitions/runtimeError"
            }
          }
        },
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/testFindUserRequest"
            }
          }
        ],
        "tags": [
          "Gint"
        ]
      }
    }
  },
  "definitions": {
    "UserPhoneNumber": {
      "type": "object",
      "properties": {
        "number": {
          "type": "string"
        },
        "type": {
          "$ref": "#/definitions/UserPhoneType"
        }
      }
    },
    "UserPhoneType": {
      "type": "string",
      "enum": [
        "MOBILE",
        "HOME",
        "WORK"
      ],
      "default": "MOBILE"
    },
    "protobufAny": {
      "type": "object",
      "properties": {
        "type_url": {
          "type": "string"
        },
        "value": {
          "type": "string",
          "format": "byte"
        }
      }
    },
    "runtimeError": {
      "type": "object",
      "properties": {
        "error": {
          "type": "string"
        },
        "code": {
          "type": "integer",
          "format": "int32"
        },
        "message": {
          "type": "string"
        },
        "details": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/protobufAny"
          }
        }
      }
    },
    "testFindUserRequest": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer",
          "format": "int32"
        }
      },
      "description": "The request message containing the user's name."
    },
    "testFindUserResponse": {
      "type": "object",
      "properties": {
        "user": {
          "$ref": "#/definitions/testUser"
        }
      },
      "title": "The response message containing the greetings"
    },
    "testUser": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer",
          "format": "int32"
        },
        "name": {
          "type": "string"
        },
        "email": {
          "type": "string"
        },
        "phones": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/UserPhoneNumber"
          }
        },
        "last_updated": {
          "type": "string",
          "format": "date-time"
        }
      }
    }
  }
}

访问 swagger editor查看