Golang GRPC Practice serial Three protobuf grammar

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

PROTOBUF syntax

GRPC recommends using Proto3, this section only describes the common syntax, more advanced use posture please refer to the Official document

Message definition

A message type definition describes a request or the corresponding message format, which can contain several types of fields. For example, define a message format for a search request that contains query strings, page numbers, and the number of pages per page.

syntax = "proto3";message SearchRequest {    string query = 1;           // 查询字符串    int32  page_number = 2;     // 页码    int32  result_per_page = 3; // 每页条数}

The first line declares that the Protobuf version used is Proto3

SearchRequest defines three fields, each with a semicolon ending with a double slash to // add a comment.

field type declaration

All fields require a predecessor declaration data type, the above example specifies two numeric types and a string type. There are compound types in addition to the basic scalar types, such as enumerations, other message types, and so on.

Identifiers tags

As you can see, in the definition of a message, each field has a unique numeric type identifier . These identifiers are used to identify the binary format of a field in a message, and the type in use should not be arbitrarily altered. Note that the identity within [1-15] occupies only one byte at the time of encoding, including identifiers and field types. The identifier between [16-2047] occupies 2 bytes. It is recommended that you use identifiers between [1-15] for frequently occurring message elements. If you consider possible or extended frequent elements later, you can reserve some identifiers.

The minimum identifier can start at 1, maximum to 229-1, or 536,870,911. identifiers between [19000-19999] cannot be used, and these identifiers are reserved in the PROTOBUF protocol implementation. These reserved identifiers are used in the. proto file and are compiled with an error.

Field rules

    • Repeated: The identity field can be repeated any time, like an array

    • Proto3 does not support required and optional in Proto2

Add more message types

A. proto file can define multiple message types, which are typically used to define multiple related messages at the same time, such as defining both a search request and a response message in the same. Proto file:

syntax = "proto3";// SearchRequest 搜索请求message SearchRequest {    string query = 1;           // 查询字符串    int32  page_number = 2;     // 页码    int32  result_per_page = 3; // 每页条数}// SearchResponse 搜索响应message SearchResponse {    ...}

Add Comment

Add comments to the. proto file, support C-style double slash // line comments

Reserved fields and identifiers

You can use the reserved keyword to specify reserved fields and reserved identifiers:

message Foo {    reserved 2, 15, 9 to 11;    reserved "foo", "bar";}

Note that you cannot mix field names and identifiers in a reserved declaration.

. proto File Compilation results

When you run a file using the protocol buffer compiler, the .proto compiler generates code for the selected language, using the .proto message type defined in the file, the service interface contract, and so on. Different languages generate different code formats:

    • C + +: Each .proto file generates a file .h and a .cc file, each message type corresponds to a class

    • Java: Generates a .java file with one class for each message, and a special Builder class to create the message interface

    • Python: Posture is not the same, the .proto message type in each file generates a module with a static descriptor, and a meta-class Metaclass to create the required Python data access class at run time

    • Go: Generate a .pb.go file, each message type corresponds to a struct body

    • Ruby: A .rb Ruby module that generates a file that contains all the message types

    • Javanano: Java-like, but does not contain Builder classes

    • OBJECTIVE-C: Each .proto file generates one pbobjc.h and one pbobjc.m file

    • C #: Generate .cs file contains, one class for each message type

Please refer to the official API documentation for more information on how to use various languages.

Data type

A description of the official documentation is directly quoted here:

. Proto C + + Java Python Go Ruby C #
Double Double Double Float Float64 Float Double
Float Float Float Float Float32 Float Float
Int32 Int32 Int Int Int32 Fixnum or Bignum Int
Int64 Int64 Long ING/LONG[3] Int64 Bignum Long
UInt32 UInt32 INT[1] INT/LONG[3] UInt32 Fixnum or Bignum UInt
UInt64 UInt64 LONG[1] INT/LONG[3] UInt64 Bignum ULong
Sint32 Int32 Int Intj Int32 Fixnum or Bignum Int
Sint64 Int64 Long INT/LONG[3] Int64 Bignum Long
Fixed32 UInt32 INT[1] Int UInt32 Fixnum or Bignum UInt
Fixed64 UInt64 LONG[1] INT/LONG[3] UInt64 Bignum ULong
Sfixed32 Int32 Int Int Int32 Fixnum or Bignum Int
Sfixed64 Int64 Long INT/LONG[3] Int64 Bignum Long
bool bool Boolean Boolean bool Trueclass/falseclass bool
String String String STR/UNICODE[4] String String (UTF-8) String
bytes String ByteString Str []byte String (Ascii-8bit) ByteString

Refer to Protocol Buffer Encoding for encoding rules for these types at serialization.

[1] Java

[2] all

[3] 64

[4] Python

Default value

    • String type defaults to an empty string

    • BYTE type default is NULL byte

    • Boolean type Default False

    • Value type defaults to 0 values

    • The enums type defaults to the first defined enumeration value, which must be 0

Specific behavior for default values for different languages refer to generated code guide

Enum (enum) TODO

Use a different message

message SearchResponse {    repeated Result results = 1;}message Result {    string url = 1;    string title = 2;    repeated string snippets = 3;}

The message supports nested use as a field type in another message

Importing definition (Import)

You can import a type that is declared in a different profile by using an import statement

import "others.proto";

Protocol the buffer compiler looks for the -I / --proto_path imported file in the directory specified by the parameter, and if it is not specified, it is found by default in the current directory.

Message nesting

message SearchResponse {    message Result {        string url = 1;        string title = 2;        repeated string snippets = 3;    }    repeated Result results = 1;}

Internally declared message type names can be used only internally, and external references require a pre-parent message name, such as Parent.Type :

message SomeOtherMessage {    SearchResponse.Result result = 1;}

Multilayer Nesting Support:

message Outer {                // Level 0    message MiddleAA {         // Level 1        message Inner {        // Level 2            int64 ival = 1;            bool  booly = 2;        }    }    message MiddleBB {         // Level 1        message Inner {        // Level 2            int32 ival = 1;            bool  booly = 2;        }    }}

Message Update TODO

Map type

Proto3 supports map type declarations:

map<key_type, value_type> map_field = N;message Project {...}map<string, Project> projects = 1;
    • The key, value type can be a built-in scalar type, or it can be a custom message type

    • field does not support repeated attributes

    • Do not rely on the map type's field order

Package (Packages)

.protouse the package declaration package name in the file to avoid naming conflicts.

syntax = "proto3";package foo.bar;message Open {...}

In other message format definitions, the type can be used in the same way as the package name + message name , such as:

message Foo {    ...    foo.bar.Open open = 1;    ...}

In different languages, the package name definition has different effects on the code that is generated after compilation:

    • C + +: corresponds to a C + + namespace, for example in Open a namespace foo::bar

    • In Java: The package is used as the Java bundle name unless an option is specified option jave_package

    • Python: The package is ignored

    • Go: The package name is used by default unless an option is specified option go_package

    • In Javanano: with Java

    • In C #: The package is converted to a camel-like namespace, for example Foo.Bar , unless an option is specified option csharp_namespace

Defining Services (Service)

If you want to use the message type in an RPC (remote method call) system, you can .proto define an RPC service interface in the file, and the protocol buffer compiler will generate the service interface code based on the different languages you choose. For example, if you want to define an RPC service and have a method that receives SearchRequest and returns one SearchResponse , you can .proto define it in a file like this:

service SearchService {    rpc Search (SearchRequest) returns (SearchResponse) {}}

The generated interface code acts as a contract between the client and the server, and the server must implement all of the interface methods defined, and the client directly invokes a method of the same name to initiate a request to the server. Compared to the egg, it is necessary to specify a request message even if the parameter is not required on the business, an empty message is generally defined.

Option (Options)

You can annotate a range of options when you define a. proto file. The options do not change the meaning of the entire file statement, but can affect how it is handled in a particular environment. Full options are available for viewing google/protobuf/descriptor.proto .

Some options are file-level, meaning that it can be used for the top-level scope and is not contained within any message, enum, or service definition. Some options are message-level and can be used inside the message definition. Of course, some options can be used in fields, enum types, enum values, service types, and service methods. But so far, there is no valid option to work with these types.

Here are some of the most common options:

    • java_package(File Option): Specifies the package in which the Java class is generated, and if there is no explicit declaration java_package in the. proto file, the default package name is used. No need to generate Java code when not working

    • java_outer_classname(File Option): Specifies the name of the generated Java class, and if Java_outer_classname is not explicitly declared in the. proto file, the generated class name will be generated according to the name of the. proto file, in the camel-named manner. such as (Foo_bar.proto generated Java class named Foobar.java), do not need to generate Java code does not play any role

    • objc_class_prefix(File Option): Specifies the Objective-c class prefix, preceded by all classes and enumerated type names. Without a default value, you should use 3-5 uppercase letters. Note that all 2-letter prefixes are reserved by Apple.

Basic specifications

A description file as a .proto file suffix, except for statements that are not defined by a struct, ending with a semicolon

    • Structure definitions include: message, service, enum

    • RPC method definition end of semicolon optional

The name of the message is named by the hump, and the field name is separated by lowercase letters and dashes.

message SongServerRequest {    required string song_name = 1;}

Enums type name using Hump naming method, field naming by uppercase and underline

enum Foo {    FIRST_VALUE = 1;    SECOND_VALUE = 2;}

Service and RPC method names are used in a camel-named style

Detailed go language compilation results TODO

The message corresponds to the struct in Golang, and after compiling the Go code, the field name is converted to Camel

Compile

.protogenerate Java, Python, C + +, Go, Ruby, Javanano, Objective-c, or C # code from a well-defined file and need to install the compiler protoc . Refer to the GitHub Project google/protobuf installation compiler. The go language needs to install a special plugin at the same time: Golang/protobuf.

To run the command:

protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --javanano_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto

Here is only a reference, the specific language of the compilation of examples, please refer to the detailed documentation, where the use of the go language posture in other chapters detailed description:

    • C + + generated code reference

    • Java Generated Code reference

    • Python Generated Code reference

    • Go Generated Code reference

    • Objective-c Generated Code reference

    • C # generated code reference

Spit Groove: According to the official document step operation does not necessarily succeed Oh!

More

    • Any message type

    • oneof field

    • customizing options

These usages are rarely used in practice and are not described here in detail, especially in the advanced usage of Custom option designs, which are required to refer to the official documentation.

Reference

Sample code for this series

    • Go-grpc-example

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.