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查看