gRPC (Google Remote Procedure Call): gRPC is an open-source RPC architecture developed by Google to enable high-speed communication between microservices. gRPC allows developers to integrate services written in different languages. gRPC uses the Protobuf messaging format (Protocol Buffers), a highly efficient, highly packed messaging format for serializing structured data. For some use cases, the gRPC API may be more efficient than the REST API. Let’s try to write a server on gRPC. First, we need to write several .proto files that describe services and models (DTO). For a simple server, we’ll use ProfileService and ProfileDescriptor. ProfileService looks like this: gRPC supports a variety of client-server communication options. We’ll break them all down:
Normal server call – request/response. Streaming from client to server. Streaming from server to client. And, of course, the bidirectional stream.
The ProfileService service uses the ProfileDescriptor, which is specified in the import section:
int64 is Long for Java. Let the profile id belong. String – just like in Java, this is a string variable.
You can use Gradle or maven to build the project. It is more convenient for me to use maven. And further will be the code using maven. This is important enough to say because for Gradle, the future generation of the .proto will be slightly different, and the build file will need to be configured differently. To write a simple gRPC server, we only need one dependency: It’s just incredible. This starter does a tremendous amount of work for us. The project that we will create will look something like this:
We need GrpcServerApplication to start the Spring Boot application. And GrpcProfileService, which will implement methods from the .proto service. To use protoc and generate classes from written .proto files, add protobuf-maven-plugin to pom.xml. The build section will look like this:
protoSourceRoot – specifying the directory where the .proto files are located. outputDirectory – select the directory where the files will be generated. clearOutputDirectory – a flag indicating not to clear generated files.
At this stage, you can build a project. Next, you need to go to the folder that we specified in the output directory. The generated files will be there. Now you can gradually implement GrpcProfileService. The class declaration will look like this: GRpcService annotation – Marks the class as a grpc-service bean. Since we inherit our service from ProfileServiceGrpc, ProfileServiceImplBase, we can override the methods of the parent class. The first method we’ll override is getCurrentProfile: To respond to the client, you need to call the onNext method on the passed StreamObserver. After sending the response, send a signal to the client that the server has finished working onCompleted. When sending a request to the getCurrentProfile server, the response will be: Next, let’s take a look at the server stream. With this messaging approach, the client sends a request to the server, the server responds to the client with a stream of messages. For example, it sends five requests in a loop. When sending is complete, the server sends a message to the client about the successful completion of the stream. The overridden server stream method will look like this: Thus, the client will receive five messages with a ProfileId, equal to the response number. Client stream is very similar to server stream. Only now the client transmits a stream of messages, and the server processes them. The server can process messages immediately or wait for all requests from the client and then process them. In the Client stream, you need to return the StreamObserver to the client, to which the server will receive messages. The onError method will be called if an error occurred in the stream. For example, it terminated incorrectly. To implement a bidirectional stream, it is necessary to combine creating a stream from the server and the client. In this example, in response to the client’s message, the server will return a profile with an increased pointCount. Conclusion We have covered the basic options for messaging between a client and a server using gRPC: implemented server stream, client stream, bidirectional stream. The article was written by Sergey Golitsyn