Golang grpc and protobuf quick start

Time:2022-5-2

gPRC

Grpc introduction

Grpc is an RPC framework open source by Google

How grpc works

In grpc, the client application can directly call the method of the server application on another different machine like calling the method of the local object, which makes it easier for us to create distributed applications and services.

Grpc is based on the idea of defining a service and specifying its methods (including parameters and return types) that can be called remotely. Implement this interface on the server side and run a grpc server to handle the calls from the client side. The client has a stub, which provides the same method or function as the server. The stub is automatically generated by grpc

Golang grpc and protobuf quick start

Grpc uses protocol buffer to generate server & client stubs

Golang grpc and protobuf quick start

Why is grpc efficient
  • Grpc uses http / 2 as the transport protocol
gRPC & REST

Golang grpc and protobuf quick start

Written by protobuf

Vscode download vscode proto3 plug-in

Install the goochub plug-in com/golang/protobuf/protoc-gen- [email protected]

Compile and generate go File protocol — go_ out=./ go ./ proto/*

Examples
//Protobuf file
syntax = "proto3";
option go_package="./;hello";

package hello;

//The field number is used to identify your field in the message binary format and should not be changed after using your message type
//The field number in the range of 1 ~ 15 needs one byte to encode, and the field code in the range of 16 ~ 2047 occupies two bytes
message Person {
    string name = 1;
    int32 age = 2;
    string email = 3;
}
Specify field rules
  • Singular: messages that conform to syntax rules can have zero or one field (but no more than one). This is the default field rule of proto3 syntax
  • Repeated: this field can be repeated any number of times (including zero times) in the message that conforms to the syntax rules. The order of duplicate values will be preserved
    • In proto3, the field packed of repeated scalar numeric type uses encoding by default
Reserved fields
  • Specify the field number of the deleted field as reserved. If a user tries to use these field identifiers in the future, the protocol buffer compiler will report an error
message Foo {
	reserved 2, 15, 9 to 11;
	reserved "foo", "bar";
}
Protobuf data type

int32 int64 double string …

Protobuf enumeration
  • There must be a zero value so that we can use 0 as the numeric default
  • The zero value must be the first element to be compatible with the proto2 semantics where the first enumeration value is always the default
  • You can assign the same value to different enumeration constants to define aliases. You need to set allow_ Alias option is true
syntax = "proto3";

message SearchRequest {
    string query = 1;
    int32 page_number = 2;
    int32 result_per_page = 3;
    enum Corpus {
        //0 1 2 in enumeration Not a field number
        UNIVERSAL = 0;
        WEB = 1;
        IMAGES = 2;
        LOCAL = 3;
        NEWS = 4;
        PRODUCTS = 5;
        VIDEO = 6;
        /*
        	option allow_alias = true;
        	UNKONWN = 0;
        	STARTED = 1;
        	RUNNING = 1;
        */
    }
    Corpus corpus = 4;
}
Serialization & deserialization
package main

import (
	"encoding/json"
	"fmt"
	"grpc/user"

	"google.golang.org/protobuf/proto"
)

func main() {
	article := &user.Article{
		Aid:   1,
		Title: "protobuf for golang",
		Views: 100,
	}
	//Serialize to binary data
	bytes, _ := proto.Marshal(article.ProtoReflect().Interface())
	fmt.Printf("bytes: %v\n", bytes)

	//Deserialization
	otherArticle := &user.Article{}
	proto.Unmarshal(bytes, otherArticle.ProtoReflect().Interface());
	fmt.Printf("otherArticle: %v\n", otherArticle)
}
Protobuf and JSON conversion

Download protojson go get Google golang. org/protobuf/encoding/protojson

package main

import (
	"fmt"
	"grpc/blog"

	"google.golang.org/protobuf/encoding/protojson"
)

func main() {
	article := &blog.Article {
		Aid: 1,
		Title: "protobuf for golang",
		Views: 100,
	}

	// message to json
	jsonString := protojson.Format(article.ProtoReflect().Interface())
	fmt.Printf("jsonString: %v\n", jsonString)

	// json to message
	m := article.ProtoReflect().Interface()
	protojson.Unmarshal([]byte(jsonString), m)
	fmt.Printf("m: %v\n", m)
}
Protobuf definition service

Generate Pb with service Go File protocol — go_ out=plugins=grpc:. ./ proto/*. proto

syntax = "proto3"

service UserService {
	rpc login(User) returns (User) {};
	rpc register(User) returns (User) {};
}
Four types of service methods allowed by grpc
  • Single RPC, that is, the client sends a request to the server and obtains a response from the server, just like an ordinary function call
rpc SayHello(HelloRequest) returns (HelloResponse) {}
  • Server side streaming RPC, that is, the client sends a request to the server side to obtain a data stream to read a series of messages. The client reads from the returned data stream until there are no more messages
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse) {}
  • Client streaming RPC, that is, the client writes and sends a series of messages to the server with a data stream provided. Once the client completes the message writing, it waits for the server to read the message and return a response
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {}
  • Bidirectional streaming RPC, both sides can send a series of messages through a read-write data stream. The two data stream operations are independent of each other, so the client and server can read and write in any order they want
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse)
Grpc example

Import dependency:

go get -u google.golang.org/grpc

go install github.com/golang/protobuf/[email protected]

grpc-example