【gRPC】2 分钟学会 Protocol Buffer 语法

1,614 阅读2分钟

导读

学习 gRPC 一定绕不过 proto 文件(不清楚什么是 proto 文件的,请移步 【gRPC】5 分钟入门扫盲)。笔者也是 gRPC 初学,写这个短篇的目的非常纯粹,就是帮助团队新人用最短的时间掌握 proto 的基本用法,起码能看懂。所以本文的内容不会面面俱到,一切以实用为主。

PS:本文最适合熟悉 ts 的同学。文末会附上文本版代码,方便大家 copy。

正文

Talk is cheap, show me the code. 没有什么比直接上代码对比更高效清晰的了。

Proto vs TS

image.png

小结

大概的规则如下:

ProtoTS
messageinterface
serviceclass
repeatedArray<T>
stringstring
int32/int64/float etc.number

其他类型比较好理解,就不一一列举了。还有两点需要特别说明:

  • proto 中的字段名会在 TS 里被转化成小驼峰(camelCase)
  • repeated 修饰的字段名会被自动加 List 后缀。

看完以上内容,相信应付日常开发肯定没问题了。高级应用就先不展开了,以目前笔者的程度估计还 cover 不住。

结语

也没什么好总结的了,来段最近看的《诫子书》中的一段作为结尾,然后祝大家身体健康,万事如意吧。

夫君子之行,静以修身,俭以养德。非淡泊无以明志,非宁静无以致远。夫学须静也,才须学也,非学无以广才,非志无以成学。淫慢则不能励精,险躁则不能治性。年与时驰,意与日去,遂成枯落,多不接世,悲守穷庐,将复何及!——《诫子书》诸葛亮

文本代码

Proto

syntax = "proto3";

package helloworld;

message HelloRequest {
  string name = 1;
}

message RepeatHelloRequest {
  string name = 1;
  int32 count = 2;
}

message HelloReply {
  string message = 1;
}

message ListRequest {
  repeated int32 id = 1;
  string nil = 2;
}

message ListReply {
  repeated string id = 1;
  string Data = 2;
}

message TsMap {
  string feature = 1;
  string version = 2;
  string series = 3;
}

message MapI {
  TsMap test_map1 = 1;
  TsMap test_map2 = 2;
  TsMap validate_map = 3;
}

message MapRequest {
  MapI map = 1;
  repeated string do_safety_cars = 2;
}

message MapReply {
  MapI map = 1;
}

service Greeter {
  // unary call
  rpc SayHello(HelloRequest) returns (HelloReply);
  
  rpc ListTest(ListRequest) returns (ListReply);

  rpc MapTest(MapRequest) returns (MapReply);
}

service Stream {
  // server streaming call
  rpc SayRepeatHello(RepeatHelloRequest) returns (stream HelloReply);
}

TS

import * as grpcWeb from "grpc-web";

interface HelloRequest {
  name: string;
}

interface RepeatHelloRequest {
  name: string;
  count: number;
}

interface HelloReply {
  message: string;
}

interface ListRequest {
  idList: Array<number>;
  nil: string;
}

interface ListReply {
  idList: Array<string>;
  data: string;
}

interface TsMap {
  feature: string;
  version: string;
  series: string;
}

interface MapI {
  testMap1?: TsMap;
  testMap2?: TsMap;
  validateMap?: TsMap;
}

interface MapRequest {
  map?: MapI;
  doSafetyCarsList: Array<string>;
}

interface MapReply {
  map?: MapI;
}

export class GreeterPromiseClient {
  constructor(
    hostname: string,
    credentials?: null | { [index: string]: string },
    options?: null | { [index: string]: any }
  );

  sayHello(
    request: HelloRequest,
    metadata?: grpcWeb.Metadata
  ): Promise<HelloReply>;

  listTest(
    request: ListRequest,
    metadata?: grpcWeb.Metadata
  ): Promise<ListReply>;

  mapTest(request: MapRequest, metadata?: grpcWeb.Metadata): Promise<MapReply>;
}

export class StreamPromiseClient {
  constructor(
    hostname: string,
    credentials?: null | { [index: string]: string },
    options?: null | { [index: string]: any }
  );

  sayRepeatHello(
    request: RepeatHelloRequest,
    metadata?: grpcWeb.Metadata
  ): grpcWeb.ClientReadableStream<HelloReply>;
}