Protobuf 生成的文件无法识别导入路径

问题描述

我有一个原型文件 product.proto,我想在 catalog.proto 中使用它。我可以在 product.proto 中成功导入 catalog.proto,但自动生成catalog.pb.go 无法重新识别其依赖项的路径,即 product.pb.go。它指出:

无法导入catalog/pb/entities(在任何一个目录中都找不到包“catalog/pb/entities” /usr/local/go/src/catalog/pb/entities(来自 $GOROOT)
/Users/trimulabs/go/src/catalog/pb/entities(来自 $GOPATH)

目录结构

?catalog
 ┣ ?main
 ┃ ┣ ?client.go
 ┃ ┗ ?server.go
 ┣ ?pb
 ┃ ┣ ?entities
 ┃ ┃ ┣ ?product.pb.go
 ┃ ┃ ┗ ?product.proto
 ┃ ┣ ?catalog.pb.go
 ┃ ┗ ?catalog.proto

catalog.proto

Syntax = "proto3";
package catalog;
import "catalog/pb/entities/product.proto";

service CatalogService {
    rpc PostProduct (PostProductRequest) returns (PostProductResponse) {}
    rpc GetProduct (GetProductRequest) returns (GetProductResponse) {}
    rpc GetProducts (GetProductsRequest) returns (GetProductsResponse) {}
}

product.proto

message Product {
    string id = 1;
    string name = 2;
    string description = 3;
    double price = 4;
}
message PostProductRequest {
    string name = 1;
    string description = 2;
    double price = 3;
}
message PostProductResponse {
    Product product = 1;
}

message GetProductRequest {
    string id = 1;
}

message GetProductResponse {
    Product product = 1;
}

message GetProductsRequest {
    uint64 skip = 1;
    uint64 take = 2;
    repeated string ids = 3;
    string query = 4;
}

message GetProductsResponse {
    repeated Product products = 1;
}

有人可以帮忙吗?

解决方法

您看到的错误是因为您生成的 protobuf 文件可能具有不正确的导入路径。

如果您检查您的 product.pb.go 文件,它可能有类似的内容:

import "catalog/pb/entities"

这意味着它正在尝试导入具有指定路径的 go 包。您可能熟悉,go 包必须使用绝对路径,因此需要类似于:

import "github.com/<myuser>/<myproject>/catalog/pb/entities"

protoc-gen-go 幸运的是支持几个标志来帮助您解决这个问题。

第 1 步。在您的 go_package 文件中设置 .proto 以指定 go 中的预期导入路径。

option go_package = "example.com/foo/bar";

第 2 步:使用 --go_opt=module=github.com/<myuser>/<project>protoc 标志从生成的代码中去除模块前缀。否则你会得到这样的输出(假设你使用当前目录作为你的 go_out 路径

catalog/
  main/
  pb/
  github.com/
    <myuser>/
      <project>/
        catalog/
          pb/
            entities/

我建议您查看 protoc-gen-go go 标志上的文档页面:

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...