Skip to content

Protocol Buffers 入门:搭建 gRPC 开发环境与 Buf 依赖管理

Protocol Buffers 入门:搭建 gRPC 开发环境与 Buf 依赖管理示意图

前言

在微服务架构日益普及的今天,Protocol Buffers(简称 Protobuf)作为高效的结构化数据序列化协议,已成为 gRPC 服务定义的事实标准。本文将带你一步步搭建完整的 Protobuf 开发环境,从 IDE 插件配置到依赖管理,再到代码生成,让你快速上手 Protobuf 项目开发。

IDE 编辑器支持 Protocol Buffers

1. 安装插件

在 IntelliJ IDEA 中,首先需要安装 Protobuf 支持插件:

File → Settings → Plugins → 搜索 "Protocol Buffers" 并安装

安装完成后,重启 IDE 即可生效。

2. 配置导入路径

为了让 IDE 正确识别 Protobuf 文件中的 import 语句,需要配置导入路径:

File → Settings → Languages & Frameworks → Protocol Buffers

  • 勾选 "Configure automatically",让 IDE 自动识别
  • 或者在 "Import Paths" 中手动添加项目中的 Protobuf 定义目录

小贴士

正确配置导入路径后,IDE 将能够智能识别 import "google/protobuf/any.proto" 这类导入语句,并提供代码补全和跳转功能。

管理 Protocol Buffers

在 Protobuf 生态中,Buf 已逐渐成为行业标准工具。它不仅提供了高效的依赖管理能力,还集成了代码质量检查(Lint)、版本兼容性检查(Breaking Change Detection)等功能,大幅提升了 Protobuf 的开发体验。

Buf CLI 安装

Buf CLI 是 Buf 提供的命令行工具,可以通过多种方式安装:

macOS(Homebrew):

bash
brew install bufbuild/buf/buf

其他平台:

可参考官方安装文档,使用安装脚本或下载对应操作系统的二进制文件。

使用 Buf 管理依赖

1. 项目根目录初始化

在项目根目录下执行以下命令,初始化 Buf 配置:

bash
buf config init

执行后,将生成一个名为 buf.yaml 的配置文件:

buf.yaml
yaml
# For details on buf.yaml configuration, visit https://buf.build/docs/configuration/v2/buf-yaml
version: v2
lint:
  use:
    - STANDARD
breaking:
  use:
    - FILE
  • lint:配置代码规范检查规则,STANDARD 表示使用 Buf 推荐的标准规则集
  • breaking:配置兼容性检查规则,FILE 表示按文件级别检查是否存在破坏性变更

2. 添加 Protocol Buffers 依赖

以添加 Google 官方维护的 Protobuf 定义库为例,在 buf.yaml 中增加 deps 字段:

buf.yaml
yaml
# For details on buf.yaml configuration, visit https://buf.build/docs/configuration/v2/buf-yaml
version: v2
deps: 
  - buf.build/googleapis/googleapis
lint:
  use:
    - STANDARD
breaking:
  use:
    - FILE

注意

buf.build/googleapis/googleapis 是 Google 官方维护的 Protobuf 公共定义库,包含了 google/type/decimal.protogoogle/protobuf/timestamp.proto 等常用类型定义。

添加依赖后,执行以下命令下载并锁定依赖版本:

bash
buf dep update

该命令将生成一个名为 buf.lock 的依赖版本锁定文件:

buf.lock
txt
# Generated by buf. DO NOT EDIT.
version: v2
deps:
  - name: buf.build/googleapis/googleapis
    commit: 72c8614f3bd0466ea67931ef2c43d608
    digest: b5:13efeea24e633fd45327390bdee941207a8727e96cf01affb84c1e4100fd8f48a42bbd508df11930cd2884629bafad685df1ac3111bc78cdaefcd38c9371c6b1

说明

  • 首次执行 buf dep update 会生成 buf.lock 文件,后续添加新依赖时将自动更新该文件
  • buf.lock 记录了依赖的具体版本(commit hash)和校验和(digest),请不要手动修改,以确保团队构建的一致性
  • 这种依赖管理方式与 Go Modules、npm 等工具的设计理念类似,上手非常直观

3. 添加 Buf 依赖目录到 IDE 导入路径

为了让 IDE 能够识别已下载的第三方依赖(如 google/type/decimal.proto),我们需要将依赖的实际存储路径添加到 IDE 的 Protocol Buffers 导入路径中。

首先,执行以下命令查看依赖的存储信息:

bash
buf dep prune --debug

在输出日志中,可以找到如下 JSON 信息:

json
{"moduleFullName":"buf.build/googleapis/googleapis","commitID":"72c8614f3bd0466ea67931ef2c43d608","dirPath":"b5/buf.build/googleapis/googleapis/72c8614f3bd0466ea67931ef2c43d608"}

解析

  • moduleFullName:模块的完整名称
  • commitID:当前使用的版本标识
  • dirPath:模块在缓存中的相对路径

在 macOS 系统中,Buf 的全局缓存目录为 ~/.cache/buf/v3/modules,因此该模块的完整路径为:

~/.cache/buf/v3/modules/b5/buf.build/googleapis/googleapis/72c8614f3bd0466ea67931ef2c43d608

关键配置

我们需要将上述路径下的 files 子目录 添加到 IDE 的导入路径中,即:

~/.cache/buf/v3/modules/b5/buf.build/googleapis/googleapis/72c8614f3bd0466ea67931ef2c43d608/files

因为该目录下恰好包含 google 目录,这样在其他 Proto 文件中就可以通过 import "google/type/decimal.proto" 正确引用定义了。

4. 创建 Protocol Buffers 服务定义文件

现在,让我们创建一个实际的 Protobuf 服务定义文件,展示如何导入和使用第三方依赖:

proto/product/product.proto
protobuf
// proto/product/product.proto
syntax = "proto3";

package product;
option go_package = "github.com/kittycoffee/kittycoffee-protos/product";

import "google/protobuf/any.proto";
import "google/type/decimal.proto";
import "proto/user/user.proto";

service ProductService {
  rpc GetProduct(GetProductRequest) returns (ProductResponse);
  rpc CreateProduct(CreateProductRequest) returns (ProductResponse);
}

message GetProductRequest {
  string id = 1;
}

message CreateProductRequest {
  string name = 1;
  string description = 2;
  google.type.Decimal price = 3;
  string image_url = 4;
  string created_user_id = 5;
}

message ProductResponse {
  string id = 1;
  string name = 2;
  string description = 3;
  string price = 4;
  string image_url = 5;
  string created_user_id = 6;
  user.UserMinimalResponse created_user = 7;
  string created_at = 8;
  string updated_at = 9;
}

注意

IDE 之所以能够正确识别 import "google/type/decimal.proto",正是因为我们前面正确配置了导入路径——将 Buf 缓存的 files 目录加入了 IDE 的 Protocol Buffers 导入路径中。

5. 配置 buf.gen.yaml 文件

代码生成是 Protobuf 开发流程中的关键环节。创建 buf.gen.yaml 文件来配置代码生成规则:

buf.gen.yaml
yaml
# https://buf.build/docs/configuration/v2/buf-gen-yaml/
version: v2
managed:
  enabled: true
  disable:
    # Don't modify any files in buf.build/googleapis/googleapis
    - module: buf.build/googleapis/googleapis
  override:
    - file_option: go_package_prefix
      value: github.com/kittycoffee/kittycoffee-protos/gen
plugins:
  - protoc_builtin: go
    protoc_path: /usr/local/bin/protoc
    out: gen
    opt:
      - paths=source_relative
  - protoc_builtin: go-grpc
    protoc_path: /usr/local/bin/protoc
    out: gen
    opt:
      - paths=source_relative
inputs:
  - directory: proto
配置项详解

managed.disable

配置需要关闭自动管理的依赖模块。以 buf.build/googleapis/googleapis 为例:

  • 如果不关闭,Buf 会使用当前项目的 go_package_prefix 前缀重写该模块的 Go 导入路径,导致生成的代码引用本地路径,如 github.com/kittycoffee/kittycoffee-protos/gen/type/decimal
  • 如果关闭(即配置 disable),则保留第三方库原有的导入路径,正确引用官方维护的 Go 语言库,如 google.golang.org/genproto/googleapis/type/decimal

我们当然需要关闭——直接使用官方远程依赖库即可,无需在本地维护第三方库的 Go 实现。

plugins

声明需要使用的代码生成插件:

  • go:生成标准的 Go 消息类型代码(.pb.go
  • go-grpc:生成 gRPC 服务端和客户端代码(_grpc.pb.go

inputs

指定 Protobuf 源文件目录为 proto,Buf 将只处理该目录下的 .proto 文件。

6. 生成 Protocol Buffers 代码

一切配置就绪后,执行生成命令:

bash
buf generate

执行完成后,项目目录下将生成 gen 目录,包含所有生成的 Go 代码:

txt
gen
├── product
│   ├── product.pb.go
│   └── product_grpc.pb.go
└── user
    ├── user.pb.go
    └── user_grpc.pb.go
  • *.pb.go:包含所有消息类型的 Go 结构体定义及序列化/反序列化方法
  • *_grpc.pb.go:包含 gRPC 服务接口定义、客户端 stub 和服务端注册函数

总结

至此,我们已经完成了完整的 Protocol Buffers 开发环境搭建,包括:

  1. ✅ IDE 插件安装与导入路径配置
  2. ✅ Buf CLI 工具安装
  3. ✅ 使用 Buf 管理第三方 Protobuf 依赖
  4. ✅ 配置 IDE 识别 Buf 缓存中的依赖文件
  5. ✅ 编写自定义 Protobuf 服务定义
  6. ✅ 配置代码生成规则并成功生成 Go 代码

完成上述步骤后,github.com/kittycoffee/kittycoffee-protos 定义的服务就可以作为依赖被其他项目引用了。在服务端项目中,你可以实现生成的接口并启动 gRPC 服务;在客户端项目中,你可以使用生成的客户端 stub 轻松调用远程服务。

参考


本文档中的代码示例基于 macOS 环境,Linux/Windows 用户在路径和命令上可能需要做相应调整。

最后更新2026/08/12 06:39
如果你觉得这篇文章有帮助,或者想聊聊技术、工作,欢迎通过下面方式联系我:
contact fishfinal