Add gRPC to Your Java Application
Learn how to autogenerate gRPC code, back a gRPC service with implementation, and spin up a server to send a response to a client.
Join the DZone community and get the full member experience.
Join For FreegRPC is a high-performance, open-source universal RPC framework.
There are various benefits to using gRPC.
- It simplifies development by providing client/server code.
- It supports multiple languages.
It all starts with defining a .proto file, .proto files reside on src/main/proto file.
Be aware it is a good practice to keep proto files on a repo and have some schema versioning. This way developers from other teams could generate their SDKs by referencing them, even for other languages.
We shall create an Order Service on src/main/proto/Order.proto:
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.egkatzioura.order.v1";
service OrderService {
rpc ExecuteOrder(OrderRequest) returns (OrderResponse) {};
}
message OrderRequest {
string email = 1;
string product = 2;
int32 amount = 3;
}
message OrderResponse {
string info = 1;
}
In order to work with gRPC the following binaries need to be placed:
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.39.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.39.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.39.0</version>
</dependency>
<dependency> <!-- necessary for Java 9+ -->
<groupId>org.apache.tomcat</groupId>
<artifactId>annotations-api</artifactId>
<version>6.0.53</version>
<scope>provided</scope>
</dependency>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.17.2:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.39.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
By executing mvn clean install
, the classes will be generated on target/classes.
Those classes are more than enough to spin up a server and run a client to communicate to it.
Therefore let’s try to spin up the server.
We shall create a service Implementation:
package com.egkatzioura.order.impl;
import com.egkatzioura.order.v1.Order;
import com.egkatzioura.order.v1.OrderServiceGrpc;
import io.grpc.stub.StreamObserver;
public class OrderServiceImpl extends OrderServiceGrpc.OrderServiceImplBase {
@Override
public void executeOrder(Order.OrderRequest request, StreamObserver<Order.OrderResponse> responseObserver) {
Order.OrderResponse response = Order.OrderResponse.newBuilder()
.setInfo("Hi "+request.getEmail()+", you order has been executed")
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
Then our main class will spin up the server and serve the request.
package com.egkatzioura.order;
import java.io.IOException;
import com.egkatzioura.order.impl.OrderServiceImpl;
import io.grpc.Server;
import io.grpc.ServerBuilder;
public class Application {
public static void main(String[] args) throws IOException, InterruptedException {
Server server = ServerBuilder
.forPort(8080)
.addService(new OrderServiceImpl()).build();
server.start();
server.awaitTermination();
}
}
While the server is running we can spin up another main class which shall communicate to the server and execute a gRPC request towards the server.
package com.egkatzioura.order;
import com.egkatzioura.order.v1.Order;
import com.egkatzioura.order.v1.OrderServiceGrpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
public class ApplicationClient {
public static void main(String[] args) {
ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 8080)
.usePlaintext()
.build();
OrderServiceGrpc.OrderServiceBlockingStub orderServiceBlockingStub
= OrderServiceGrpc.newBlockingStub(managedChannel);
Order.OrderRequest orderRequest = Order.OrderRequest.newBuilder()
.setEmail("hello@word.com")
.setProduct("no-name")
.setAmount(3)
.build();
Order.OrderResponse orderResponse = orderServiceBlockingStub.executeOrder(orderRequest);
System.out.println("Received response: "+orderResponse.getInfo());
managedChannel.shutdown();
}
}
So we just autogenerated gRPC code, we backed a gRPC service with an implementation, a server spun up and a client got a response from the server.
You can find the source code on Github.
On the next blog, we shall add gRPC to our Spring Application.
Published at DZone with permission of Emmanouil Gkatziouras, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments