Interceptors

Helidon gRPC allows you to configure standard `io.grpc.ServerInterceptor`s.

For example, you could implement an interceptor that logs each RPC call:

class LoggingInterceptor implements ServerInterceptor {   

    private static final Logger LOG = Logger.getLogger(LoggingInterceptor.class.getName());

    @Override
    public <ReqT, ResT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, ResT> call,
                                                                 Metadata metadata,
                                                                 ServerCallHandler<ReqT, ResT> handler) {

        LOG.info(() -> "CALL: " + call.getMethodDescriptor());  
        return handler.startCall(call, metadata);               
    }
}
Copied
  • Implement io.grpc.ServerInterceptor
  • Implement the logging logic
  • Start intercepted call

Registering Interceptors

You can register interceptors globally, in which case they will be applied to all methods of all services, by simply adding them to the GrpcRouting instance:

private static GrpcRouting createRouting(Config config) {
    return GrpcRouting.builder()
            .intercept(new LoggingInterceptor())  
            .register(new GreetService(config))
            .register(new EchoService())
            .build();
}
Copied
  • Adds LoggingInterceptor to all methods of GreetService and EchoService

You can also register an interceptor for a specific service, either by implementing GrpcService.update method:

public class MyService implements GrpcService {

    @Override
    public void update(ServiceDescriptor.Rules rules) {
        rules.intercept(new LoggingInterceptor())   
                .unary("MyMethod", this::myMethod);
    }

    private <ReqT, ResT> void myMethod(ReqT request, StreamObserver<ResT> observer) {
        // do something
    }
}
Copied
  • Adds LoggingInterceptor to all methods of MyService

Or by configuring ServiceDescriptor externally, when creating GrpcRouting, which allows you to add interceptors to plain io.grpc.BindableService services as well:

private static GrpcRouting createRouting(Config config) {
    return GrpcRouting.builder()
            .register(new GreetService(config), cfg -> cfg.intercept(new LoggingInterceptor()))  
            .register(new EchoService())
            .build();
}
Copied
  • Adds LoggingInterceptor to all methods of GreetService only

Finally, you can also register an interceptor at the method level:

public class MyService implements GrpcService {

    @Override
    public void update(ServiceDescriptor.Rules rules) {
        rules.unary("MyMethod",
                     this::myMethod,
                     cfg -> cfg.intercept(new LoggingInterceptor()));  
    }

    private <ReqT, ResT> void myMethod(ReqT request, StreamObserver<ResT> observer) {
        // do something
    }
}
Copied
  • Adds LoggingInterceptor to MyService::MyMethod only