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?
- - Create a .proto file for define the service and the input/out objects
- Create a java project lib, to allow the other services get the objects that are require to communicate between them
- Create the server application
- Create the client application
- 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 😆 🍍