简介
buf 可以做 protoc 的替代品
- buf 效率比 protoc 更好
- buf 使用 yaml 文件,使用更清晰
NOTE:
- 目前不支持 Windows,下面为 linux 演示
- 官方文档:https://docs.buf.build/
- 官方的BSR地址是https://buf.build/,我们可以https://buf.build/login页面进行注册登录。使用体验类似github
buf.build
buf之于proto,类似go mod之于golang
Buf 需要三个不同的文件来生成存根和反向代理:buf.work.yaml、buf.gen.yaml、buf.yaml。
另外,还有一个buf.lock文件,但是它不需要进行人工配置,它是由buf mod update命令所生成。这跟前端的npm、yarn等的lock文件差不多,golang的go.sum也差不多。
它的配置文件不多,也不复杂,维护起来非常方便,支持远程proto插件,支持远程第三方proto。对构建系统Bazel支持很好,对CI/CD系统也支持得很好。它还有很多优秀的特性。
buf.work.yaml
它一般放在项目的根目录下面,它代表的是一个工作区,通常一个项目也就一个该配置文件。
该配置文件最重要的就是directories配置项,列出了要包含在工作区中的模块的目录。目录路径必须相对于buf.work.yaml,像…/external就是一个无效的配置。
version: v1
directories:
- api
- third_party
buf.gen.yaml
它一般放在buf.work.yaml的同级目录下面,它主要是定义一些protoc生成的规则和插件配置。
# 配置protoc生成规则
version: v1
managed:
enabled: false
plugins:
# generate go struct code
- name: go
out: gen/api/go
opt: paths=source_relative
# generate grpc service code
- name: go-grpc
out: gen/api/go
opt:
- paths=source_relative
# generate rest service code
- name: go-http
out: gen/api/go
opt:
- paths=source_relative
# generate kratos errors code
- name: go-errors
out: gen/api/go
opt:
- paths=source_relative
# generate message validator code
- name: validate
out: gen/api/go
opt:
- paths=source_relative
- lang=go
buf.yaml
它放置的路径,你可以视之为protoc的–proto-path参数指向的路径,也就是proto文件里面import的相对路径。
需要注意的是,buf.work.yaml的同级目录必须要放一个该配置文件。
该配置文件的内容通常来说都是下面这个配置,不需要做任何修改,需要修改的情况不多。
version: v1
deps:
breaking:
use:
- FILE
lint:
use:
- DEFAULT
快速开始
安装
官方提供 3 种安装方式
bin
tar package
go/bin
第一种:
brew install bufbuild/buf/buf
第二种:
go install github.com/bufbuild/buf/cmd/buf@v1.15.1
第三种:
BIN="/usr/local/bin" && \
VERSION="0.43.2" && \
BINARY_NAME="buf" && \
curl -sSL \
"https://github.com/bufbuild/buf/releases/download/v${VERSION}/${BINARY_NAME}-$(uname -s)-$(uname -m)" \
-o "${BIN}/${BINARY_NAME}" && \
chmod +x "${BIN}/${BINARY_NAME}"
检查是否安装成功
buf --version
1.15.1
示例
初始化项目
创建一个文件,然后在文件夹下执行:
$ mkdir buf_test && cd buf_test
$ go mod init grpc-gateway-demo
go: creating new go.mod: module grpc-gateway-demo
$ ls
go.mod
$ touch main.go
目前项目目录如下:
.
├── go.mod
├── main.go
└── proto
proto目录是所有proto文件的目录
创建buf.work.yaml
cd buf_test
touch buf.work.yaml
此文件指定工作空间中包含 Protocol Buffer 定义的所有文件夹/目录。内容:
version: v1
directories:
- proto
创建buf.gen.yaml
cd buf_test
touch buf.gen.yaml
这些文件指定编译器应该使用的所有插件和相关选项。
使用 Buf,你可以简单地在 YAML 文件中指定名称和选项。Buf 还允许构建代码使用远程插件(即,指定的插件将在构建过程中由 Buf 自动下载并由本地系统上的 Buf 维护)。内容为:
version: v1
plugins:
# generate go structs for protocol buffer defination
- remote: buf.build/library/plugins/go:v1.27.1-1
out: gen/go
opt:
- paths=source_relative
# generate gRPC stubs in golang
- remote: buf.build/library/plugins/go-grpc:v1.1.0-2
out: gen/go
opt:
- paths=source_relative
# generate reverse proxy from protocol definations
- remote: buf.build/grpc-ecosystem/plugins/grpc-gateway:v2.6.0-1
out: gen/go
opt:
- paths=source_relative
# generate openapi documentation for api
- remote: buf.build/grpc-ecosystem/plugins/openapiv2:v2.6.0-1
out: gen/openapiv2
创建buf.yaml
- 该文件应位于所有 proto 文件的根目录中。
- 目的:
- 为proto指定编译 proto 文件(例如 Google API)所需的依赖项。
- 为这个 pb 目录创建一个 buf 的模块。此后便可以使用 buf 的各种命令来管理这个 buf 模块了
cd buf_test/proto
buf mod init
此时会在根目录多出一个buf.yaml文件,内容为
version: v1
breaking:
use:
- FILE
lint:
use:
- DEFAULT
修改:
version: v1
deps:
- buf.build/googleapis/googleapis
lint:
use:
- DEFAULT
breaking:
use:
- FILE
生成
此时项目目录:
├── buf.gen.yaml
├── buf.work.yaml
├── go.mod
├── main.go
└── proto
├── buf.yaml
在项目根目录中你可以通过运行 buf build 命令来测试你的配置。
$ cd buf_test
$ buf build
Failure: directory "proto" listed in buf.work.yaml contains no .proto files
我们来添加一个proto文件:proto/hello/hello_world.proto :
// define syntax used in proto file
syntax = "proto3";
// options used by gRPC golang plugin(not related to gRPC gateway)
option go_package = "helloword/grpc-gateway-demo;grpc_gateway_demo";
// well know type by google, gRPC gateway uses HTTP annotation.
package hello_world;
// simple message
message HelloRequest { string name = 1; }
message HelloReply { string message = 1; }
// a gRPC service
service Greeter {
// SayHello is a rpc call and a option is defined for it
rpc SayHello(HelloRequest) returns (HelloReply) {}
}
重新执行:
$ buf build
$ buf generate
WARN Plugin "buf.build/library/go" is deprecated
WARN Plugin "buf.build/library/go-grpc" is deprecated
WARN Plugin "buf.build/grpc-ecosystem/grpc-gateway" is deprecated
WARN Plugin "buf.build/grpc-ecosystem/openapiv2" is deprecated
最后:
$ tree
.
├── buf.gen.yaml
├── buf.work.yaml
├── gen
│ ├── go
│ │ └── hello
│ │ ├── hello_world_grpc.pb.go
│ │ └── hello_world.pb.go
│ └── openapiv2
│ └── hello
│ └── hello_world.swagger.json
├── go.mod
├── main.go
└── proto
├── buf.yaml
└── hello
└── hello_world.proto
https://www.cuiwei.net/p/1679512807#/
https://blog.xuegaogg.com/posts/1951/
https://www.cnblogs.com/rongfengliang/p/16703778.html
http://www.guoxiaolong.cn/blog/?id=11287