CtrlK
BlogDocsLog inGet started
Tessl Logo

finkel/spring-grpc

Spring gRPC reference documentation covering server, client, security, and configuration

92

2.19x
Quality

Pending

Does it follow best practices?

Impact

92%

2.19x

Average score across 3 eval scenarios

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

getting-started.mddocs/

Getting Started

Build a Spring Boot gRPC server and client. Spring gRPC 1.0.x targets Spring Boot 4.1.x.

1. Generate a Project

Use Spring Initializr with the gRPC dependency.

2. Define the Proto Service

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; }

3. Generate Stubs

./mvnw clean package
# or
./gradlew build

Generated sources:

BuildPath
Maventarget/generated-sources/protobuf/grpc-java, target/generated-sources/protobuf/java
Gradlebuild/generated/source/proto/main/grpc, build/generated/source/proto/main/java

Mark as source roots in your IDE.

4. Implement the Service

@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();
    }
}

5. Run

./mvnw spring-boot:run
# or
./gradlew bootRun

The gRPC server starts on port 9090 by default.

6. Test with grpcurl

grpcurl -d '{"name":"Hi"}' -plaintext localhost:9090 Simple.SayHello
{ "message": "Hello ==> Hi" }

Dependency Management

Milestone / Snapshot Repositories

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' }
}

BOM

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")
}

Minimal Client

@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:9090

Native Images

Native images are supported for both servers and clients. Use the standard Spring Boot native image process for Maven or Gradle.

docs

client.md

getting-started.md

index.md

server.md

tile.json