First of all, when you are trying to implement a gRPC
communication, so you have probably more than one service(project) that you want them to be communicated.
I myself implemented a separate project grpc-interface
and added it to the Git repository, then I could add this project as a submodule
using the Git-submodule
feature to my services(projects) that I needed to be communicated.
I implemented my grpc-interface
as below:
here is my build.gradle
file, you can find the Maven
version with a little R&D easily too:
buildscript {
ext {
protobufVersion = '3.19.1'
protobufPluginVersion = '0.8.18'
grpcVersion = '1.44.0'
protobufJava = '3.19.4'
}
}
plugins {
id 'java'
id 'com.google.protobuf' version "${protobufPluginVersion}"
}
group = 'com.ada.bourse.grpc-interface'
version = '0.0.1-SNAPSHOT'
dependencies {
implementation "io.grpc:grpc-protobuf:${grpcVersion}"
implementation "io.grpc:grpc-stub:${grpcVersion}"
implementation "com.google.protobuf:protobuf-java:${protobufJava}"
compileOnly 'jakarta.annotation:jakarta.annotation-api:1.3.5' // Java 9+ compatibility - Do NOT update to 2.0.0
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:${protobufVersion}"
}
generatedFilesBaseDir = "$projectDir/src/generated"
clean {
delete generatedFilesBaseDir
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}"
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
repositories {
mavenCentral()
}
Then I created a .proto
file to introduce my service and its request and response model:
syntax = "proto3";
package com.ada.bourse.grpc.accounting;
option java_multiple_files = true;
option java_package = "com.ada.bourse.grpc.accounting";
service AccountingService {
rpc userBalance(UserBalanceRequest) returns (UserBalanceResponse) {
}
}
message UserBalanceRequest {
string username = 1;
}
message UserBalanceResponse {
double balance = 1;
}
After this step, you need to compile the project and it will result in creating a package with a generated
name beside your main
package.
Then, as I said if you put this project in a repository like Git, you need to add it to your projects using the Git-submodule
feature, of course, there are other ways to add it to your projects and Git-submodule
is not a MUST!
just consider that, after adding this module to your projects, before running and compiling the main project you need to compile your grpc-interface
so that your project can use generated files that is like:

Now I have two services, named wealth-manager
and accounting
that I want to be communicated, as you saw in my .proto
file, I want my wealth
service to request and check the user balance from my accounting
service.
in my wealth
service I did as below in my Service layer:
@Service
public class RestrictionServiceImpl implements IRestrictionService {
@GrpcClient("accounting-service")
private AccountingServiceGrpc.AccountingServiceBlockingStub accountingServiceStub;
private void checkUserBalanceForBuyOrder(RestrictionFilterCriteria filterCriteria) {
Double userBalance = getUserBalanceFromAccountingServiceGrpc(filterCriteria.getUsername());
if (userBalance < filterCriteria.getAmount() * filterCriteria.getPrice())
throw new RestrictionException(new BaseException.ErrorDetail()
.setLoc("balance")
.setType(Constant.INSUFFICIENT_BALANCE));
}
private Double getUserBalanceFromAccountingServiceGrpc(String username) throws GrpcConnectionException {
UserBalanceRequest request = UserBalanceRequest.newBuilder()
.setUsername(username)
.build();
return accountingServiceStub.userBalance(request).getBalance();
}
}
And in my accounting
service I have created class for grpc
services as below:
@GrpcService
public class AccountingServiceGRPC extends AccountingServiceGrpc.AccountingServiceImplBase {
private final IUserAccountService userAccountService;
public AccountingServiceGRPC(IUserAccountService userAccountService) {
this.userAccountService = userAccountService;
}
@Override
public void userBalance(UserBalanceRequest request, StreamObserver<UserBalanceResponse> responseObserver) {
UserBalanceResponse balanceResponse = UserBalanceResponse.newBuilder()
.setBalance(userAccountService.getUserBalance(request.getUsername()))
.build();
responseObserver.onNext(balanceResponse);
responseObserver.onCompleted();
}
}
I myself have argued with gRPC
a lot until I could resolve it, hope my experience with it helps you to resolve yours too.