简介

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

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…