Spring boot starter for gRPC framework.
Auto-configures and runs the embedded gRPC server with @GRpcService-enabled beans as part of spring-boot application.
repositories {
jcenter()
// maven { url "http://oss.jfrog.org/oss-snapshot-local" } //for snashot builds
}
dependencies {
compile('org.lognet:grpc-spring-boot-starter:1.0.0')
}
Note
|
If you are using protobuf version lower than 3.0.0 , please use org.lognet:grpc-spring-boot-starter:0.0.3
|
-
Start by generating stub and server interface(s) from your
.proto
file(s). -
Annotate your server interface implementation(s) with
@org.lognet.springboot.grpc.GRpcService
-
Optionally configure the server port in your
application.yml/properties
. Default port is6565
grpc: port : 6565
In the 'grpc-spring-boot-starter-demo' project you can find fully functional example with integration test.
The service definition from .proto
file looks like this :
service Greeter {
rpc SayHello ( HelloRequest) returns ( HelloReply) {}
}
Note the generated io.grpc.examples.GreeterGrpc.GreeterImplBase
class that extends io.grpc.BindableService
.(The generated classes were intentionally committed for demo purposes).
All you need to do is to annotate your service implementation with @org.lognet.springboot.grpc.GRpcService
@GRpcService
public static class GreeterService extends GreeterGrpc.GreeterImplBase{
@Override
public void sayHello(GreeterOuterClass.HelloRequest request, StreamObserver<GreeterOuterClass.HelloReply> responseObserver) {
final GreeterOuterClass.HelloReply.Builder replyBuilder = GreeterOuterClass.HelloReply.newBuilder().setMessage("Hello " + request.getName());
responseObserver.onNext(replyBuilder.build());
responseObserver.onCompleted();
}
}
The starter supports the registration of two kinds of interceptors: Global and Per Service.
In both cases the interceptor has to implement io.grpc.ServerInterceptor
interface.
-
Per service
@GRpcService(interceptors = { LogInterceptor.class })
public class GreeterService extends GreeterGrpc.GreeterImplBase{
// ommited
}
LogInterceptor
will be instantiated via spring factory if there is bean of type LogInterceptor
, or via no-args constructor otherwise.
-
Global
@GRpcGlobalInterceptor
public class MyInterceptor implements ServerInterceptor{
// ommited
}
The annotation on java config factory method is also supported :
@Configuration
public class MyConfig{
@Bean
@GRpcGlobalInterceptor
public ServerInterceptor globalInterceptor(){
return new ServerInterceptor(){
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
// your logic here
return next.startCall(call, headers);
}
};
}
}
The particular service also has the opportunity to disable the global interceptors :
@GRpcService(applyGlobalInterceptors = false)
public class GreeterService extends GreeterGrpc.GreeterImplBase{
// ommited
}
To intercept the io.grpc.ServerBuilder
instance used to build the io.grpc.Server
, you can add bean that inherits from org.lognet.springboot.grpc.GRpcServerBuilderConfigurer
to your context and override the configure
method.
By the time of invocation of configure
method, all discovered services, including theirs interceptors, had been added to the passed builder.
In your implementation of configure
method, you can continue with passed instance of ServerBuilder
by adding your configuration:
@Component
public class MyGRpcServerBuilderConfigurer extends GRpcServerBuilderConfigurer(){
@Override
public ServerBuilder<?> configure(ServerBuilder<?> serverBuilder){
return serverBuilder
.executor(YOUR EXECUTOR INSTANCE)
.compressorRegistry(YOUR COMPRESSION REGISTRY)
.decompressorRegistry(YOUR DECOMPRESSION REGISTRY)
.useTransportSecurity(YOUR TRANSPORT SECURITY SETTINGS);
}
};
}
or return completely new instance of ServerBuilder
:
@Component
public class MyGRpcServerBuilderConfigurer extends GRpcServerBuilderConfigurer(){
@Override
public ServerBuilder<?> configure(ServerBuilder<?> serverBuilder){
return ServerBuilder.forPort(YOUR PORT)
.executor(YOUR EXECUTOR INSTANCE)
.compressorRegistry(YOUR COMPRESSION REGISTRY)
.decompressorRegistry(YOUR DECOMPRESSION REGISTRY)
.useTransportSecurity(YOUR TRANSPORT SECURITY SETTINGS);
}
};
}
Note
|
In this case you should also take care about adding the services to the fresh instance of ServerBuilder
|