gRPC with Java. In today’s fast-paced software development world, efficiency and speed are paramount. This is where gRPC (gRPC Remote Procedure Calls) comes into play, especially in the context of microservices architecture. gRPC, developed by Google, is an open-source framework that enables quick and efficient communication between microservices. This article delves into the basics of implementing gRPC in Java, offering a step-by-step guide to integrating this powerful technology into your microservices architecture.
Table of Contents
Introduction to gRPC
gRPC is a high-performance, universal RPC (Remote Procedure Call) framework that uses HTTP/2 for transport, Protocol Buffers as its interface description language, and provides features such as authentication, load balancing, and more. It is designed to enable seamless and efficient communication between services, making it an excellent choice for microservices architectures where various services need to communicate with each other in a lightweight and efficient manner.
Why Use gRPC in Java Microservices?
Java, being one of the most widely used programming languages for building enterprise-level applications, pairs well with gRPC for several reasons:
- Performance: gRPC’s use of HTTP/2 and Protocol Buffers results in a highly efficient, low-latency communication layer.
- Cross-Language Support: gRPC supports multiple languages, making it easy to integrate services written in different languages.
- Strong Typing: With Protocol Buffers, you define your service methods and messages in a strongly typed manner, which gets compiled into efficient, language-specific code.
- Ease of Use: gRPC provides out-of-the-box support for features like authentication, load balancing, and retries, simplifying microservices development.
gRPC with Java Microservice Example
Let’s create a gRPC java project and see the working –
Create a Maven Project
First, create a new Maven project. You can do this either through your IDE (like IntelliJ IDEA or Eclipse) or by using the Maven command line tool. If you’re starting from scratch, create a pom.xml
file at the root of your project directory. This XML file will define your project’s build configuration.
Add Required Dependencies
To use gRPC in your project, you need to include the gRPC core library and the protobuf plugin that compiles .proto
files into Java code. Add the following dependencies to your pom.xml
file:
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.61.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.grpc/grpc-protobuf -->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.61.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.grpc/grpc-stub -->
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.61.0</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.2</version>
</dependency>
Add the Protobuf Maven Plugin
To automatically generate Java code from your .proto
files, add the protobuf-maven-plugin
to your pom.xml
. This plugin compiles .proto
files during the build process.
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.2</version>
</extension>
</extensions>
<plugins>
<!-- compile proto file into java files. -->
<plugin>
<groupId>com.github.os72</groupId>
<artifactId>protoc-jar-maven-plugin</artifactId>
<version>3.11.1</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<includeMavenTypes>direct</includeMavenTypes>
<inputDirectories>
<include>src/main/</include>
</inputDirectories>
<outputTargets>
<outputTarget>
<type>java</type>
<outputDirectory>src/main/java</outputDirectory>
</outputTarget>
<outputTarget>
<type>grpc-java</type>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${io.grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
<outputDirectory>src/main/java</outputDirectory>
</outputTarget>
</outputTargets>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Configure the gRPC Version
To keep your project organized and make it easier to update the gRPC version in the future, define the gRPC version as a property in your pom.xml
:
<properties>
<io.grpc.version>1.55.1</io.grpc.version>
</properties>
Then, replace the version numbers in your gRPC dependencies and the protobuf plugin with ${grpc.version}
to ensure consistency.
Defining Service in Protocol Buffers
Start by defining your service and its method signatures in a .proto
file. This file acts as the contract between your services, specifying the request and response message types.
syntax = "proto3";
package gfc.proto;
option java_multiple_files = true;
// The greeting service definition.
service GreetingService {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloResponse) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloResponse {
string message = 1;
}
Generate Java Code from the proto file
Use the Protocol Buffer compiler (protoc
) with the gRPC Java plugin to generate Java stubs from your .proto
file. These stubs are the building blocks for your client and server code.
If using Maven or Gradle, you can configure your build script to automatically generate these classes when you build your project.
For Maven use this command –
mvn clean package
Java files generated from the proto file
Implement the Service in Java
Implement the service interface generated by the protoc
compiler. This involves extending the abstract base class provided in the generated Java code and implementing the service methods.
package service;
import gfc.proto.GreetingServiceGrpc;
import gfc.proto.HelloRequest;
import gfc.proto.HelloResponse;
import io.grpc.stub.StreamObserver;
public class greetingService extends GreetingServiceGrpc.GreetingServiceImplBase {
@Override
public void sayHello(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {
HelloResponse response = HelloResponse.newBuilder() .setMessage("Hello " + request.getName())
.build(); responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
Start the gRPC Server
Now let’s Create a server to listen for requests on a port and dispatch them to your service.
import io.grpc.ServerBuilder;
import service.greetingService;
import java.io.IOException;
public class Server {
public static void main(String[] args) throws IOException, InterruptedException {
io.grpc.Server server = ServerBuilder.forPort(8080)
.addService(new greetingService()) .
build() .start();
System.out.println("Server started, listening on " + server.getPort()); server.awaitTermination();
}
}
Now our micro-service is ready let’s start our server and test the endpoints –
Testing End Point
Let’s test our endpoint with the BloomRPC application
Source Code
You can download the entire source code here – source code
Happy Coding & Keep Learning