gRPC Implementation with spring boot and java 17 (2/3)

Anderson
6 min readJan 13, 2023

--

Keeping on track with my first publication about gRPC, I want to show you a simple implementation of gRPC with spring boot that in a not far further post we’re going to containerize and config files to deploy successfully in a kubernetes environment and see how use correctly the load balancer with gRPC.

As we say in Venezuela, “Vamo’ a echale bola ✌️”

First of all, remember that a server/client gRPC communication use to understand them and be able to communicate is the IDL (Interface Definition Language) ProtoBuf.

Then what we’re going to do?

  1. - Create a .proto file for define the service and the input/out objects
  2. Create a java project lib, to allow the other services get the objects that are require to communicate between them
  3. Create the server application
  4. Create the client application
  5. Test it!

Step One, Define .proto file

There are a lot of documentation to learn about how define a .proto and conventions, these are some of them

Let’s check some lines of that code

  • Line 1-> syntax

This first line is to define which will be the syntax that you’re going to use, first line before anything, any comment or any empty line. If you don’t define this, the Buffer compiler would use proto2.

  • Line 3 -> package

Here we define in which package the auto generated classes are going to be created, also work to avoid collision between name of classes

  • Line 5, 6 -> option java_package and java_multiple_files

java_package, is the package you wnat to use for your generated Java/Kotlin classes
java_multiple_files, if its false, only a single class will be generated for this .proto and the Java classes/enums/etc. generated for the top-level messages, services, and enumerations will be nested inside of an outer class. If its true, separate .java files will be generated for each of the Java classes/enums/etc. generated for the top-level messages, services, and enumerations, and the wrapper Java class generated for this .proto file won't contain any nested classes/enums/etc.

Then, we define the ProductResponse as a message, and let’s take a look to the parameter and how are define.

In this link, we can see the different data type that can be used https://developers.google.com/protocol-buffers/docs/proto3#scalar and if you want to know more, this link could be interesting to learn about how these types are encoded https://developers.google.com/protocol-buffers/docs/encoding

So, we define

message ProductResponse {
//DataTye - Parameter name = Number?
int64 id = 1;
....

What is this Number?

As you can see, each field in the message definition has a unique number. These field numbers are used to identify your fields in the message binary format, and should not be changed once your message type is in use.

You can learn more here

Then, we define the service in lines 17, 18, 19

Remember the different types of streaming api that we can built with gRPC

service ProductService {
//Unary
rpc getProduct(ProductRequest) returns (ProductResponse) {}

// Streaming Server
rpc getProductManyTimes(ProductRequest) returns (stream ProductManyTimesResponse) {}

// Streaming Client
rpc getLongProduct(stream LongProductRequest) returns (LongProductResponse) {}

// Bi Directional Streaming
rpc getEveryProduct(stream EveryProductRequest) returns (stream EveryProductResponse) {}

}

Now, we’re going to have a gradle project with java-library plugin

Step Two, define our library to encapsulate the auto generated classes from .proto file

Build.gradle file example:

Full project example can be found in github

Our project would look like

So after run some gradle tasks like:

We would have in our local m2 a library with the auto generated classes from our .proto required for the server and client application

Step Three, Create the server application

We need to import our new library and the library that help us to expose a grpc server

Build.gradle file would look like this

At line 17, we’re using the mavenLocal repository to look for our local library

At line 29, we import the library that we just created

Now you can see at line 30, the required library to auto configure a gRPC server

In our application.yml, we would add the port that we’re going to use for the gRPC server

Hint:

I’ve been using the versión 3.0.1 of spring boot in these projects, so I’ve to indicate to this project manually to inject the auto configuration files of gRPC because it isn’t support it yet

Here you find the issue in github and an example of how fix it for client and service

Now, our only class for this project is a class which would extend from the auto generated service implementation and will override the operation that we define in the .proto file

Full project example can be found in github

Step Four, Create the client application

We need to import our new library and the library that help us to create a grpc client

Build.gradle file would look like this

We did pretty much the same like the server project

Now you can see at line 30, the required library to construct a grpc client

In our application.yml, we would add the configuration required to define our grpc client

You can see that we define at line 13, how our service would be named, at line 14 the address that is required to communicate with the server and the load balancing policy round_robin, we would talk about this further

Now, Let’s see how implement a component which would have the grpc client

We can see that at line 12, The annotation @GrpcClient, is doing the hard work for us, is inject into the field productServiceBlockingStub, the object with the right configuration to consume the server

Full project example can be found in github

Step Five, Let’s test this

First of all, let’s test the server application with postman

Pretty simple, I used the .proto file to indicate to postman the operation that would use

And work amazing! 🎆

I also create a controller in the grpcclient-product application to use the grpc client component

Then we consume this endpoint with postman and…

And also work amazing! 👍

The complete code can be found on Github here

Link to the next article here

Thanks a lot for your time reading my article till the end
Keep on learning and always keep your thirst knowledge, since this world comes with never ending supply of knowledge.

If you think this article was useful and help you in some way, please give a clap and follow me 😆 🍍

--

--

Anderson

Senior Java Developer at Capitole Consulting Spain. I'm from Venezuela, I love my job and the challenge of keeping up with all the new things to learn every day