HandsOn Introduction to gRPC with Java

gRPC is a modern open-source high-performance Remote Procedure Call (RPC) framework developed by Google. It can efficiently connect services in and across data centers with pluggable support for load balancing, tracing, health checking and authentication.

  1. Protobuf instead of JSON/XML
    REST uses JSON for sending and receiving messages. JSON is flexible, text-based and human-readable but it is not fast enough or light-weight enough for transmitting data between systems.
    gRPC uses Protobuf(protocol buffers) messaging format which is faster and more efficient for data transmission
  2. First-class support for code generation
    REST needs third-party tools to generate the code for API calls.
    gRPC comes with an in-built protoc compiler which provides the code generation features by default.
  3. Built on HTTP 2
    REST is built on HTTP 1.1 which uses a request-response model of communication.
    gRPC uses HTTP2 so that it supports client-response communication and bidirectional streaming.
  4. Works across languages and platforms
    Since the code can be generated for any language, it is easy to create micro-services in any language to interact with each other
Communication across languages
Types of API in gRPC

Following is an example of the four types of APIs. You can understand it further when we are implementing the sample.

I hope you got a basic idea about gRPC. So, now let’s see how we can implement a gRPC server and client using Java.

We will build a CarParkusing gRPC.

  1. Create a maven project
  2. Define a service in a .proto file
  3. Generate server and client code using the protocol buffer compiler
  4. Build the server application, implement the generated service interfaces spawning the gRPC server
  5. Build the client application, making RPC calls using generated stubs

Let’s go through each of these steps in detail. I have shared the complete source code of the sample on GitHub. You can refer to that and there are inline comments for more details. [1]

Create a maven project

  1. Create a maven project. (You can refer to the complete pom of the sample)
  2. Add the following dependencies in the pom file.

3. Add the protobuf-maven-plugin. This is responsible for code generation.

<protoSourceRoot> indicates the place where the service definition file is located.

I’m are using java 8 for my sample.

Define the service

Defining the service means specifying the methods that can be remotely called along with their parameters and return types.

This is done in the .proto file using Protocol Buffers. The structure of the payload messages should also be described here.

You can refer to the complete proto file of the sample.

  1. Add the common configurations
  • syntax : this indicates the syntax of this file
  • java_multiple_files : this says the compiler to generate java code in separate files. Otherwise, all will be in a single java file

2. Define the message formats

In this, vehicle_number and vehicle_type are the attributes of the Vehicle message. And the given value is the order. ParkRequest is another message format.

Likewise you can define all the message formats that you will need.

3. Define the service and the methods

  • CarParkService : This is the gRPC service
  • parkVehicle : This is a method in the CarParkService
  • ParkRequest : This is the input parameter for the parkVehicle method
  • ParkResponse : This is the response of the parkVehicle method

4. Define another method with streaming

In this method, the server will stream the response.

Generate the source code

Run the mvn clean install command to compile the project and generate the java codes for the defined service.

You will see the generated java classes inside the <SAMPLE_HOME>/target/generated-sources/protobuf/java

Implement the server

  1. Create a separate package for the server. For my sample, I will create the package as org.sample.park.server

2. Implement the service by extending the generated service base class. The base class has all the methods that we have defined in the proto file. I have service implementation in the CarParkServiceImpl class.

3. In the service implementation class, let’s first implement the parkVehicle method by overriding the method of the base class.

gRPC uses builders for creating objects.

Inside the parkVehicle method, the number and the type of the vehicle is printed and the sent back to the client.

The response is sent when we call responseObserver’s onNext() method.

onCompleted() specifies that RPC is finished, else the connection will be hung, and the client will just wait for more information to come in.

4. Let’s implement the parkVehicleManyTimes method by overriding the method of the base class where the server will send several messages to the client.

Here, the server is sending 3 responses to the client and before each response, the server will wait for 10 seconds.

5. Write a separate java class to start the server. I will name my class as CarParkServer. Here, we need to add the service and start the server with a given port. The server needs to be kept alive for the client to make requests.

Implement the Client

  1. Create a separate package for the client. For my sample, I will create the package as org.sample.park.client
  2. Write a class to start the client. I have the class CarParkClient.
  3. In the main method of the client, initiate the communication with the server using a channel.

4. Inside the same main method, use the stub of the CarParkService to call the methods of the service. The stub is the primary way for the clients to interact with the server.

Here we have used a blocking/synchronous stub so that the RPC call waits for the server to respond, and will either return a response or raise an exception. There are two other types of stubs provided by gRPC, which facilitate non-blocking/asynchronous calls.

5. In the same main method, define a ParkRequest to call the parkVehicle method. And then, we call parkVehicle method and to catch the ParkResponse returned by the method.

6. In the same main method, call the parkVehicleManyTimes method and handle the streaming response from the server.

Try out the service

  1. Run the server.
  2. Run the client.

Then you can see the corresponding messages get printed.

I know this article is a bit lengthy. But I assure you that is because of the attached code snippets. Otherwise, the steps are simpler. 😌

Hope you understand how gRPC works. You can try out the sample and see how easy it is.

See you soon with another blog. Happy Reading!

[1] https://github.com/pamodaaw/grpc-sample

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store