Recently, grpc-go introduced the mustEmbedUnimplemented*** method. It is used for forward compatibility.
In simple terms, I am unable to understand how it is helping and how earlier without it what problems we were facing? In my structs now I use to add the following statement but, I don't know why...
type server struct {
pdfpb.UnimplementedGreetServiceServer
}
In Github issue - https://github.com/grpc/grpc-go/issues/3669 they debated over it, can someone please explain in simple terms how it is helping and how earlier without it what problems we were facing?
That was quite basic.
UnimplementedGreetServiceServer
is a struct with all implemented methods.
When I add pdfpb.UnimplementedGreetServiceServer
I am able to call UnimplementedGreetServiceServer
defined methods.
That's how, if I add more RPC services in the proto file, then I don't need to add all RPC methods leading to forward compatibility.
Demo code is available at: https://github.com/parthw/fun-coding/tree/main/golang/understanding-grpc-change
This error comes newer versions of the protoc-gen-grpc-go
compiler. Server implementations must now be forward-compatible.
Before this change, whenever you registered a server implementation, you would do something like this:
pb.RegisterFooBarServiceServer(
server,
&FooBarServer{}, // or whatever you use to construct the server impl
)
Which would result in a compile-time error in case your server has some missing method implementations.
With the newer proto compiler version, forward-compatibility becomes opt-out, which means two things:
you must now embed UnimplementedFooBarServiceServer
, as the error message suggests. As I said, this will not produce compiler errors when you do not explicitly implement new methods (this is what forward compatibility means). Though it will result in a run-time error with codes.Unimplemented
if you attempt to call an RPC that you didn't (or forgot) to explicitly implement.
you can still opt-out of forward compatibility by embedding instead UnsafeFooBarServiceServer
(with Unsafe
prefix). This interface simply declares the mustEmbedUnimplementedFooBarServiceServer()
method which makes the error in the question go away, without forgoing a compiler errors in case you didn't explicitly implement the new handlers.
So for example:
// Implements the grpc FooBarServiceServer
type FooBarService struct {
grpc.UnsafeFooBarServiceServer // consciously opt-out of forward compatibility
// other fields
}
You can also generate code without forward compatibility by setting an option on protoc-gen-grpc-go
plugin (source):
protoc --go-grpc_out=require_unimplemented_servers=false:.
Note the :.
after the --go-grpc_out
option is used to set the path element.
For anyone that still have problems with mustEmbededUnimplementedServiceServer
as suggested on the Github Issue. the best solution is just to update your ServerStruct.
Ex.
type AuthenticationServiceServer struct {
}
To.
type AuthenticationServiceServer struct {
service.UnimplementedAuthenticationServiceServer
}
that will solve the exception throw by Go when doing this.
grpcService.RegisterAuthenticationServiceServer(grpcServer, controller.AuthenticationServiceServer{})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With