创建 .proto 文件定义

由于本章的目标是编写一个可以在后续项目中使用的模板,我们将创建一个虚拟的 .proto 文件,以测试我们的构建系统是否正常工作。这个虚拟的 .proto 文件将包含一个消息和一个服务,因为我们希望测试 Protobuf 和 gRPC 的代码生成。

我们将定义一个名为 DummyMessage 的消息,内容如下:

message DummyMessage {}

接下来,我们将定义一个名为 DummyService 的服务,内容如下:

service DummyService {}

由于我们计划生成 Golang 代码,我们还需要定义一个名为 go_package 的选项,并将其值设置为 Go 模块的名称,后面跟着包含 .proto 文件的子文件夹的名称。这个选项非常重要,因为它让我们能够定义生成代码应该放在哪个包中。在我们的案例中,项目架构如下所示:

.
├── client
│     └── go.mod
├── go.work
├── proto
│     ├── dummy
│     │     └── v1
│     │          └── dummy.proto
│     └── go.mod
└── server
      └── go.mod

我们有一个单一代码库(Go 工作区),其中包含三个子模块:clientprotoserver。我们通过进入每个文件夹并运行以下命令来创建每个子模块:

$ go mod init github.com/github.com/PacktPublishing/gRPC-Go-for-Professionals/$FOLDER_NAME

其中,$FOLDER_NAME 应该替换为当前所在文件夹的名称(clientprotoserver)。

为了加快过程,我们可以创建一个命令,列出 root 目录中的文件夹并执行 go 命令。可以使用以下 UNIX(Linux/macOS)命令:

$ find . -maxdepth 1 -type d -not -path . -execdir sh -c "pushd {}; go mod init 'github.com/PacktPublishing/gRPC-Go-for-Professionals/{}'; popd" ";"

如果你使用的是 Windows,可以使用 PowerShell 来运行以下命令:

$ Get-ChildItem . -Name -Directory | ForEach-Object { PushLocation $_; go mod init "github.com/PacktPublishing/gRPC-Go-for-Professionals/$_" ; Pop-Location }

接下来,我们可以创建工作区文件。我们通过进入项目的根目录(chapter4),然后运行以下命令:

$ go work init client server proto

现在,我们会有如下内容的 go.work 文件:

go 1.20

use (
    ./client
    ./proto
    ./server
)

每个子模块都有如下内容的 go.mod 文件:

module $MODULE_NAME/$SUBMODULE_NAME

go 1.20

这里,我们将 $MODULE_NAME 替换为类似 github.com/PacktPublishing/gRPC-Go-for-Professionals 的 URL,将 $SUBMODULE_NAME 替换为包含文件的文件夹的名称。例如,在 client 中的 go.mod 文件将会是:

module github.com/PacktPublishing/gRPC-Go-for-Professionals/client

go 1.20

最后,我们可以通过向 dummy.proto 文件添加以下行来完成该文件:

option go_package = "github.com/PacktPublishing/gRPC-Go-for-Professionals/proto/dummy/v1";

现在,我们的 dummy.proto 文件如下所示:

syntax = "proto3";

option go_package = "github.com/PacktPublishing/gRPC-Go-for-Professionals/proto/dummy/v1";

message DummyMessage {}
service DummyService {}

这就是我们需要的所有内容,以测试从 dummy.proto 生成代码。