Woo*_*193 1 github go protocol-buffers
我目前有两个 protobuf 存储库:api 和timestamp:
时间戳回购:
- README.md
- timestamp.proto
- timestamp.pb.go
- go.mod
- go.sum
Run Code Online (Sandbox Code Playgroud)
API 仓库:
- README.md
- protos/
- dto1.proto
- dto2.proto
Run Code Online (Sandbox Code Playgroud)
目前,timestamp包含对我想要使用的时间戳对象的引用,api但我不确定导入应该如何工作,或者我应该如何修改编译过程来处理这个问题。让这个过程变得复杂的是,该api存储库被编译为 Go 的一个单独的下游存储库,名为api-go.
例如,考虑dto1.proto:
syntax = "proto3";
package api.data;
import "<WHAT GOES HERE?>";
option go_package = "github.com/my-user/api/data"; // golang
message DTO1 {
string id = 1;
Timestamp timestamp = 2;
}
Run Code Online (Sandbox Code Playgroud)
我的编译命令是这样的:
find $GEN_PROTO_DIR -type f -name "*.proto" -exec protoc \
--go_out=$GEN_OUT_DIR --go_opt=module=github.com/my-user/api-go \
--go-grpc_out=$GEN_OUT_DIR --go-grpc_opt=module=github.com/my-user/api-go \
--grpc-gateway_out=$GEN_OUT_DIR --grpc-gateway_opt logtostderr=true \
--grpc-gateway_opt paths=source_relative --grpc-gateway_opt
generate_unbound_methods=true \{} \;
Run Code Online (Sandbox Code Playgroud)
timestamp假设我对要编译的每种编程语言都有一个定义api,我将如何将其导入到.proto文件中,以及我应该做什么来确保导入不会在我的下游存储库中中断?
protobuf 没有远程导入路径的本机概念。因此导入路径必须相对于某些指示的本地文件系统基本路径(通过-I/指定--proto_path)。
一般来说,最简单的方法是为您的组织创建一个包含 protobuf 定义的存储库 - 例如名为的存储库acme-contract
.\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 protos\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 acme\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 api\n \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 data\n \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dto1.proto\n \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 dto2.proto\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 timestamp\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 timestamp.proto\nRun Code Online (Sandbox Code Playgroud)\n你的 dto1.proto 看起来像:
\nsyntax = "proto3";\n\npackage acme.api.data;\n\nimport "acme/timestamp/timestamp.proto";\n\nmessage DTO1 {\n string id = 1;\n acme.timestamp.Timestamp timestamp = 2;\n}\nRun Code Online (Sandbox Code Playgroud)\n只要您生成相对protos/于此存储库目录的代码,就不应该有问题。
有多种替代方案,您可以继续将定义拆分到不同的存储库中,但您无法真正逃避导入与文件系统相关的事实。
\n从历史上看,这可以通过手动克隆各种存储库并安排目录以使路径是相对的,或者通过使用-I指向可能有意或无意包含原型文件的各种位置(例如在 $GOPATH 中)来处理。这些策略最终往往会变得相当混乱且难以维护。
buf现在让事情变得更容易了。如果你有你的timestamp回购协议:
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 buf.gen.yaml\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 buf.work.yaml\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 gen\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 acme\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 timestamp\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 timestamp.pb.go\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 go.mod\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 go.sum\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 protos\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 acme\n \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 timestamp\n \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 timestamp.proto\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 buf.lock\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 buf.yaml\nRun Code Online (Sandbox Code Playgroud)\ntimestamp.proto看起来像:
syntax = "proto3";\n\npackage acme.timestamp;\n\noption go_package = "github.com/my-user/timestamp/gen/acme/timestamp";\n\nmessage Timestamp {\n int64 unix = 1;\n}\nRun Code Online (Sandbox Code Playgroud)\nbuf.gen.yaml看起来像:
version: v1\nplugins:\n - name: go\n out: gen\n opt: paths=source_relative\n - name: go-grpc\n out: gen\n opt:\n - paths=source_relative\n - require_unimplemented_servers=false\n - name: grpc-gateway\n out: gen\n opt:\n - paths=source_relative\n - generate_unbound_methods=true\nRun Code Online (Sandbox Code Playgroud)\n...下面的所有内容gen/都是通过 生成的buf generate。
然后在你的api存储库中:
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 buf.gen.yaml\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 buf.work.yaml\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 gen\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 acme\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 api\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 data\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dto1.pb.go\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 dto2.pb.go\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 protos\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 acme\n \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 api\n \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 data\n \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dto1.proto\n \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 dto2.proto\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 buf.lock\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 buf.yaml\nRun Code Online (Sandbox Code Playgroud)\n看起来buf.yaml像:
version: v1\nname: buf.build/your-user/api\ndeps:\n - buf.build/your-user/timestamp\nbreaking:\n use:\n - FILE\nlint:\n use:\n - DEFAULT\nRun Code Online (Sandbox Code Playgroud)\ndto1.proto看起来像:
syntax = "proto3";\n\npackage acme.api.data;\n\nimport "acme/timestamp/timestamp.proto";\n\noption go_package = "github.com/your-user/api/gen/acme/api/data";\n\nmessage DTO1 {\n string id = 1;\n acme.timestamp.Timestamp timestamp = 2;\n}\nRun Code Online (Sandbox Code Playgroud)\n和仓库buf.gen.yaml中的一样timestamp。
通过生成的代码buf generate将取决于timestampGo 模块的存储库:
// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// protoc-gen-go v1.28.1\n// protoc (unknown)\n// source: acme/api/data/dto1.proto\n\npackage data\n\nimport (\n timestamp "github.com/your-user/timestamp/gen/acme/timestamp"\n protoreflect "google.golang.org/protobuf/reflect/protoreflect"\n protoimpl "google.golang.org/protobuf/runtime/protoimpl"\n reflect "reflect"\n sync "sync"\n)\n\n// <snip>\nRun Code Online (Sandbox Code Playgroud)\n请注意,如果对依赖项进行更改,您需要确保 buf 和 Go 模块保持相对同步。
\n如果您不想利用 Go 模块来导入生成的 pb 代码,您也可以寻找与 类似的设置Option 2,而是将所有代码生成到一个单独的存储库中(听起来类似于您现在正在做的事情) )。通过使用托管模式最容易实现这一点buf,这基本上使其不需要+忽略任何go_modules指令。
在api-go:
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 buf.gen.yaml\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 go.mod\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 go.sum\nRun Code Online (Sandbox Code Playgroud)\n含有buf.gen.yaml:
version: v1\nmanaged:\n enabled: true\n go_package_prefix:\n default: github.com/your-user/api-go/gen\nplugins:\n - name: go\n out: gen\n opt: paths=source_relative\n - name: go-grpc\n out: gen\n opt:\n - paths=source_relative\n - require_unimplemented_servers=false\n - name: grpc-gateway\n out: gen\n opt:\n - paths=source_relative\n - generate_unbound_methods=true\nRun Code Online (Sandbox Code Playgroud)\n然后,您需要为每个相应的存储库生成代码(布什到 BSR):
\n$ buf generate buf.build/your-user/api\n$ buf generate buf.build/your-user/timestamp\nRun Code Online (Sandbox Code Playgroud)\n之后您应该为两者生成一些代码:
\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 buf.gen.yaml\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 gen\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 acme\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 api\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 data\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dto1.pb.go\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 dto2.pb.go\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 timestamp\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 timestamp.pb.go\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 go.mod\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 go.sum\nRun Code Online (Sandbox Code Playgroud)\n导入将相对于当前模块:
\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// protoc-gen-go v1.28.1\n// protoc (unknown)\n// source: acme/api/data/dto1.proto\n\npackage data\n\nimport (\n timestamp "github.com/your-user/api-go/gen/acme/timestamp"\n protoreflect "google.golang.org/protobuf/reflect/protoreflect"\n protoimpl "google.golang.org/protobuf/runtime/protoimpl"\n reflect "reflect"\n sync "sync"\n)\n\n// <snip>\nRun Code Online (Sandbox Code Playgroud)\n总而言之,我推荐选项 1 - 将您的 protobuf 定义合并到单个存储库中(包括供应商第 3 方定义) - 除非有特别充分的理由不这样做。
\n| 归档时间: |
|
| 查看次数: |
4406 次 |
| 最近记录: |