Protocol Buffers (Proto) 语法详解

2024-08-30 22:53:36 浏览数 (2)

Protocol Buffers (Proto) 语法详解

Protocol Buffers(简称Proto)是一种由Google开发的接口描述语言,用于数据结构的序列化,是一种跨语言的服务描述语言。它主要用于数据序列化,也支持定义服务接口。Proto文件定义了数据结构和RPC服务,然后可以生成各种语言的代码,以实现数据的序列化和反序列化,以及服务的调用。

1. Proto文件基础

1.1 语法版本
代码语言:c复制
syntax = "proto3"; // 或者 "proto2"
  • syntax 指定使用的Proto语法版本,通常为proto3proto2
1.2 包名
代码语言:c复制
package example;
  • package 定义了生成代码的包名,通常与文件名相关。
1.3 导入其他Proto文件
代码语言:c复制
import "other.proto";
  • import 允许在当前Proto文件中使用其他Proto文件定义的消息类型。
1.4 go_package 选项

在 Protocol Buffers 的 .proto 文件中,go_package 选项用于指定生成的 Go 代码的包名和导入路径。这对于组织生成的代码和确保代码的一致性非常有用。

代码语言:c复制
option go_package = "path/to/package";
  • go_package 是一个选项,可以设置为生成 Go 代码的包路径。

2. 定义数据结构

2.1 定义消息(Message)
代码语言:c复制
message Person {
  string name = 1;
  int32 id = 2;
  string email = 3;
}
  • message 关键字用于定义消息类型。
  • 每个字段有一个唯一标签(从1开始的整数),用于序列化时标识字段。
  • 字段类型可以是基本数据类型、枚举、消息或其他复杂类型。
2.2 定义字段类型

Proto支持多种字段类型,包括:

  • doublefloat:双精度和单精度浮点数。
  • int32int64sint32sint64fixed32fixed64sfixed32sfixed64:整数类型。
  • bool:布尔类型。
  • string:字符串类型。
  • bytes:字节数组。
  • enum:枚举类型。
  • message:其他消息类型。
2.3 定义枚举(Enum)
代码语言:c复制
enum Gender {
  MALE = 0;
  FEMALE = 1;
  OTHER = 2;
}
  • enum 关键字用于定义枚举类型。
  • 枚举值从0开始,且每个值必须唯一。
2.4 定义字段规则
代码语言:c复制
message Person {
  string name = 1;
  optional int32 id = 2; // 可选字段
  repeated string emails = 3; // 可重复字段
}
  • optional:字段可以不赋值。
  • repeated:字段可以重复出现,形成数组。
2.5 定义映射(Map)
代码语言:c复制
map<string, int32> attributes = 1;
  • map 关键字用于定义映射类型。
2.6 定义一元类型(Oneof)
代码语言:c复制
message Person {
  oneof contact {
    string email = 1;
    string phone = 2;
  }
}
  • oneof 关键字用于定义一个字段组,其中只有一个字段会被赋值。

3. 定义服务和RPC

3.1 定义服务(Service)
代码语言:c复制
service PersonService {
  rpc GetPerson(PersonRequest) returns (Person) {
    option (google.api.http) = {
      get: "/v1/people/{id}"
    };
  }
}
  • service 关键字用于定义服务。
  • rpc 关键字定义远程过程调用(RPC)。
  • returns 指定RPC调用的返回类型。
3.2 定义HTTP映射(HTTP Mapping)
代码语言:c复制
option (google.api.http) = {
  post: "/v1/people"
  body: "*"
};
  • option (google.api.http) 用于定义HTTP映射,支持RESTful API风格,这一部分也可以不写。

4. Proto3特性

  • 默认值:在Proto3中,所有字段默认为optional,无需显式声明。
  • required字段:Proto3不支持required字段。
  • 无默认值:字段不能有默认值。

5. 实践示例

代码语言:c复制
syntax = "proto3";

package example;
option go_package = "trpc-mysql-demo/service/user";

import "google/api/annotations.proto";

message Person {
  string name = 1;
  int32 id = 2;
  string email = 3;
  Gender gender = 4;
  repeated string phone_numbers = 5;
  map<string, int32> attributes = 6;
}

enum Gender {
  MALE = 0;
  FEMALE = 1;
  OTHER = 2;
}

service PersonService {
  rpc GetPerson(PersonRequest) returns (Person) {
    option (google.api.http) = {
      get: "/v1/people/{id}"
    };
  }
  rpc CreatePerson(Person) returns (Person) {
    option (google.api.http) = {
      post: "/v1/people"
      body: "*"
    };
  }
}

message PersonRequest {
  int32 id = 1;
}

message PersonResponse {
  Person person = 1;
}
  • Person:定义一个包含姓名、ID、电子邮件、性别和电话号码的Person消息。
  • PersonService:定义一个服务,包含获取个人信息和创建个人信息的RPC。
  • PersonRequestPersonResponse:定义RPC请求和响应的消息类型。
  • HTTP映射:为GetPersonCreatePerson方法定义了HTTP映射,支持RESTful API风格。

0 人点赞