To integrate Spring Boot with your gRPC service using Gradle, Java, and Avro
To integrate Spring Boot with your gRPC service using Gradle, Java, and Avro, we’ll modify the setup to include Spring Boot dependencies. The goal is to run the gRPC service inside a Spring Boot application, making it easier to manage configurations, beans, and dependencies.
Below is a complete guide to adding Spring Boot to your existing gRPC + Avro project.
Updated Project Structure
grpc-avro-user-service/
│
├── src/
│ ├── main/
│ │ ├── avro/
│ │ │ └── user.avsc
│ │ ├── java/
│ │ │ ├── proto/
│ │ │ │ └── UserService.proto
│ │ │ └── com/example/userservice/
│ │ │ ├── UserServiceImpl.java
│ │ │ ├── GrpcServerConfig.java
│ │ │ └── Application.java
├── build.gradle.kts
└── settings.gradle.kts
Step 1: Update build.gradle.kts
to Add Spring Boot Dependencies
Here’s the updated build.gradle.kts
to include Spring Boot along with gRPC and Avro:
plugins {
java
id("com.google.protobuf") version "0.9.1"
id("com.github.davidmc24.gradle.plugin.avro") version "1.3.0"
id("org.springframework.boot") version "3.1.4"
id("io.spring.dependency-management") version "1.1.2"
}
group = "com.example"
version = "1.0-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
dependencies {
// Spring Boot Starter
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.springframework.boot:spring-boot-starter-web")
// gRPC dependencies
implementation("io.grpc:grpc-netty-shaded:1.56.0")
implementation("io.grpc:grpc-protobuf:1.56.0")
implementation("io.grpc:grpc-stub:1.56.0")
// Avro dependencies
implementation("org.apache.avro:avro:1.11.0")
compileOnly("org.apache.avro:avro-compiler:1.11.0")
// Testing dependencies
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("junit:junit:4.13.2")
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.22.0"
}
plugins {
create("grpc") {
artifact = "io.grpc:protoc-gen-grpc-java:1.56.0"
}
}
generateProtoTasks {
all().forEach { task ->
task.plugins {
create("grpc")
}
}
}
}
avro {
sourceDirectories.from(file("src/main/avro"))
outputCharacterEncoding.set("UTF-8")
}
tasks.test {
useJUnitPlatform()
}
Explanation of Changes:
Spring Boot Plugin:
- Added the
org.springframework.boot
andio.spring.dependency-management
plugins.
- Added the
Spring Boot Dependencies:
- Added
spring-boot-starter
for the core Spring Boot features. - Added
spring-boot-starter-web
to enable REST capabilities if you want to expose a REST endpoint.
- Added
Step 2: Create the Spring Boot Application Entry Point
Create a Application.java
file as the entry point for the Spring Boot application.
src/main/java/com/example/userservice/Application.java
:
package com.example.userservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
This class will serve as the entry point for the Spring Boot application. When the application starts, it will scan for beans and configurations, including your gRPC server.
Step 3: Configure the gRPC Server as a Spring Bean
We need to create a configuration class to manage the gRPC server lifecycle using Spring Boot.
Create a GrpcServerConfig.java
file to configure and manage the gRPC server.
src/main/java/com/example/userservice/GrpcServerConfig.java
:
package com.example.userservice;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
@Configuration
public class GrpcServerConfig {
@Bean
public Server grpcServer(UserServiceImpl userServiceImpl) {
return ServerBuilder.forPort(8080)
.addService(userServiceImpl)
.build();
}
}
Step 4: Modify the gRPC Service Implementation
Ensure that the gRPC service implementation is a Spring-managed component by annotating it with @Service
.
src/main/java/com/example/userservice/UserServiceImpl.java
:
package com.example.userservice;
import com.example.userservice.proto.UserRequest;
import com.example.userservice.proto.UserResponse;
import com.example.userservice.proto.UserServiceGrpc;
import io.grpc.stub.StreamObserver;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase {
@Override
public void getUser(UserRequest request, StreamObserver<UserResponse> responseObserver) {
// Dummy data
UserResponse response = UserResponse.newBuilder()
.setId(request.getId())
.setName("John Doe")
.setEmail("john.doe@example.com")
.setAge(30)
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
By adding the @Service
annotation, the UserServiceImpl
class is now managed by Spring, meaning it can be injected into other components (like our GrpcServerConfig
).
Step 5: Start the gRPC Server on Application Startup
To start the gRPC server when the Spring Boot application starts, we need to modify the Application.java
class to start the server.
Modify the Application.java
class as follows:
src/main/java/com/example/userservice/Application.java
:
package com.example.userservice;
import io.grpc.Server;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
CommandLineRunner startGrpcServer(Server grpcServer) {
return args -> {
grpcServer.start();
System.out.println("gRPC server started on port 8080");
grpcServer.awaitTermination();
};
}
}
Here, we use a CommandLineRunner
bean to start the gRPC server when the application starts.
Step 6: Run the Application
To run the Spring Boot application with the embedded gRPC server, use the following command:
./gradlew bootRun
The application will start, and the gRPC server will listen on port 8080
.
Step 7: Test the gRPC Service
You can use grpcurl
to test the gRPC service.
grpcurl -plaintext -d '{ "id": "123" }' localhost:8080 com.example.userservice.UserService/GetUser
Expected Response:
{
"id": "123",
"name": "John Doe",
"email": "john.doe@example.com",
"age": 30
}
Summary
In this guide, we integrated Spring Boot into a gRPC service with Avro. We:
- Added Spring Boot dependencies to
build.gradle.kts
. - Created a Spring Boot entry point (
Application.java
). - Configured the gRPC server as a Spring-managed bean.
- Ensured the gRPC service is a Spring-managed component.
- Started the gRPC server on application startup.
This setup combines the power of Spring Boot for dependency management and configuration with gRPC for high-performance communication. Let me know if you run into any issues or need further help!
댓글
댓글 쓰기