Changes in Go implementation of the new protobuf and gRPC

If you don't know yet, there were major changes by Google in protobuf and gRPC implementation for Go. New version should be better in all means so you should switch as soon as possible, if you are already using these technologies. In this article I am going to focus on Linux variant, but the upgrade procedure should be quite similar on OSX or Windows.

In order to use protobuf compiler or generator, if you wish, you had to install protoc compiler. There are no changes in this step, you still need it although you may want to upgrade to the latest version.

Previously, in order to generate Go code you had to use protoc-gen-go plugin which you had to install using the following command:

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

Now we have new implementation which replaces the old version and you should just run:

go get google.golang.org/protobuf/cmd/protoc-gen-go

Unfortunately, this is not all. Previously you could generate gRPC code together with protobuf without further dependencies, so it was enough to run a command similar to this:

protoc --go_out=plugins=grpc:. --go_opt=paths=source_relative some_path/example.proto

As plugin gRPC is removed from the new implementation, flag --go_out won't work like this anymore. Instead, you have to install protoc-gen-go-grpc and you have to use the protoc the following way:

go get google.golang.org/grpc/cmd/protoc-gen-go-grpc
protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative some_path/example.proto

If you receive some strange errors that some constants are not defined, you may want to pin github.com/golang/protobuf, google.golang.org/grpc and google.golang.org/protobuf dependencies in go.mod to the latest versions or simply delete these lines in go.mod and run `go build` again. Hopefully it is going to fetch the right dependencies.

Finally, you will receive errors that your implementation of the gRPC server interfaces does not implement yourpb.mustEmbedUnimplementedYourServiceServer method. You can solve this easily by embeding appropriate yourpb.UnimplementedYourServiceServer in your implementation. After this the code should hapilly compile. If you have trouble solving this, you may want to check the examples from the official repository.

If you use vscode editor, it is worth saying that you can install proto3 extension from the marketplace and put the following snippet in the settings.json file:

{
  "protoc": {
    "options": [
      "--go_out=.",

      "--go_opt=paths=source_relative",

      "--go-grpc_out=.",

      "--go-grpc_opt=paths=source_relative"
    ]
  }
}

If you do so, you will be able to generate the files inside the editor. Happy protobuffing 🙂