Mutual transformation of Protobuffer, GRPC and restful grpc

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Document

    • GRPC Chinese Documents
    • Grpc-gateway,restful and Grpc Conversion libraries
    • PROTOBUF official website

Protobuf

Google Protocol Buffer (abbreviated as PROTOBUF) is a lightweight and efficient structured data storage format, platform-Independent, language-independent, extensible, and can be used in communication protocols and data storage areas.

Advantages

    • Platform-Independent, language-independent, extensible;
    • Provides a friendly dynamic library, easy to use;
    • The parsing speed is about 20-100 times faster than the corresponding XML.
    • The serialized data is very concise and compact, and the amount of data after serialization is approximately 1/3 to 1/10 compared to XML.

Installation

Refer to Golang using Protobuf

https://github.com/google/protobuf/releases // 下载并编译、安装go get github.com/golang/protobuf/proto   // golang的protobuf库文件// 插件go get github.com/golang/protobuf/protoc-gen-go  // 用于根据protobuf生成golang代码,语法 protoc --go_out=. *.proto

Grammar

Book/book.proto

syntax="proto3";package book;// import "xxx/xx.proto"// 出版社message Publisher{    required string name = 1}  // 书籍信息message Book {     required string name = 1;    message Author {        required string name = 1;        required string address = 1;    }    required Author author = 2;    enum BookType{        SCIENCE = 1 ;        LITERATURE = 2;    }    optional BookType type = 3;    optional Publisher publisher = 4}
    • Syntax= "Proto3": Specifies the version of the PROTOBUF
    • Package Book: Declare a registration, usually the same as the file directory name
    • Import "Xxx/xx.proto": Importing other packages so that you can use the data structures of other packages
    • Required, optional, repeated: Indicates whether the field must be populated, required indicates that it must be specified and only one can be specified, and when optional is optional, it can be specified or unspecified, but no more than one value is not specified, a null value is used. A field such as string is represented by a string, and repeated means that it can be repeated, similar to a list in a programming language
    • Message Author: Defines a message structure body in a message body
    • Enum: is an enumeration type struct body
    • Number: identifier of the field, non-repeatable
    • Data types: Int32, Int64, UInt32, UInt64, Sint32, Sint64, double, float, string, bool, bytes, enum, message, and more

Used in Golang

Protobuf using the Book.proto file above

and use the following command to generate the go file

protoc --go_out=. *.proto

Use in code

package mainimport (    b "book"    "github.com/golang/protobuf/proto")func main(){    ...    // 将实例转为proto编码    var b = &b.Book{Name:"xxx", Author:b.Author{Name:"yyy"}}    protoBook, err := proto.Marshal(b)    ...    // 讲proto编码转化为实例    var b2 b.Book    err = proto.Unmarshal(protoBook, &b2)        ...}

Grpc

Grpc is a Google-led RPC framework that uses the HTTP/2 protocol and PROTOBUF as a serialization tool. Its clients provide objective-c, Java interface, server side has Java, Golang, C + + and other interfaces. Using GRPC, you can easily invoke the methods of other processes, calling the data that needs to be transferred using proto encoding. This can effectively improve the coding efficiency and data transfer rate for large-scale projects.

Proto Service definition

An RPC service is a method that can be called remotely through parameters and return values, and we can simply interpret it as a function. Because GRPC is transmitted by encoding the data into protocal buffer. Therefore, we define the service method by Protocal buffers Interface Definitioin language (IDL), and also define the parameter and return value as the protocal buffer message type. The specific implementation is as follows, the file containing the following code is called Helloworld.proto:

syntax = "proto3";  package helloworld; // The greeter service definition.service Greeter {  // Sends a greeting  rpc SayHello (HelloRequest) returns (HelloReply) {}} // The request message containing the user's name.message HelloRequest {  string name = 1;} // The response message containing the greetingsmessage HelloReply {  string message = 1;}

Then, based on the service defined above, we can use protocal buffer compiler, the PROTOC, to generate the corresponding Golang code for the server side and the client. The generated code contains the methods that the client can make RPC and the interfaces that the server side needs to implement.

Assuming the current directory is $gopath/src/helloworld/helloworld, we will generate the GRPC corresponding Golang code with the following command:

protoc --go_out=plugins=grpc:. helloworld.proto

At this point, the Helloworld.pb.go file is generated under the directory

Server

Server.go

package main // server.go import (    "log"    "net"     "golang.org/x/net/context"    "google.golang.org/grpc"    pb "helloworld/helloworld") const (    port = ":50051") type server struct {}// 当接收到请求的时候回调用该方法// 参数由grpc自己根据请求进行构造 func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {    return &pb.HelloReply{Message: "Hello " + in.Name}, nil} func main() {    lis, err := net.Listen("tcp", port)    if err != nil {        log.Fatal("failed to listen: %v", err)    }    s := grpc.NewServer()    pb.RegisterGreeterServer(s, &server{})    s.Serve(lis)}

Where PB is the package of go files that we just generated based on Proto

Client

package main //client.go import (    "log"    "os"     "golang.org/x/net/context"    "google.golang.org/grpc"    pb "helloworld/helloworld") const (    address     = "localhost:50051"    defaultName = "world") func main() {    // 建立一个grpc连接    conn, err := grpc.Dial(address, grpc.WithInsecure())    if err != nil {        log.Fatal("did not connect: %v", err)    }    defer conn.Close()    // 新建一个客户端,方法为:NewXXXClinent(conn),XXX为你在proto定义的服务的名字    c := pb.NewGreeterClient(conn)     name := defaultName    if len(os.Args) >1 {        name = os.Args[1]    }    // 调用远程,并得到返回    r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name})    if err != nil {        log.Fatal("could not greet: %v", err)    }    log.Printf("Greeting: %s", r.Message)}

RESTful turn GRPC

The advantages of using GRPC are many, the binary data can speed up the transfer speed, HTTP2-based multiplexing can reduce the number of connections between services, and the function of the same call method is also effective to improve the development efficiency. However, the use of GRPC will also face a problem, our micro-service must be to provide a restful interface, if the internal call using GRPC, in some cases to provide a function of the two sets of API interface, which not only reduces the development efficiency, but also increases the complexity of debugging. So I think there is a conversion mechanism, so that restful and GPRC can transform each other.

Grpc-gateway was born

Installation

First you have to install proto and Grpc according to the previous steps in this article, and then install some libraries as follows

go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gatewaygo get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swaggergo get -u github.com/golang/protobuf/protoc-gen-go

Usage

Define the proto file for the service

 syntax = "proto3"; package example; import "google/api/annotations.proto"; message StringMessage {   string value = 1; }  service YourService {   rpc Echo(StringMessage) returns (StringMessage) {     option (google.api.http) = {       post: "/v1/example/echo"       body: "*"     };   } }

option indicates which path requests are processed and how the request body (parameters) is handled, see Https://cloud.google.com/serv ...

Generate Go File

protoc -I/usr/local/include -I. \  -I$GOPATH/src \  -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \  --go_out=plugins=grpc:. \  path/to/your_service.protoprotoc -I/usr/local/include -I. \  -I$GOPATH/src \  -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \  --grpc-gateway_out=logtostderr=true:. \  path/to/your_service.proto

The above generated two files, the first is the Pb.go file for Grpc server, and the second is the Pb.gw.go file, for Grpc-gateway, for GRPC and restful mutual transformation

Server

package mainimport (  "flag"  "net/http"  "github.com/golang/glog"  "golang.org/x/net/context"  "github.com/grpc-ecosystem/grpc-gateway/runtime"  "google.golang.org/grpc"      gw "path/to/your_service_package")var (  echoEndpoint = flag.String("echo_endpoint", "localhost:9090", "endpoint of YourService"))func run() error {  ctx := context.Background()  ctx, cancel := context.WithCancel(ctx)  defer cancel()  mux := runtime.NewServeMux()  opts := []grpc.DialOption{grpc.WithInsecure()}  err := gw.RegisterYourServiceHandlerFromEndpoint(ctx, mux, *echoEndpoint, opts)  if err != nil {    return err  }  return http.ListenAndServe(":8080", mux)}func main() {  flag.Parse()  defer glog.Flush()  if err := run(); err != nil {    glog.Fatal(err)  }}

Test

curl -X POST -k http://localhost:8080/v1/example/echo -d '{"name": " world"}{"message":"Hello  world"}

The

process is as follows: Curl uses post to send a request to the gateway, and the gateway acts as a proxy to convert the request through GRPC to Greeter_server,greeter_server and return the result via GRPC. After the gateway receives the results, it converts the JSON back to the front end.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.