0. 概述
如果你经常使用 GRPC 并且定义 protobuf 的话,那么你一定会遇到很多不爽的问题,比如 pb 格式化,代码生成等,本文将带你一除所有关于 protobuf 的各种烦恼。
其实,我这里想说的是一个 Uber 开源的 Protobuf 工具 prototool,它可以对 protobuf 进行各种我们期望的工作,例如格式化 protobuf,生成测试桩,作为客户端调试等。基于这个工具的功能比较多,我就挑选两个比较常用的功能进行介绍,分别是:
- 格式化 protobuf
- 客户端调试
这些都是在平时工作中会经常使用到的功能,所以我觉得比较值得拿出来介绍一下。
1. 安装 prototool
环境不同,安装的方式也不同,如果你使用的是 CentOS,那么可以按照我的步骤来,如果不是,那么你需要参考这里的指导:prototool 安装指导,如果是 windows 用户,那可能需要绕行了。
[root@liqiang.io]# curl -sSL \
https://github.com/uber/prototool/releases/download/v1.8.0/prototool-$(uname -s)-$(uname -m) \
-o /usr/local/bin/prototool && \
chmod +x /usr/local/bin/prototool
安装完毕之后,我习惯性得做个简写,然后顺便测试一下安装是否正常:
[root@liqiang.io]# alias pt=prototool
[root@liqiang.io]# pt version
Version: 1.8.0
Default protoc version: 3.8.0
Go version: go1.12.4
OS/Arch: linux/amd64
一切正常,可以进行下一步的尝试了。
2. 格式化 protobuf
经常写 protobuf,即使有 IDE 的辅助,但是由于修改得比较频繁,所以很容易就导致 proto 的格式乱了,看上去很不舒服,以前都需要自己用 tab 慢慢调,但是现在有了好工具了,那么就可以直接通过工具来格式化啦,下面就先马上上手试用一波:
[root@liqiang.io]# wget https://raw.githubusercontent.com/gogo/grpc-example/master/proto/example.proto
[root@liqiang.io]# pt format bar.proto
... ...
// Hello is a hello.
message Hello {
int64 hello = 1;
}
因为太简单了,以至于都很难遇到一些错误,但是,就是这么个用法;但是,就是再简单我也要玩出点花来,例如,这里的缩进只有 2 个空格,我不爽,我要 4 个,怎么做?不好意思,实现不了,从某个版本开始,format 的所有配置都被移除了,所以,你必须使用 Uber 的默认格式。
3. prototool 配置文件
但是,如果你有其他自定义需求,那么就可以了解一下 prototool 的配置文件了。可以通过 config init
命令快速得生成一个配置文件:
[root@liqiang.io]# pt config init
[root@liqiang.io]# cat prototool.yaml
protoc:
version: 3.8.0
lint:
group: uber2
我加一条我的自定义需求,ENUM 的值必须都是大写的:
[root@liqiang.io]# cat prototool.yaml
protoc:
version: 3.8.0
lint:
group: uber2
rules:
add:
- ENUM_NAMES_CAPITALIZED
然后来测试一下:
[root@liqiang.io]# cat bar.proto
.. ...
// Size is for shirt selling.
enum Size {
SIZE_INVALID = 0;
SIZE_Small = 1;
SIZE_Medium = 2;
SIZE_LARGE = 3;
}
[root@liqiang.io]# pt lint bar.proto
bar.proto:41:3:Field name "SIZE_Small" must be UPPER_SNAKE_CASE.
bar.proto:42:3:Field name "SIZE_Medium" must be UPPER_SNAKE_CASE.
OK,是我想要的,配置还是有效的,但是,如果你尝试过,你会发现这并不是很爽,因为它有很多规矩都是内置的,比如 ENUM 的默认值必须是 XXX_INVALID,我擦,这能强迫的?
4. 客户端调用
最后一个示例就要来演示一下如何通过 prototool 进行命令行的调用了,第一步还是要跑一个服务器起来,出于方便,我就使用官方的示例了:
[root@liqiang.io]# git clone https://github.com/uber/prototool.git
[root@liqiang.io]# cd prototool
[root@liqiang.io]# make example
[root@liqiang.io]# go run example/cmd/excited/main.go # run in another terminal
然后我再开一个命令行窗口,使用 prototool 进行调用:
[root@liqiang.io]# prototool grpc example \
> --address 0.0.0.0:8080 \
> --method uber.foo.v1.ExcitedAPI/Exclamation \
> --data '{"value":"hello"}'
{"value":"hello!"}
图 1:使用 prototool 调用 GRPC 服务器 |
可以看到,我输入什么,就输出了什么,正如我所期待的。