Enterprise Java

Building gRPC Services with Spring Boot

Spring gRPC is a framework that integrates gRPC with Spring Boot, making it easier to build scalable microservices using Protobuf-based contracts. It leverages Spring Boot’s dependency injection and configuration management with gRPC’s high-performance RPC mechanism. Let us delve into understanding the Spring gRPC project guide.

1. What is Spring gRPC?

gRPC is a high-performance Remote Procedure Call framework developed by Google that enables client and server applications to communicate transparently. Spring Boot, on the other hand, is a popular Java framework for building microservices quickly and efficiently. Spring gRPC bridges these two technologies by providing an easy-to-use starter project (grpc-spring-boot-starter) that hides the underlying complexity of setting up gRPC servers and clients within a Spring Boot application.

2. Code Example

To build a Spring Boot project that supports gRPC, we will use the Spring Boot starter library provided by yidongnan. This library handles all the gRPC boilerplate code and allows you to focus on your service logic.

2.1 Add Dependencies (pom.xml)

Begin by configuring your Maven project with the required dependencies. You need the gRPC server and client starters along with the protobuf Maven plugin to generate Java files from .proto definitions.

<dependencies>
  <dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-server-spring-boot-starter</artifactId>
    <version>latest__jar__version</version>
  </dependency>
  <dependency>
    <groupId>net.devh</groupId>
    <artifactId>grpc-client-spring-boot-starter</artifactId>
    <version>latest__jar__version</version>
  </dependency>
</dependencies>

<build>
  <extensions>
    <extension>
      <groupId>kr.motd.maven</groupId>
      <artifactId>os-maven-plugin</artifactId>
      <version>latest__jar__version</version>
    </extension>
  </extensions>
  <plugins>
    <plugin>
      <groupId>org.xolstice.maven.plugins</groupId>
      <artifactId>protobuf-maven-plugin</artifactId>
      <version>latest__jar__version</version>
      <configuration>
        <protocArtifact>com.google.protobuf:protoc:latest__jar__version:exe:${os.detected.classifier}</protocArtifact>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>compile</goal>
            <goal>compile-custom</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

This setup allows your Maven build to compile .proto files into usable Java classes automatically.

2.2 Writing the gRPC Service Contract

The .proto file defines the service contract including request and response structures. Create the following greet.proto file under src/main/proto.

syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.example.grpc";
option java_outer_classname = "GreetProto";

service GreeterService {
  rpc sayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

This file declares the overall structure and contract of the gRPC service. It defines a service named GreeterService that exposes a single RPC method called sayHello, which clients can call remotely. The method accepts a request message of type HelloRequest, which contains a single string field named name to capture the user’s input. It returns a response message of type HelloResponse, which includes a string field called message that typically carries the server’s greeting or acknowledgment. This setup establishes a simple yet complete communication pattern between a client and server using gRPC.

2.3 Auto-Generating gRPC Stubs and Messages

Once the project is built, the protobuf-maven-plugin will generate the Java classes automatically:

  • GreeterServiceGrpc.java: Contains service stubs for client/server
  • HelloRequest.java and HelloResponse.java: Plain Old Java Objects (POJOs) for messages

These classes abstract away serialization and provide a Java-friendly interface for working with gRPC.

2.4 Creating the Service Logic

You need to implement the service defined in the proto file. Extend the base class generated for your gRPC service and annotate it with @GrpcService so Spring Boot detects it.

package com.example.grpc;

import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;

@GrpcService
public class GreeterServiceImpl extends GreeterServiceGrpc.GreeterServiceImplBase {

  @Override
  public void sayHello(HelloRequest request, StreamObserver<HelloResponse> responseObserver) {
    String name = request.getName();
    String greeting = "Hello, " + name + "!";

    HelloResponse response = HelloResponse.newBuilder()
        .setMessage(greeting)
        .build();

    responseObserver.onNext(response);
    responseObserver.onCompleted();
  }
}

This class is a gRPC service implementation annotated with @GrpcService, allowing Spring Boot to detect and register it as a gRPC server bean. The class GreeterServiceImpl extends the auto-generated base class GreeterServiceGrpc.GreeterServiceImplBase, which provides an interface for implementing the service methods defined in the .proto file. The sayHello method is overridden to handle incoming RPC calls. It receives a HelloRequest object, extracts the name field, constructs a personalized greeting message, and wraps it in a HelloResponse object. The response is then sent back to the client using responseObserver.onNext(), and the call is marked as complete with responseObserver.onCompleted(). This implementation demonstrates how to process a unary gRPC request and send back a simple string response.

2.5 Starting and Validating the Server

Once the service is implemented, you need a Spring Boot application class to run the server.

2.5.1 Spring Boot Main Class

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GrpcServerApplication {
  public static void main(String[] args) {
    SpringApplication.run(GrpcServerApplication.class, args);
  }
}

This class serves as the entry point for the Spring Boot application and is annotated with @SpringBootApplication, which enables component scanning, auto-configuration, and configuration properties support. The class GrpcServerApplication contains the main method, which calls SpringApplication.run() to bootstrap the application. When the application starts, Spring Boot automatically initializes all configured beans, including the gRPC server components defined with @GrpcService. This setup allows the gRPC service to start listening for incoming requests on the configured port without any additional server configuration code.

2.5.2 Test Client

You can write a basic Java client to test the service without using Spring.

package com.example.grpc;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;

public class GrpcClient {

  public static void main(String[] args) {
    ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 9090)
        .usePlaintext()
        .build();

    GreeterServiceGrpc.GreeterServiceBlockingStub stub = GreeterServiceGrpc.newBlockingStub(channel);

    HelloRequest request = HelloRequest.newBuilder()
        .setName("Yatin")
        .build();

    HelloResponse response = stub.sayHello(request);
    System.out.println("Response: " + response.getMessage());

    channel.shutdown();
  }
}

This class defines a simple standalone gRPC client in Java that connects to a gRPC server running on localhost at port 9090. It starts by creating a ManagedChannel using ManagedChannelBuilder and configures it to use plaintext communication (without SSL/TLS). Then, it creates a blocking stub from the auto-generated GreeterServiceGrpc class, which is used to call the sayHello method synchronously. A HelloRequest object is built by setting the name field to Yatin, and this request is sent to the server through the stub. The client receives a HelloResponse from the server, extracts the message, and prints it to the console. Finally, the channel is gracefully shut down to release resources.

2.5.2.1 Output

To start the server, build the project using mvn clean install (or your preferred build tool), then run the application using your IDE’s run option or the command java -jar target/your-app-name.jar. Make sure the greet.proto file is compiled, and the generated classes are present before launching.

Response: Hello, Yatin!

The expected output confirms that the gRPC client has successfully communicated with the server, sent the name “Yatin” as part of the request, and received a valid response. When the server processes the request, it constructs a greeting message by appending the provided name to the word “Hello” and returns it in the HelloResponse. As a result, the client prints the message Response: Hello, Yatin! to the console, indicating that the entire gRPC flow—from client request to server response—was completed successfully.

3. Conclusion

Spring gRPC simplifies the integration of gRPC services into Spring Boot applications. By leveraging .proto files, developers can define clear service contracts and ensure consistency between client and server implementations. This guide walked you through setting up the project, defining and compiling proto files, implementing the service, running the server, and testing it with a basic client.

Yatin Batra

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button