Spring Boot + gRPC Hello World Example
gRPC - Table of Contents
Spring Boot+ gRPC Hello World Example Spring Boot gRPC Server + C# gRPC Client Example Spring Boot 3 + gRPC - Types of gRPC Spring Boot 3 + gRPC Unary Example Spring Boot 3 + gRPC Server Streaming Example Spring Boot 3 + gRPC Client Streaming Example Spring Boot 3 + gRPC Bidirectional Streaming Example Spring Boot + gRPC Deadline Example Spring Boot + gRPC Error Handling Example Spring Boot + gRPC Error Handling - Using Trailer Metadata Spring Boot + gRPC Error Handling - Global Exception Handler Using GrpcAdvice
Video
This tutorial is explained in the below Youtube Video.What is gRPC
gRPC, short for Google Remote Procedure Call, is a high-performance open-source framework developed by Google. It facilitates communication between client and server applications, allowing them to call methods on each other as if they were making local function calls.
Before we can understand the benefits of gRPC we need to understand the drawbacks of technologies used before gRPC.
Remote Procedure Call(RPC)
Remote Procedure Call (RPC) is a communication protocol used to enable inter-process communication between different systems. However, RPC has some disadvantages that limited its effectiveness. One major drawback is its tight coupling with specific programming languages and platforms. For example in Java applications makes use of Java RMI(Remote Method Invocation) for developing the required code skeletons and stubs. While .NET makes use of .NET Remoting for the same.
There is no RPC standard contract - Interface Definition Language (IDL), i.e. what functionality is to be implemented between the Client and Server.
Representational State Transfer (REST)
REST is another industry standard which is used widely. REST is language agnostic but has a limited set of primary 'function' callsHTTP Verb | CRUD |
---|---|
POST | Create |
GET | Read |
PUT | Update/Replace |
PATCH | Update/Modify |
DELETE | Delete |
The other major advantage of gRPC is that REST uses HTTP/1.1 while gRPC makes use of HTTP/2. HTTP/2 allows for lower latency (faster) connections that can take advantage of a single connection from client to server. HTTP/2 also supports bidirectional connectivity and asynchronous connectivity. So it is possible for the server to efficiently make contact with client to send messages
Advantages of gRPC
- gRPC facilitates faster and more efficient communication between systems or services.
- It allows for streamlined and quick exchange of data.
- gRPC supports multiple programming languages, making it developer-friendly.
- Built-in support for authentication and load balancing enhances security and scalability.
- Efficient and secure communication through gRPC enhances performance and user experience in software projects.
- gRPC utilizes Protocol Buffers, a language-agnostic binary serialization format, which enables efficient and compact communication over the network. This results in improved performance and reduced bandwidth consumption.
Implementation
We will be creating a gRPC Server that exposes an endpoint called GetBook. By utilizing the gRPC Client, we will consume this GetBook endpoint.
Spring Boot + gRPC Server Example
The maven project we will be creating is as follows -
Next we will be defining the proto file. A proto file in gRPC is a special type of file that helps define the structure and communication between different software components. It acts like a blueprint for creating and interacting with these components. In this specific example, the proto file contains information about a book request and response, along with a service called BookService that allows you to retrieve a book by sending a request and receiving a response.
syntax = "proto3"; import "constants/util.proto"; option java_multiple_files = true; option java_package = "com.javainuse.employee"; message BookRequest{ string book_id = 1; } message BookResponse { string book_id = 1; string name = 2; constants.Type type = 3; } service BookService { rpc getBook(BookRequest) returns (BookResponse) {}; }
syntax = "proto3"; package constants; option java_multiple_files = true; option java_package = "com.javainuse.constants"; enum Type { FANTASY = 0; AUTOBIOGRAPHY = 1; HISTORY = 2; }In pom.xml example we define the required gRPC dependencies. Also we make use of a maven plugin, called protobuf-maven-plugin. This is used to compile Protocol Buffers (protobuf) files in a Maven project. Protocol Buffers is a language-agnostic data serialization format. This plugin takes the protobuf files (defined in the specified <protoSourceRoot> directory) and generates Java code from them. This code enables communication between different components of the application, making it easier to exchange data in a structured and efficient manner.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javainuse</groupId> <artifactId>Spring-Boot-GRPC-Server-Example</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.7</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <java.version>1.8</java.version> <protobuf.version>3.17.3</protobuf.version> <protobuf-plugin.version>0.6.1</protobuf-plugin.version> <grpc.version>1.42.1</grpc.version> </properties> <dependencies> <dependency> <groupId>net.devh</groupId> <artifactId>grpc-server-spring-boot-starter</artifactId> <version>2.9.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>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.2</version> </dependency> </dependencies> <build> <extensions> <extension> <groupId>kr.motd.maven</groupId> <artifactId>os-maven-plugin</artifactId> <version>1.7.0</version> </extension> </extensions> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.xolstice.maven.plugins</groupId> <artifactId>protobuf-maven-plugin</artifactId> <version>0.5.1</version> <configuration> <protocArtifact> com.google.protobuf:protoc:3.6.1:exe: </protocArtifact> <pluginId>grpc-java</pluginId> <pluginArtifact> io.grpc:protoc-gen-grpc-java:1.22.1:exe: </pluginArtifact> <protoSourceRoot> ${basedir}/src/main/proto/ </protoSourceRoot> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>compile-custom</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>