go-kit Truss Protobuf 3 语法基本规范

本文是为后面使用 go-kit 代码生成工具 truss 做一个铺垫,不会太深入去研究 protobuf 用法,各位看官对于 protobuf 语法简单了解后,可以进行简单配置即可正常使用 truss,如有需要,后面再深入研究 protobuf 的高级用法

前提说明

  • 关于 protobuf 的由来以及优势与劣势不再赘述,在网上有很多介绍,感兴趣的看官可以自行搜索。
  • 本文对于 protobuf 介绍内容比较片面,仅限于基本极少,而且会针对 truss常用内容进行简单说明。

Protobuf

范例

废话不多说,先举个例子。

syntax = "proto3"; // 指定 protobuf 版本
package main; // 定义包名

// 引入第三方定义好的结构体,当然也可以自己定义
import "github.com/metaverse/truss/deftree/googlethirdparty/annotations.proto";
import "google/protobuf/any.proto";
import "google/protobuf/struct.proto";

//定义服务
service OauthUser {
  // 定义 RPC 接口
  rpc AddItem (AddItemRequest) returns (DefaultResponse) {
  // 使用 protobuf 的 extend option 的方法来扩展协议
    option (google.api.http) = {
    // 自定义选项-自定义 head 请求
      custom {
        kind: "HEAD"
        path: "/api/v1/item"
      }
      // 定义 http post 方法
      additional_bindings {
        post: "/api/v1/item"
        body : "*"
      }
    };
  }
  
  rpc GetItem (GetItemRequest) returns (DefaultResponse) {
  // 使用 protobuf 的 extend option 的方法来扩展协议
    option (google.api.http) = {
      // 定义 http get 方法
      additional_bindings {
        post: "/api/v1/item"
        body : "*"
      }
    };
  }
  rpc UpdateItem (UpdateItemRequest) returns (DefaultResponse) {
  // 使用 protobuf 的 extend option 的方法来扩展协议
    option (google.api.http) = {
    // 自定义选项-自定义 head 请求
      custom {
        kind: "HEAD"
        path: "/api/v1/item/{itemId}"
      }
      // 定义 http post 方法
      additional_bindings {
        post: "/api/v1/item/{itemId}"
        body : "*"
      }
    };
  }
  rpc DeleteItem (DeleteItemRequest) returns (DefaultResponse) {
  // 使用 protobuf 的 extend option 的方法来扩展协议
    option (google.api.http) = {
      // 定义 http delete 方法
      additional_bindings {
        delete: "/api/v1/item/{itemId}"
        body : "*"
      }
    };
  }
}

// 定义消息体
message AddItemRequest {
// 定义参数字段
// 基本格式 :数据类型 参数=数值标签; 
  string itemName = 1;
  string itemType = 2;
}

message GetItemRequest {
  string itemId = 1;
}

message UpdateItemRequest {
  string itemId = 1;
  string itemName = 2;
  string itemType = 3;
}

message DeleteItemRequest {
  string itemId = 1;
}

message DefaultResponse {
  string message = 1;
  int64 code = 2;
  google.protobuf.Struct data = 3;
}

protobuf 关键字说明

syntax

指定 protobuf 版本关键字,目前常用:

// syntax "proto2"
syntax "proto3"

package

指定生成代码时项目包名。

import

用于引入第三方(自定义)数据结构,常用的有:

import "github.com/metaverse/truss/deftree/googlethirdparty/annotations.proto";
import "google/protobuf/any.proto";
import "google/protobuf/struct.proto";

service

服务关键字,后面跟名称,名称最好使用驼峰结构例如:

service OauthUser {}

rpc

定义 RPC 接口关键字, 基本格式为 rpc 接口名(请求消息体) returns (返回消息体),需注意的是这里的 接口名请求消息体返回消息体需使用 驼峰格式命名。

例如上例中的:

rpc GetItem (GetItemRequest) returns (DefaultResponse)
rpc AddItem (AddItemRequest) returns (DefaultResponse)
rpc UpdateItem (UpdateItemRequest) returns (DefaultResponse)
rpc DeleteItem (DeleteItemRequest) returns (DefaultResponse)

option

option 关键字是对 http 接口进行扩展,通过指定的协议将 grpc 映射成为 http 协议。 如:

option 内定义需要的 HTTP 接口, 通过 custom 以及 additional_bindings 实现

// 基本格式 option (协议)
// 常用协议: google.api.http、google.api.rule
option (google.api.http) = {
     // 自定义选项-自定义 head 请求
      custom {
        kind: "HEAD"
        path: "/api/v1/item/{itemId}"
      }
      // 定义 http post 方法
      additional_bindings {
        post: "/api/v1/item/{itemId}"
        body : "*"
      }
}

message

字段规则
  • 单数形态:一个message内同名单数形态的字段不能超过一个
  • repeated:前置repeated关键词,声明该字段为数组类型
  • proto3不支持proto2中的requiredoptional关键字
消息定义

一个message类型定义描述了一个请求或响应的消息格式,可以包含多种类型字段。

例如定义一个搜索请求的消息格式AddItemRequest,每个请求包含名称、类型。每个字段声明以分号结尾。

如上面例子:

message AddItemRequest {
  string itemName = 1;
  string itemType = 2;
}

所有的字段需要前置声明数据类型,上面的示例指定了两个数值类型和一个字符串类型。除了基本的标量类型还有复合类型,如枚举、map、数组、甚至其它message类型等

分配Tags

消息的定义中,每个字段都有一个唯一的数值标签。这些标签用于标识该字段在消息中的二进制格式,使用中的类型不应该随意改动。其中,[1-15]内的标识在编码时占用一个字节,包含标识和字段类型。[16-2047]之间的标识符占用2个字节。建议为频繁出现的消息元素分配[1-15]间的标签。如果考虑到以后可能或扩展频繁元素,可以预留一些。

最小的标识符可以从1开始,最大到229 - 1,或536,870,911。不可以使用[19000-19999]之间的标识符, Protobuf协议实现中预留了这些标识符。在.proto文件中使用这些预留标识号,编译时会报错。

附上主要常用数据结构对比

.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

到此,对于 truss 中定义基本的 protobuf 文件的说明结束,希望各位看官有所收获,不对的地方欢迎留言指正。

参考

Protocol Buffers

Go-gRPC实践指南

Protobuf 扩展指南

拓展

自定义 proto 文件导入

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容