无法使用 google/apis/annotations

Unable to use google/apis/annotations

我尝试使用 google api 注释在 gRPC 上使用 REST。 不幸的是,我遇到了一个协议问题,告诉我 annotations.proto 不存在或有错误。 我徒劳地尝试了几次修复。

我什至尝试重新安装一个完整的堆栈以防我做错了什么。 我将尽可能详细地向您详细介绍我在全新安装中设置的完整行和文件。

我从全新的 go install VM 中输入这些 shell 行:

$ mkdir sources/golang

$ echo 'export GOPATH=$HOME/sources/golang' >> $HOME/.zshrc

$ source ~/.zshrc

$ cd sources/golang

$ mkdir src

$ cd src

$ export PATH=$PATH:$GOPATH/bin

$ go get -u google.golang.org/grpc

$ go get -u github.com/golang/protobuf/protoc-gen-go

$ go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway

$ go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger

$ mkdir -p test/proto/test

$ cd test/proto/test

$ vim test.proto

在我的 test.proto 文件中,我写了非常基本的行:

syntax = "proto3";

package main;

import "google/api/annotations.proto";

service Tester {
    rpc Test (Request) returns (Reply) {
        option (google.api.http) = { get: "/v1/test" };
    }
}

message Request {
    string Message = 1;
}

message Reply {
    string Message = 1;
}

然后

$ cd $GOPATH/src

$ vim main.go

在我的 main.go 中,也非常基础:

package main

import (
        tc "test/proto/test"
        "context"
        "fmt"
        "log"
        "net"

        grpc "google.golang.org/grpc"
        codes "google.golang.org/grpc/codes"
)

func main() {
        err := StartServer("tcp", "127.0.0.1:50051")
        if err != nil {
                fmt.Printf("Error!! %s", err)
        }
}

type Server struct {
        tc.UnimplementedTesterServer
}

func (s *Server) Test(ctx context.Context, in *tc.Request) (*tc.Reply, error) {
        return &tc.Reply{Message: ""}, nil
}

func StartServer(protocol string, port string) error {
        lis, err := net.Listen(protocol, port)
        if err != nil {
                fmt.Printf("failed to listen: %v", err)
        }
        s := grpc.NewServer()
        tc.RegisterTesterServer(s, &Server{})

        error := s.Serve(lis)

        if error != nil {
                fmt.Printf("failed to serve: %v", error)
                return error
        }

        return nil
}

最后,我尝试编译我的原型文件:

$ protoc --proto_path=.:$GOPATH/src --go_out=plugins=grpc:. proto/*/*.proto

而且我系统地出现以下错误:

proto/test/test.proto:5:1: Import "github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/google/api/annotations.proto" was not found or had errors.

当我看到文件通过 go get ... 时,它们被放置在 $GOPATH/pkg/mod/

例如 googleapis' annotations.proto 文件位于:$GOPATH/pkg/mod/github.com/grpc-ecosystem/grpc-gateway@v1.12.1/third_party/googleapis/google/api/annotations.proto

可能是这个原因?

混合你的 protobuf 命令和你的 go 命令使这比它需要的更复杂。只关注protobuf来处理错误。

您正在导入 "google/api/annotations.proto"

你的proto_path是--proto_path=.:$GOPATH/src

所以这意味着当您执行 protoc 时,您应该将文件放在 ./google/api/annotations.proto 或 $GOPATH/src/google/api/annotations.proto

我遇到了同样的问题,我试图自动化一个解决方案,该解决方案适用于任何 Linux,并且依赖性尽可能小。

grpc_gateway 的官方文档指出:

You will need to provide the required third party protobuf files to the protoc compiler. They are included in this repo under the third_party/googleapis folder, and we recommend copying them into your protoc generation file structure. If you've structured your proto files according to something like the Buf style guide, you could copy the files into a top-level ./google folder.

换句话说:以某种方式下载它并使其工作。

此外,由于此引用也是原始来源中的引用,所以它不是很明显,这让我在前 2 次阅读它以寻找解决方案时跳过它,这很糟糕。

所以,正如我在@SeanF 回答的评论中争论的那样,使用 go get 不是一个可维护的选项,因为它将项目保存在一个名称包含最新版本的文件夹中,这会导致维护时头疼版本变化。

所以最好的选择实际上是克隆 grpc-gateway 项目:

git clone https://github.com/grpc-ecosystem/grpc-gateway
protoc -I grpc-gateway/ \
    -I grpc-gateway/third_party/googleapis \
    --go_out=plugins=grpc:. proto/*/*.proto

我还用我的解决方案写了一个要点,它只依赖于 dockerbash,因此应该是稳定的:

https://gist.github.com/VinGarcia/43dfa71b412c16b9365c224d3760af5e

它有一个问题,我使用 go.mod 但在每次执行后都将其丢弃,这是不好的。但它目前运行良好,可能对某些人有帮助。

此致