DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Why and When to Use GraphQL
  • HTTP for Inter-Service Communication?
  • Replacing JSON With Protobuf in Your Microservice Mesh: A Zero-Downtime Migration Blueprint
  • Accelerating Connection Handshakes in Trusted Network Environments

Trending

  • A Software Factory on Kubernetes: Gemini Builds, jev Decides (Genkit + senro in Go)
  • Decoupling a Data Pipeline From the Tables It Was Never Supposed to Depend On
  • A Non-Expiring AKS Deployment Token Could Read Secrets Across Three Namespaces
  • Constrained Decoding Models Explained: Encoders, Decoders and When to Use Them

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Data Engineering
  3. Data
  4. gRPC Basics

gRPC Basics

As a continuation of the evaluation of Apache AVRO, take a look at the evaluation of the protocol buffer through gRPC.

By 
Milind Deobhankar
·
Aug. 03, 20 · Analysis
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
5.7K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

As part of our protocol evaluation in the last blog, we evaluated Apache AVRO. In continuation let’s try to evaluate protocol buffer (protobuf). The easiest and simplest way to evaluate protobuf is through gRPC. Let’s try to understand what is protobuf and gRPC.

What Is Protobuf?

Let’s take it from official website. “Protocol buffers are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data – think JSON, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages."z

There are two versions :

  • proto2
  • proto3

We are going to demonstrate proto3, as this is the latest. Syntax-wise there is considerable amount of difference between proto2 and proto3 but the underlying rpc concept remains the same. For extensive information about proto3 refer language guide here.

What Is gRPC?

gRPC is RPC (Remote Procedure Call) framework that can run in any environment and supports multiple programming language. It uses protocol buffers as both its Interface Definition Language (IDL) and as its underlying message interchange format. Many cool feature of gRPC is bidirectional streaming and multiplexing of requests using HTTP/2. You can get more info about gRPC here.

gRPC Over REST?

Following are some reasons you should choose gRPC over Rest:
1) gRPC transfer binary data as payload rather then text which makes communication much faster and compact.
2) gRPC use HTTP/2 with long-lived connections so overhead of making connection per request can be avoided.
3) gRPC is type-safe so if you are expecting an integer then nobody can send it as a string.
4) gRPC is few millisecond faster then REST. So if millisecond matter for you then gRPC can be good choice.
5) gRPC supports streaming so if you are looking for distributed streaming support gRPC can be pretty useful in this case.

Different gRPC Communication Mechanism:
1) Unary

Unary communication

2) Client Streaming

Client streaming

3)  Server Streaming 

Server streaming

4) Bi-directional Streaming 

Bi-directional streaming

In this blog, we are going to demo only unary other modes of communication will be described in upcoming blogs of gRPC so stay tune.

Our use-case (Order Service calling Order Confirmation) and payload is same we used in AVRO blog so that payload comparison becomes consistent. The first part is to create a contract between the client and server so let’s do that.

Protobuf contract: 

ProtoBuf
 




x
37


 
1
syntax = "proto3";
2
option java_multiple_files = true;
3
package com.milind.grpc;
4

          
5
message Order {
6
    string currency = 1;
7
    double totalAmount = 2;
8
    string orderId = 3;
9
    string emailAddress = 4;
10
    string cartURL =5;
11
    repeated LineItems lineItems = 6;
12
}
13
message LineItems {
14
    string sku = 1;
15
    string name = 2;
16
    string description = 3;
17
    string category = 4;
18
    string other = 5;
19
    double unitPrice = 6;
20
    double salePrice = 7;
21
    double quantity = 8;
22
    double totalPrice = 9;
23
}
24

          
25
message OrderConfirmation {
26
  string orderId = 1;
27
  repeated ConfirmedLineItems confirmedLineItems = 2;
28
}
29

          
30
message ConfirmedLineItems {
31
    string sku = 1;
32
    double confirmQuantity = 2;
33
}
34

          
35
service OrderConfrimationService {
36
    rpc confrim(Order) returns (OrderConfirmation);
37
}



I am not going to go in-depth about the datatype you can find it here. The server needs to implement OrderConfrimationService::confirm which will take Order as input and return OrderConfirmation. Once the contract is defined, we need to generate the code using the following maven plugin. 

XML
 




xxxxxxxxxx
1
30


 
1
        <plugin>
2
                <groupId>com.github.os72</groupId>
3
                <artifactId>protoc-jar-maven-plugin</artifactId>
4
                <version>3.5.1</version>
5
                <executions>
6
                    <execution>
7
                        <phase>generate-sources</phase>
8
                        <goals>
9
                            <goal>run</goal>
10
                        </goals>
11
                        <configuration>
12
                            <protocArtifact>com.google.protobuf:protoc:3.0.0</protocArtifact>
13
                            <inputDirectories>
14
                                <include>src/main/proto</include>
15
                            </inputDirectories>
16
                            <outputTargets>
17
                                <outputTarget>
18
                                    <type>java</type>
19
                                    <outputDirectory>src/main/java</outputDirectory>
20
                                </outputTarget>
21
                                <outputTarget>
22
                                    <type>grpc-java</type>
23
                                    <outputDirectory>src/main/java</outputDirectory>
24
                                    <pluginArtifact>io.grpc:protoc-gen-grpc-                                                            java:1.0.1</pluginArtifact>     
25
                                </outputTarget>
26
                            </outputTargets>
27
                        </configuration>
28
                    </execution>
29
                </executions>
30
            </plugin>



Execute mvn clean install command to generate the code.

Creating Server

gRPC require its own server it is not like servlet container where you will deploy your app. Creating server is very easy almost in line with npm server. Let’s do some coding. First we will provide implementation to our gRPC service.

Java
 




xxxxxxxxxx
1
16


 
1
public class OrderConfirmationServiceImpl extends 
2
        OrderConfrimationServiceGrpc.OrderConfrimationServiceImplBase {
3

          
4
    @Override
5
    public void confrim(Order request,
6
                        StreamObserver<OrderConfirmation> responseObserver){
7

          
8
    ...
9
        OrderConfirmation.Builder orderbuilder = OrderConfirmation.newBuilder()
10
                .setOrderId(request.getOrderId());
11
        ...
12
    responseObserver.onNext(orderbuilder.build());
13
        responseObserver.onCompleted();
14
    }
15

          
16
}



We need to extend generated class OrderConfrimationServiceImpl Base and provide the implementation of confirm method. If you see that, confirm method return type is void so how we will pass response to the client ?. It is through StreamObserver onNext() method and then completing the stream operation by onCompeted(). Let’s create the server to listen to particular port. 

Java
 




xxxxxxxxxx
1
10


 
1
public class GrpcServer {
2

          
3
    public static void main(String[] args) throws IOException, InterruptedException {
4
        int port=args.length==0?8080:Integer.parseInt(args[0]);
5
        Server server = ServerBuilder.forPort(port)
6
                .addService(new OrderConfirmationServiceImpl()).build();
7
        server.start();
8
        server.awaitTermination();
9
    }
10
}



Creating Client 

Java
 




xxxxxxxxxx
1


 
1
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", port)
2
                .usePlaintext()
3
                .build();
4

          
5
OrderConfrimationServiceGrpc.OrderConfrimationServiceBlockingStub stub =
6
        OrderConfrimationServiceGrpc.newBlockingStub(channel);
7

          
8
OrderConfirmation orderConfirmation = stub.confrim(DummyObjectCreator.createOrder());



Client code is straightforward:

  1. Create the channel to connect to gRPC server.
  2. Use the channel to create the stub.
  3. Call the gRPC service via stub and get the response object directly.

Note: gRPC doesn’t support null. It will throw exception at client side when you pass null in any attribute while creating the request object. If you don’t have the data then no need to set or assign in the request object rather then setting null.

Payload Comparison

Following is the comparison of the payload size with the same request data:

Payload comparison

If you see the size of payload for Protobuf is almost similar to JSON+GZip but compared to Avro it is 33% higher, but far better than JSON.

Conclusion

gRPC is very good for the streaming requirements and if you want to avoid making connections per request. In the case of a microservice architecture it has the added advantage of a reduction of payload, saving the connection cost and type-safe contract.

gRPC client also supports reactive way of handling the request, so if you are developing the reactive architecture then gRPC can support that too.

In an upcoming blog we will go through other modes of communication and the reactive way of handling the gRPC calls. Stay tuned.

You can get the entire code here.

Happy Coding.

Data (computing) Payload (computing) Requests Blog microservice Connection (dance) Use case Protocol Buffers Protocol (object-oriented programming) Web Protocols

Published at DZone with permission of Milind Deobhankar. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Why and When to Use GraphQL
  • HTTP for Inter-Service Communication?
  • Replacing JSON With Protobuf in Your Microservice Mesh: A Zero-Downtime Migration Blueprint
  • Accelerating Connection Handshakes in Trusted Network Environments

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook