导入”protoc-gen-openapiv2/options/annotations.proto”未找到或存在错误。

huangapple go评论76阅读模式
英文:

Import "protoc-gen-openapiv2/options/annotations.proto" was not found or had errors

问题

我有一个 proto 文件,我想在其中添加分页功能。技术栈是 GoLang 和 gRPC。

import "google/api/annotations.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
import "google/protobuf/timestamp.proto";

当我尝试通过 go installgo get 添加依赖时,我得到以下错误信息:

go install protoc-gen-openapiv2/options/annotations.proto@latest                                                       
go: protoc-gen-openapiv2/options/annotations.proto@latest: malformed module path "protoc-gen-openapiv2/options/annotations.proto": missing dot in first path element
go get protoc-gen-openapiv2/options/annotations.proto                                                                  
go: go.mod file not found in current directory or any parent directory.
        'go get' is no longer supported outside a module.

当我阅读文档时,似乎我是正确操作的。是否有其他人遇到过这个问题?

message BlogAllRequest {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["filter"]
        }
    };

    string id = 1;
    int32 page = 2;
    int32 per_page = 3 [json_name="per_page"];
    SortOrder order = 4 [json_name = "order"];
}
英文:

I have a proto file where I want to add pagination. The technology stack is GoLang with gRPC.

import "google/api/annotations.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
import "google/protobuf/timestamp.proto";

When try to add the dependency via go install or go get. I get

go install protoc-gen-openapiv2/options/annotations.proto@latest                                                       
go: protoc-gen-openapiv2/options/annotations.proto@latest: malformed module path "protoc-gen-openapiv2/options/annotations.proto": missing dot in first path element

go get protoc-gen-openapiv2/options/annotations.proto                                                                  
go: go.mod file not found in current directory or any parent directory.
        'go get' is no longer supported outside a module.

When I read the documentation it appears I am doing this correctly. Has anyone else had this issue?

message BlogAllRequest {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["filter"]
        }
    };

    string id = 1;
    int32 page = 2;
    int32 per_page = 3 [json_name="per_page"];
    SortOrder order = 4 [json_name = "order"];

}

答案1

得分: 0

注意 抱歉,我对 gRPC Gateway 不太熟悉,但我非常熟悉 Protocol Buffers(和 gRPC)。所以,我无法提供完整的解决方案,但我可以向你展示如何编译你的 proto 文件。

使用 Protocol Buffers,你需要在本地拥有源文件(例如 .proto 文件)。你不能使用 go getgo install 命令获取 Protocol Buffer 文件。

你需要的 grpc-gateway 的 proto 文件如下:

下一步,最简单的方法可能是 git clone grpc-gateway 仓库。上面提到的 proto 文件位于仓库的 ./protoc-gen-openapiv2 文件夹中。

我已经将它克隆到我的工作目录中(请参考下面的目录结构)。

第一步是使用 protoc 编译你的 proto 文件,并引用这些 proto 文件。这是我完成你的 proto 文件的示例:

foo.proto:

syntax = "proto3";

option go_package = "{MODULE}/protos";

import "protoc-gen-openapiv2/options/annotations.proto";

message BlogAllRequest {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["filter"]
        }
    };

    enum SortOrder{
        BAR = 0;
        BAZ = 1;
    }

    string id = 1;
    int32 page = 2;
    int32 per_page = 3 [json_name="per_page"];
    SortOrder order = 4 [json_name = "order"];
}

注意{MODULE} 替换为你的仓库名称。通常,你的仓库名称将与你的 Go 模块名称匹配。就像我所做的那样,你可能希望为 go_package 的值添加 /protos,以便为 protoc 生成的源文件提供自己的包名称。我还添加了一个任意的 SortOrder 类型。

现在,你可以使用 protoc 编译你的 proto 文件:

# 你的 go.mod 模块值,可能与你的 Git 仓库匹配
MODULE="..."

# 在这里执行以证明这一点
go mod init ${MODULE}

# Protoc 将在 protos 文件夹中输出 foo.pb.go
# 这将使其成为 ${MODULE}/protos 包
mkdir protos

protoc \
--proto_path=${PWD} \
--proto_path=${PWD}/grpc-gateway \
--go_out=./protos \
--go_opt=module=${MODULE} \
${PWD}/foo.proto

protoc 对路径非常敏感。我总是将其根目录设置为我的工作目录(${PWD}),在这种情况下,我已经将 gprc-gateway 克隆到了工作目录中。两个文件夹都包含 proto 文件,因此都必须在 proto_path 中指定。因为我在 proto_path 中使用了 ${PWD},所以我必须在 proto 文件名前加上 ${PWD}(即 ${PWD}/foo.proto)。这是 protoc 的规定。

重要的是,我希望你的 proto 文件编译为以 protos 结尾的包,因此我也需要在工作文件夹中反映这一点。

为了确保 protoc 知道我的工作目录(带有 go.mod)是我的 Go 模块根目录,你可以使用 --go_opt=module=${MODULE} 将文件正确放置。

我将你的部分 proto 文件命名为 foo.proto

grpc-gateway 仓库不仅包含了 protos./protoc-gen-openapiv2/options/*.proto),还包含了 protoc 生成的 Golang 源文件(./protoc-gen-openapiv2/options/*.pb.go)。这是仓库维护者做出的(我认为是很好的实践)选择,这意味着你不需要自己生成这些源文件。

实际上,你的 protoc 生成的 foo.pb.go 应该包含对这些源文件的正确引用,你只需要运行 go mod tidygo get 它们。这是我生成的 foo.pb.go 的开头部分:

foo.pb.go:

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.28.1
// 	protoc        v3.21.12
// source: foo.proto

package protos

import (
	_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

运行 tree 命令:

tree
.
├── foo.proto
├── go.mod
├── grpc-gateway
│   ├── protoc-gen-openapiv2
│   │   └── options
│   │       ├── annotations.pb.go
│   │       ├── annotations.proto
│   │       ├── annotations.swagger.json
│   │       ├── BUILD.bazel
│   │       ├── openapiv2.pb.go
│   │       ├── openapiv2.proto
│   │       └── openapiv2.swagger.json
├── protoc-21.12-linux-x86_64
│   ├── bin
│   │   └── protoc
│   ├── include
│   │   └── google
│   │       └── protobuf
│   │           ├── any.proto
│   │           ├── api.proto
│   │           ├── compiler
│   │           │   └── plugin.proto
│   │           ├── descriptor.proto
│   │           ├── duration.proto
│   │           ├── empty.proto
│   │           ├── field_mask.proto
│   │           ├── source_context.proto
│   │           ├── struct.proto
│   │           ├── timestamp.proto
│   │           ├── type.proto
│   │           └── wrappers.proto
│   └── readme.txt
└── protos
    └── protos
        └── foo.pb.go
英文:

NOTE Apologies I'm less familiar with gRPC Gateway but I'm very familiar with Protocol Buffers (and gRPC). So, I can't help with the full solution but I can show you how to compile your proto.

With Protocol Buffers you need source files locally (e.g. .proto files). You cannot go get nor go install Protocol Buffer files.

The grpc-gateway protos that you need are:

For the next step, it's probably easiest to git clone the grpc-gateway repo. The protos mentioned above are in the repo's ./protoc-gen-openapiv2 folder.

I've cloned it into my working directory (see tree below).

The first step is to then protoc compile your proto referencing these protos. Here's my completion of your proto file:

foo.proto:

syntax = "proto3";

option go_package = "{MODULE}/protos";

import "protoc-gen-openapiv2/options/annotations.proto";

message BlogAllRequest {
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
        json_schema: {
            required: ["filter"]
        }
    };

    enum SortOrder{
        BAR = 0;
        BAZ = 1;
    }

    string id = 1;
    int32 page = 2;
    int32 per_page = 3 [json_name="per_page"];
    SortOrder order = 4 [json_name = "order"];
}

NOTE Replace {MODULE} with your repo name. Generally your repo name will match your Go module name. As I've done, you may want to add e.g. /protos to your {MODULE} value for the value of go_package as this provides the protoc-generated sources with their own package name. I also add an arbitrary SortOrder type.

You can now protoc compile your proto:

# Your go.mod module value and probably matching your Git repo 
MODULE="..."

# Doing this here to prove the point
go mod init ${MODULE}

# Protoc will output foo.pb.go in protos folder
# This will make it the ${MODULE}/protos package
mkdir protos

protoc \
--proto_path=${PWD} \
--proto_path=${PWD}/grpc-gateway \
--go_out=./protos \
--go_opt=module=${MODULE} \
${PWD}/foo.proto

protoc is very particularly about paths. I always root it on my working directory (${PWD}) and, in this case, I've cloned gprc-gateway into the working directory. Both folders contain protos and so both must be proto_path'd. Because I used ${PWD} for the proto_path, I must prefix proto filenames with ${PWD} too (i.e. ${PWD}/foo.proto). It's protoc's way.

Importantly, I want your proto compiled into a package ending protos and so I need to reflect this in the working folder too

To ensure protoc knows that my working directory (with go.mod) is my Go module root, you can use --go_opt=module=${MODULE} to place the files correctly.

I've called your partial proto foo.proto.

The grpc-gateway repo not only includes the protos (./protoc-gen-openapiv2/options/*.proto) but it also includes the protoc-generated Golang sources (./protoc-gen-openapiv2/options/*.pb.go). This is a (helpful) choice (I think, good practice) made by the repo maintainers and it means that you don't need to generate these sources for yourself.

In fact, your protoc-generated foo.pb.go should include the correct references to these sources and you will just need to go mod tidy to go get them. Here's the beginning of the foo.pb.go that I generated:

foo.pb.go:

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.28.1
// 	protoc        v3.21.12
// source: foo.proto

package protos

import (
	_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

Running tree:

tree
.
├── foo.proto
├── go.mod
├── grpc-gateway
│   ├── protoc-gen-openapiv2
│   │   └── options
│   │       ├── annotations.pb.go
│   │       ├── annotations.proto
│   │       ├── annotations.swagger.json
│   │       ├── BUILD.bazel
│   │       ├── openapiv2.pb.go
│   │       ├── openapiv2.proto
│   │       └── openapiv2.swagger.json
├── protoc-21.12-linux-x86_64
│   ├── bin
│   │   └── protoc
│   ├── include
│   │   └── google
│   │       └── protobuf
│   │           ├── any.proto
│   │           ├── api.proto
│   │           ├── compiler
│   │           │   └── plugin.proto
│   │           ├── descriptor.proto
│   │           ├── duration.proto
│   │           ├── empty.proto
│   │           ├── field_mask.proto
│   │           ├── source_context.proto
│   │           ├── struct.proto
│   │           ├── timestamp.proto
│   │           ├── type.proto
│   │           └── wrappers.proto
│   └── readme.txt
└── protos
    └── protos
        └── foo.pb.go

huangapple
  • 本文由 发表于 2023年2月22日 04:06:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75525407.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定