Spring Boot and gRPC - Boost your service communication
Introduction
In this article, I will describe gRPC and how you can employ it in your project. The motivation creation of gRPC The motivation behind creating gRPC was that developers and businesses require faster and more efficient solutions. The existing technologies utilize HTTP 1/1.1. The Spring Boot supports Undertow, but Tomcat requires some additional changes. It is why creators employed HTTP 2 in gRPC. This article will create another CRUD service to manage restaurant reservations.
Implementation
The first thing to do is create the proto file and describe the service contract.
syntax = "proto3";
package io.vrnsky.grpc;
import "google/protobuf/timestamp.proto";
option java_multiple_files = true;
option java_package = "io.vrnsky.grpc";
option java_outer_classname = "GrpcReservationService";
service ReservationService {
rpc create (Reservation) returns (ReservationResponse) {
}
rpc update (Reservation) returns (ReservationResponse) {
}
rpc getById (UUID) returns (ReservationResponse) {
}
rpc delete (UUID) returns (Empty) {
}
}
message Reservation {
string id = 1;
string name = 2;
string phone = 3;
google.protobuf.Timestamp desiredDateTime = 4;
bool deleted = 5;
}
message ReservationResponse {
string id = 1;
string name = 2;
string phone = 3;
google.protobuf.Timestamp desiredDateTime = 4;
bool deleted = 5;
}
message UUID {
string id = 1;
}
message Empty {
}
There are a few tricks that are simpler in classic Spring Boot Web service:
- To get an entity by ID, we have to define a new message type — UUID
- We don’t need to return something to the client for delete operations. It is the reason for the empty message.
The next step is to generate interfaces and classes. We must configure our pom.xml with the plugin, additional dependencies, and properties to achieve this.
<properties>
<java.version>17</java.version>
<protobuf.version>3.23.4</protobuf.version>
<protobuf-plugin.version>0.6.1</protobuf-plugin.version>
<grpc.version>1.58.0</grpc.version>
</properties>
...
<dependency>
<groupId>net.devh</groupId>
<artifactId>grpc-server-spring-boot-starter</artifactId>
<version>2.15.0.RELEASE</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>1.3.5</version>
<optional>true</optional>
</dependency>
...
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.7.0</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>${protobuf-plugin.version}</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier}
</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>