grpc with mustEmbedUnimplemented*** method

15.8k Views Asked by At

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?

3

There are 3 best solutions below

2
On

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

1
On

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{})
0
On

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:

  1. 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.

  2. 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.