我目前有兩個 protobuf 存盤庫:api 和timestamp:
時間戳回購:
- README.md
- timestamp.proto
- timestamp.pb.go
- go.mod
- go.sum
api回購:
- README.md
- protos/
- dto1.proto
- dto2.proto
目前,timestamp包含對我想要使用的時間戳物件的參考,api但我不確定匯入應該如何作業或我應該如何修改編譯程序來處理這個問題。使這個程序復雜化的事實是,apirepo 被編譯為一個單獨的下游 repo 用于 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;
}
我的編譯命令是這樣的:
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 \{} \;
假設我對timestamp要編譯的每種編程語言都有一個定義,我api將如何將其匯入.proto檔案中,我應該怎么做才能確保匯入不會在我的下游存盤庫中中斷?
uj5u.com熱心網友回復:
protobuf 沒有遠程匯入路徑的原生概念。因此匯入路徑必須相對于某些指示的本地檔案系統基本路徑(通過-I/指定--proto_path)。
選項1
通常,最簡單的方法是為您的組織只擁有一個帶有 protobuf 定義的存盤庫 - 例如一個名為acme-contract
.
└── protos
└── acme
├── api
│ └── data
│ ├── dto1.proto
│ └── dto2.proto
└── timestamp
└── timestamp.proto
您的 dto1.proto 將類似于:
syntax = "proto3";
package acme.api.data;
import "acme/timestamp/timestamp.proto";
message DTO1 {
string id = 1;
acme.timestamp.Timestamp timestamp = 2;
}
只要您生成protos/與此存盤庫的目錄相關的代碼,就不會出現問題。
選項 2
有多種選擇,您可以繼續將定義拆分到各個存盤庫中,但您無法真正逃避匯入與檔案系統相關的事實。
從歷史上看,這可以通過手動克隆各種存盤庫和安排目錄以使路徑是相對的,或者通過使用-I指向可能有意或偶然包含原始檔案的各種位置(例如,在 $GOPATH 中)來處理。這些策略最終往往會變得相當混亂且難以維護。
buf現在讓事情變得更容易了。如果你有你的timestamp回購:
.
├── buf.gen.yaml
├── buf.work.yaml
├── gen
│ └── acme
│ └── timestamp
│ └── timestamp.pb.go
├── go.mod
├── go.sum
└── protos
├── acme
│ └── timestamp
│ └── timestamp.proto
├── buf.lock
└── buf.yaml
timestamp.proto看起來像:
syntax = "proto3";
package acme.timestamp;
option go_package = "github.com/my-user/timestamp/gen/acme/timestamp";
message Timestamp {
int64 unix = 1;
}
buf.gen.yaml看起來像:
version: v1
plugins:
- name: go
out: gen
opt: paths=source_relative
- name: go-grpc
out: gen
opt:
- paths=source_relative
- require_unimplemented_servers=false
- name: grpc-gateway
out: gen
opt:
- paths=source_relative
- generate_unbound_methods=true
...并且下面的所有內容gen/都是通過buf generate.
然后在您的api存盤庫中:
.
├── buf.gen.yaml
├── buf.work.yaml
├── gen
│ └── acme
│ └── api
│ └── data
│ ├── dto1.pb.go
│ └── dto2.pb.go
└── protos
├── acme
│ └── api
│ └── data
│ ├── dto1.proto
│ └── dto2.proto
├── buf.lock
└── buf.yaml
看起來buf.yaml像:
version: v1
name: buf.build/your-user/api
deps:
- buf.build/your-user/timestamp
breaking:
use:
- FILE
lint:
use:
- DEFAULT
dto1.proto看起來像:
syntax = "proto3";
package acme.api.data;
import "acme/timestamp/timestamp.proto";
option go_package = "github.com/your-user/api/gen/acme/api/data";
message DTO1 {
string id = 1;
acme.timestamp.Timestamp timestamp = 2;
}
和回購buf.gen.yaml一樣。timestamp
通過生成的代碼將通過 Go 模塊buf generate依賴于存盤庫:timestamp
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc (unknown)
// source: acme/api/data/dto1.proto
package data
import (
timestamp "github.com/your-user/timestamp/gen/acme/timestamp"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
// <snip>
請注意,如果對依賴項進行了更改,您需要確保 buf 和 Go 模塊保持相對同步。
選項 3
如果您不想利用 Go 模塊來匯入生成的 pb 代碼,您也可以尋找與 類似的設定Option 2,而是將所有代碼生成到一個單獨的存盤庫中(類似于您現在正在做的事情,聽起來) . 這可以通過使用buf托管模式最容易地實作,這基本上使它不需要 忽略任何go_modules指令。
在api-go:
.
├── buf.gen.yaml
├── go.mod
└── go.sum
包含buf.gen.yaml:
version: v1
managed:
enabled: true
go_package_prefix:
default: github.com/your-user/api-go/gen
plugins:
- name: go
out: gen
opt: paths=source_relative
- name: go-grpc
out: gen
opt:
- paths=source_relative
- require_unimplemented_servers=false
- name: grpc-gateway
out: gen
opt:
- paths=source_relative
- generate_unbound_methods=true
然后,您需要為每個相應的 repo 生成代碼(連接到 BSR):
$ buf generate buf.build/your-user/api
$ buf generate buf.build/your-user/timestamp
之后,您應該為兩者生成一些代碼:
.
├── buf.gen.yaml
├── gen
│ └── acme
│ ├── api
│ │ └── data
│ │ ├── dto1.pb.go
│ │ └── dto2.pb.go
│ └── timestamp
│ └── timestamp.pb.go
├── go.mod
└── go.sum
并且匯入將相對于當前模塊:
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc (unknown)
// source: acme/api/data/dto1.proto
package data
import (
timestamp "github.com/your-user/api-go/gen/acme/timestamp"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
// <snip>
總而言之,我推薦選項 1 - 將您的 protobuf 定義合并到一個存盤庫中(包括供應商第 3 方定義) - 除非有特別強烈的理由不這樣做。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/524387.html
標籤:去github协议缓冲区
