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
Over 2 million developers have joined DZone.
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?
  • Accelerating Connection Handshakes in Trusted Network Environments
  • What Is API-First?

Trending

  • Querying Without a Query Language
  • Building an Image Classification Pipeline With Apache Camel and Deep Java Library (DJL)
  • Product-Led Software Delivery: Intelligent Platforms for DevOps at Scale
  • Navigating the Complexities of AI-Driven Integration in Multi-Cloud Environments: A Veteran’s Insights
  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 user avatar
Milind Deobhankar
·
Aug. 03, 20 · Analysis
Likes (14)
Comment
Save
Tweet
Share
5.4K Views

Join the DZone community and get the full member experience.

Join For Free

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?
  • Accelerating Connection Handshakes in Trusted Network Environments
  • What Is API-First?

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • 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