To round off the list of useful Google technologies for now, let’s look at gRPC. Building on top of Protocol Buffers, it enables a language agnostic RPC definition. Similar to protobufs, auto-generated source code for a long list of compatible languages can easily be integrated. This includes the source for both the client and the server side. The communication is by protobuf objects, over HTTP.
Proto Service
Like protobufs, the RPC service API is defined in a .proto file.
Notice the service and rpc keywords. Within a service, there can be one or more rpc methods. The method declaration follows the pattern “rpc MethodName (InputType) returns (ReturnType) {}”. However, as opposed to many languages, there can only be one input and one return object, which means that it is common to have dedicated Request and Response types with nested fields.
Finally, the import statement includes the proto we looked in the previous example. The Person message can then be used in the fields (or grpc) of this proto file.
Bazel
To compile the gRPC service code, we need an additional Bazel rule. Now, gRPC compile rules have changed frequently over the years, often with incompatible versions and upgrades. For now, we’re using the java_grpc_library rule from rules_proto_grpc_java. This rule will also compile the imported person.proto.
Notice the protos field, similar to srcs in other rules. It takes the proto_library dependencies of all protos and dependencies to compile.
Finally, there are two java_binary rules for the server and client which we’ll look at next.
Server
This examples includes a very minimal server class, which combines the main, start and RPC methods. Typically, these would be split over multiple classes and files.
First, the sayHello RPC method, which takes the protobufs HelloRequest input and HelloReply output as parameters. Within the methods, the usual protobuf generated API methods apply.
To start and let the server run, a io.grpc.Server objected is constructed our GreeterGrpc as the Service. This runs in blocking mode.
Client
Finally, we fire up a minimal gRPC client to make a request on the server. It news a channel, a stub (which has the service API) and a request. After the call, the reply from the server is printed and we shutdown and exit.
Run it
To run the server and client, use two separate terminal windows and call, in order: