Spring gRPC reference documentation covering server, client, security, and configuration
92
Pending
Does it follow best practices?
Impact
92%
2.19xAverage score across 3 eval scenarios
Pending
The risk profile of this skill
Build a Spring Boot gRPC server and client. Spring gRPC 1.0.x targets Spring Boot 4.1.x.
Use Spring Initializr with the gRPC dependency.
src/main/proto/hello.proto:
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.example.proto";
option java_outer_classname = "HelloWorldProto";
service Simple {
rpc SayHello(HelloRequest) returns (HelloReply) {}
rpc StreamHello(HelloRequest) returns (stream HelloReply) {}
}
message HelloRequest { string name = 1; }
message HelloReply { string message = 1; }./mvnw clean package
# or
./gradlew buildGenerated sources:
| Build | Path |
|---|---|
| Maven | target/generated-sources/protobuf/grpc-java, target/generated-sources/protobuf/java |
| Gradle | build/generated/source/proto/main/grpc, build/generated/source/proto/main/java |
Mark as source roots in your IDE.
@Service
class GrpcServerService extends SimpleGrpc.SimpleImplBase {
private static final Log log = LogFactory.getLog(GrpcServerService.class);
@Override
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
log.info("Hello " + req.getName());
if (req.getName().startsWith("error")) {
throw new IllegalArgumentException("Bad name: " + req.getName());
}
HelloReply reply = HelloReply.newBuilder()
.setMessage("Hello ==> " + req.getName()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
@Override
public void streamHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
for (int count = 0; count < 10; count++) {
HelloReply reply = HelloReply.newBuilder()
.setMessage("Hello(" + count + ") ==> " + req.getName()).build();
responseObserver.onNext(reply);
try { Thread.sleep(1000L); }
catch (InterruptedException e) {
Thread.currentThread().interrupt();
responseObserver.onError(e);
return;
}
}
responseObserver.onCompleted();
}
}./mvnw spring-boot:run
# or
./gradlew bootRunThe gRPC server starts on port 9090 by default.
grpcurl -d '{"name":"Hi"}' -plaintext localhost:9090 Simple.SayHello{ "message": "Hello ==> Hi" }Maven:
<repositories>
<repository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
<snapshots><enabled>false</enabled></snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<url>https://repo.spring.io/snapshot</url>
<releases><enabled>false</enabled></releases>
</repository>
</repositories>Gradle:
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
maven { url 'https://repo.spring.io/snapshot' }
}Maven:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.grpc</groupId>
<artifactId>spring-grpc-dependencies</artifactId>
<version>1.1.0-M1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>Gradle:
dependencies {
implementation platform("org.springframework.grpc:spring-grpc-dependencies:1.1.0-M1")
}@Bean
SimpleGrpc.SimpleBlockingStub stub(GrpcChannelFactory channels) {
return SimpleGrpc.newBlockingStub(channels.createChannel("0.0.0.0:9090"));
}Named channel via properties:
spring.grpc.client.channels.local.address=0.0.0.0:9090@Bean
SimpleGrpc.SimpleBlockingStub stub(GrpcChannelFactory channels) {
return SimpleGrpc.newBlockingStub(channels.createChannel("local"));
}Default channel:
spring.grpc.client.default-channel.address=0.0.0.0:9090Native images are supported for both servers and clients. Use the standard Spring Boot native image process for Maven or Gradle.
evals