An open API service indexing awesome lists of open source software.

https://github.com/linux-china/reactive-grpc-spring-boot-starter

Spring Boot Starter for Reactive gRPC
https://github.com/linux-china/reactive-grpc-spring-boot-starter

grpc reactive reactor rxjava2 spring-boot

Last synced: 12 months ago
JSON representation

Spring Boot Starter for Reactive gRPC

Awesome Lists containing this project

README

          

Spring Boot Starter Reactive gRPC
=================================
Spring Boot 2.0 starter for Reactive gRPC (https://github.com/salesforce/reactive-grpc) to bring reactive style for grpc-java.

### How to use?

* Please clone the repository and install reactive-grpc-spring-boot-starter artifact to your local Maven repository.

```
$ git clone git@github.com:linux-china/reactive-grpc-spring-boot-starter.git
$ cd reactive-grpc-spring-boot-starter
$ mvn -P release -DskipTests clean install
```

* Add dependency and repository in your pom.xml. Now reactive-grpc-spring-boot-starter hosted by jitpack
```xml

...


com.github.linux-china
reactive-grpc-spring-boot-starter
1.0.0-SNAPSHOT


```

* Add protobuf-maven-plugin with Reactor-gRPC protocPlugin included. **Attention:** proto files should be in "src/main/proto" directory

```xml



kr.motd.maven
os-maven-plugin
1.6.1




org.apache.maven.plugins
maven-compiler-plugin
3.8.0

1.8
1.8
true



org.xolstice.maven.plugins
protobuf-maven-plugin
0.6.1

com.google.protobuf:protoc:${protobuf-java.version}:exe:${os.detected.classifier}

grpc-java
io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}



reactor-grpc
com.salesforce.servicelibs
reactor-grpc
${reactive-grpc.version}
com.salesforce.reactorgrpc.ReactorGrpcGenerator






compile
compile-custom




```

* Implement Reactive Service with @ReactiveGrpcService annotation.

```java
@Service
@ReactiveGrpcService
public class ReactiveGreeterImpl extends ReactorGreeterGrpc.GreeterImplBase {
@Override
public Mono sayHello(Mono request) {
return request.map(helloRequest -> HelloReply.newBuilder().setMessage("Hello " + helloRequest.getName()).build());
}

@Override
public Mono sayHelloAgain(Mono request) {
return request.map(helloRequest -> HelloReply.newBuilder().setMessage("Hello Again " + helloRequest.getName()).build());
}
}
```

* Start you Spring application and you will get following output on your console.

```
09:40:17.366 [INFO ] o.m.s.b.r.g.ReactiveGrpcAutoConfiguration - gRPC server started on: 50051
09:40:17.379 [INFO ] o.m.s.b.r.g.ReactiveGrpcAutoConfiguration - Reactive gRPC service exposed: org.mvnsearch.spring.boot.reactive.grpc.demo.ReactiveGreeterImpl

```

* Use Evans to test gRPC service

```
$ evans src/main/proto/greeter.proto
```

### Reactive gRPC configuration
You don't need to setup anything for Reactive gRPC service.
If you want to change listen port(default is 50051), please change as following in application.properties:

```properties
grpc.reactive.port=50051
```

### FAQ

#### What's difference with gRPC Spring Boot Starter

gRPC has different starters to integration with Spring Boot, for example:

* https://github.com/yidongnan/grpc-spring-boot-starter
* https://github.com/LogNet/grpc-spring-boot-starter

The main difference is code style in these starters. If you like Reactive style, please choose Reactive gRPC.
If you think native style fine, please use starters above.

* gRPC native style:
```
//server side
public void sayHello(HelloRequest req, StreamObserver responseObserver) {
HelloReply reply = HelloReply.newBuilder().setMessage("Hello ==> " + req.getName()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
//client side
asyncStub.sayHello(HelloRequest.newBuilder().setName(name).build(), new StreamObserver() {
@Override
public void onNext(HelloReply reply) {

}

@Override
public void onError(Throwable throwable) {

}

@Override
public void onCompleted() {

}
});
```

* gRPC reactive style:
```
//server side
public Mono sayHello(Mono request) {
return request.map(helloRequest -> HelloReply.newBuilder().setMessage("Hello " + helloRequest.getName()).build());
}
//client side
Mono request = Mono.just(HelloRequest.newBuilder().setName("Jack").build());
request.as(greeter::sayHello)
.map(HelloReply::getMessage)
.subscribe(System.out::println);
```

#### Convert between DDD model(entity,value object) and Protobuf message

Please refer MapStruct to map DDD model and Protobuf message, and MapStruct 1.3 with Protobuf builder support.

#### Quick test

Please execute "mvn -DskipTests clean package" and run ReactiveGrpcDemoApplication

### Todo

* Publish artifact to Maven repository
* Actuator endpoint to output proto sources
* SSL for gRPC by using certificate in Spring Boot https://github.com/grpc/grpc-java/blob/master/SECURITY.md

```
server.ssl.enabled=true
server.ssl.key-store=${user.home}/domain_certs/localhost.com/localhost.com.p12
server.ssl.key-store-type=PKCS12
server.ssl.key-store-password=changeit
```

### References

* Reactive gRPC: https://github.com/salesforce/reactive-grpc
* Project Reactor: https://projectreactor.io/
* Evans: expressive universal gRPC client https://github.com/ktr0731/evans
* MapStruct: http://mapstruct.org/