使用 Buf 管理项目的 Protobuf
简介⌗
Buf 是一款开源的 Protobuf 的生态管理工具,不只是管理 Protobuf 文件和依赖,还有 protobuf-compiler-plugin 配置选项。
让开发者能够不用在 Protobuf Compiler 方面耗费太多精力,同时也支持 Plugin Registry,能够更好的管理私有的 protobuf-compiler-plugin,Buf 在 Protobuf 生态方面的建设起到了非常重要的作用,说是颠覆都不为过!
安装⌗
macOS 上安装方式如下:
brew install bufbuild/buf/buf
其他平台可以参考官方文档。
使用⌗
要使用 Buf ,需要使用 buf.yaml
文件配置 Buf CLI 工作区,该文件定义了要视为逻辑单元或模块的 Protobuf 文件目录列表。使用以下命令创建该文件:
buf config init
运行命令后,工作区目录中会有一个 buf.yaml,其内容如下:
# For details on buf.yaml configuration, visit https://buf.build/docs/configuration/v2/buf-yaml
version: v2
lint:
use:
- STANDARD
breaking:
use:
- FILE
设置工作区⌗
生成的 buf.yaml
文件的行为类似于一个工作区,其中包含一个模块,其路径设置为当前目录。要明确定义工作区中的模块,请提供包含 .proto
文件的目录的路径。使用 modules 键将 proto 目录添加到 buf.yaml 文件中:
# For details on buf.yaml configuration, visit https://buf.build/docs/configuration/v2/buf-yaml
version: v2
lint:
use:
- STANDARD
modules:
- path: internal/proto
breaking:
use:
- FILE
我的项目 .proto
文件放在 internal/proto
目录下,所以这里设置 modules.path 为 internal/proto
。
设置项目依赖⌗
通过在 buf.yaml
文件中添加 deps
列表,并定义需要的依赖项即可:
# For details on buf.yaml configuration, visit https://buf.build/docs/configuration/v2/buf-yaml
version: v2
lint:
use:
- STANDARD
deps:
- buf.build/googleapis/googleapis
modules:
- path: internal/proto
breaking:
use:
- FILE
我这里因为用到了 Google Protobuf 相关的 RESTful 定义,所以设置了 buf.build/googleapis/googleapis
依赖。在没有 buf 之前,这需要我们自己手动去下载 googleapis 的仓库,然后在编译过程中指定依赖的路径。
生成代码⌗
Buf CLI 提供了用户友好的体验,用于在本地生成与 protoc 用法兼容的代码。在开始之前,我们需要创建 buf.gen.yaml
配置文件来配置本地代码生成。它控制 buf generate
命令如何在给定模块上执行协议插件。你可以使用它来配置每个 protobuf-compiler-plugin
写入其结果的路径以及为每个插件指定配置选项。
touch buf.gen.yaml
version: v2
managed:
enabled: true
disable:
- file_option: go_package
module: buf.build/googleapis/googleapis
override:
- file_option: go_package_prefix
value: github.com/betterde/focusly/internal/gen
plugins:
- remote: buf.build/protocolbuffers/go
out: internal/gen
opt: paths=source_relative
- remote: buf.build/grpc/go
out: internal/gen
opt: paths=source_relative
- remote: buf.build/grpc-ecosystem/gateway
out: internal/gen
opt: paths=source_relative
- remote: buf.build/connectrpc/go:v1.12.0
out: internal/gen
opt: paths=source_relative
- local: protoc-gen-es
out: spa/src/gen
opt: target=ts
- local: protoc-gen-connect-es
out: spa/src/gen
opt: target=ts
- local: protoc-gen-connect-query
out: spa/src/gen
opt: target=ts
- remote: buf.build/community/google-gnostic-openapi:v0.7.0
out: docs/api
opt: paths=source_relative
上述配置,用于生成如下文件:
- *.pb.go
- *.pb.gw.go
- *_grpc.pb.go
- connect/.connect.go
- 前端项目所需的 TS
- OpenAPI specification
如果项目中还有其他语言需要使用 gRPC,只需要找到对应的 protobuf-compiler-plugin
并安装,然后就可以用 buf generate
来生成对应的代码了。
代码检查⌗
可以使用如下命令对项目中的 .proto 文件继续代码检查:
buf lint
兼容性检查⌗
对于 Protobuf 来说,文件的变更兼容性非常重要,为了避免兼容性问题,可以使用如下命令进行兼容性检测:
buf breaking --against ".git#subdir=internal/proto"
可以通过 --against
设置对比参照,支持的设置相如下:
- .git#branch=master
- .git#tag=v1.0.0
- .git#subdir=internal/proto
除了本地的 .git
, 也可以用远端的 git 作为对比参照,例如 https://github.com/betterde/focusly.git
。另外可以使用 --error-format=json
参数设置输出格式为 JSON。
格式化⌗
可以使用如下命令对 .proto
文件进行代码格式化:
# 查看格式化后的变更内容
buf format -d
# 将格式化后的变更写入文件
buf format -w
总结⌗
Buf 的强大还不止于此,它完善了 Protobuf 和 gRPC 的生态,后面我还会写一些关于 Buf 在项目中的实战经验……
I hope this is helpful, Happy hacking…