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 文件导入

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,719评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,337评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,887评论 0 324
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,488评论 1 266
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,313评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,284评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,672评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,346评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,644评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,700评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,457评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,316评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,706评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,261评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,648评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,859评论 2 335

推荐阅读更多精彩内容