5 reasons to use gRPC
Communication between services is one of the critical parts of the system. A lot of factors depend on the decision: complexity of implementation, latency, throughput, etc. I’m going to tell you about technology that covers these aspects — it’s easy to implement and it gives you fast connection! Greetings, enters the stage… gRPC. Google invented this technology and open-sourced it in 2015. And this already gained a lot of fans! Let’s look at 5 reasons why you should use this technology.
Simple definition
By default gRPC uses protocol-buffer. It’s a language-independent definition for serializing structured-data and services that use this data. To describe your service, you need to create .proto file. A simple example looks like this:
service Service {
rpc DoSomething (InputRequest) returns (OutputResponse);
}
message InputRequest {
string message = 1;
}
message OutputResponse {
string message = 1;
}
This defines a service named Service with one method DoSomething, the input parameter is InputRequest and it returns OutputResponse. The number at each parameter defines the order of serialization, it should be unique within one particular message.
It’s also possible to create more comprehensive messages, where the message consists of other messages.
Types that technology allows to use: string, bytes, bool, int32, int64, etc. The important thing you should know is there are no null values, all fields use the default value. And proto is backward compatible with new version unless you change the order of the fields.
Cross-language support
The mentioned above proto could be used in the most popular languages: C# / .NET, C++, Go, Java, Kotlin/JVM, PHP, Python, Ruby. It’s very useful when you have services written in different languages.
Easy to use
Here is an example of the command for CLI to generate code from proto file on Java (and, of course, there are plugins for gradle, maven and other building tools):
protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/service.proto
Then you just need to implement your service:
public class ServiceImpl extends ServiceGrpc.ServiceImplBase {
...
}
And start the server:
...
public void start() throws IOException {
Server server = ServerBuilder.forPort(8080)
.addService(new ServiceImpl())
.build();
// Start the server
server.start();
...
}
Using from the client is also simple enough. You should only provide host and port:
...
ManagedChannel channel = ManagedChannelBuilder.forTarget("localhost:8080")
.usePlaintext(true)
.build();
...
And send your request:
...
ServiceGrpc.ServiceBlockingStub stub = ServiceGrpc.newBlockingStub(channel);
ServiceOuterClass.InputRequest request =
ServiceOuterClass.InputRequest.newBuilder()
.setMessage("Ray")
.build();
ServiceOuterClass.OutputResponse response = stub.doSomething(request);
...
As you can see it’s really easy.
It’s really fast
Think of protobuf as an XML, but, smaller, faster, and simpler. So the serialization consumes less time and CPU usage.
Besides this, gRPC uses HTTP/2. Which gives you multiplexing and minimize protocol overhead via efficient compression of the header. Multiplexing allows having multiple requests over a single TCP connection. Both features reduce latency for communication. Worth to mention the HTTP/2 was made from project called SPDY an experimental protocol from Google in 2009, the main goal was to reduce latency for web pages.
Built-in timeout
In order safe precious resources of the server, if the response takes longer than needed, the client could use a timeout feature. For any request, you could add parameters for the request. Example on java:
response = serviceStub.withDeadlineAfter(deadlineMs, TimeUnit.MILLISECONDS).doSomething(request);
And the client receives DEADLINE_EXCEEDED in case of exceeding.
Conclusion
As you can see, gRPC is very fast, cross-language, and easy to use technology. Consider using it in your system. Do you know other good solutions with such features? Please, write in the comments! I’m interested in hearing it.
If you liked it, please clap 😏