Contents

Overview

gRPC scope is temporarily smaller in Helidon, please follow issue https://github.com/helidon-io/helidon/issues/5418 As this is still work in progress, the WebServer gRPC module is release in preview mode, as we may introduce backward incompatible changes to our APIs, so we can re-introduce features.

The Helidon gRPC server provides a framework for creating gRPC applications. While it allows you to deploy any standard gRPC service that implements io.grpc.BindableService interface, including services generated from the Protobuf IDL files (and even allows you to customize them to a certain extent), using Helidon gRPC framework to implement your services has a number of benefits:

  • It allows you to define both HTTP and gRPC services using a similar programming model, simplifying the learning curve for developers.

  • It provides a number of helper methods that make service implementation significantly simpler.

  • It allows you to run gRPC and HTTP endpoints on the same WebServer, and even on the same port.

Maven Coordinates

To enable gRPC Server add the following dependency to your project’s pom.xml (see Managing Dependencies).

<dependency>
    <groupId>io.helidon.webserver</groupId>
    <artifactId>helidon-webserver-grpc</artifactId>
</dependency>
Copied

Usage

gRPC Server Routing

Unlike the HTTP server, which allows you to route requests based on path expression and the HTTP verb, the gRPC server always routes requests based on the service and method name. This makes routing configuration somewhat simpler — all you need to do is register your services:

private static GrpcRouting.Builder createRouting(Config config) {
    return GrpcRouting.builder()
            .service(new GreetService(config)) 
            .service(new EchoService())        
            .service(new MathService())        
            .unary(Strings.getDescriptor(),    
                   "StringService",
                   "Upper",
                   Main::grpcUpper);
}
Copied
  • Register GreetService instance.
  • Register EchoService instance.
  • Register MathService instance.
  • Register a custom unary gRPC route

Both "standard" gRPC services that implement io.grpc.BindableService interface (typically implemented by extending the generated server-side stub and overriding its methods), and Helidon gRPC services that implement io.helidon.grpc.server.GrpcService interface can be registered. The difference is that Helidon gRPC services allow you to customize behavior down to the method level, and provide a number of useful helper methods that make service implementation easier, as we’ll see in a moment.

Customizing Service Definitions

When registering a service, regardless of its type, you can customize its descriptor by providing an instance of ServerServiceDefinition to service method.

Service Implementation

Implementing Protobuf Services

In order to implement Protobuf-based service, you would follow the official instructions on the gRPC website, which boil down to the following:

Define the Service IDL

For this example, we will re-implement the EchoService above as a Protobuf service in echo.proto file.

syntax = "proto3";
option java_package = "org.example.services.echo";

service EchoService {
  rpc Echo (EchoRequest) returns (EchoResponse) {}
}

message EchoRequest {
  string message = 1;
}

message EchoResponse {
  string message = 1;
}
Copied

Based on this IDL, the gRPC compiler will generate message classes (EchoRequest and EchoResponse), client stubs that can be used to make RPC calls to the server, as well as the base class for the server-side service implementation.

We can ignore the last one, and implement the service using Helidon gRPC framework instead.

Implement the Service

The service implementation will be very similar to our original implementation:

class EchoService implements GrpcService {
    @Override
    public Descriptors.FileDescriptor proto() {
        return Echo.getDescriptor(); 
    }

    @Override
    public void update(Routing routing) {
        routing.unary("Echo", this::echo); 
    }

    /**
     * Echo the message back to the caller.
     *
     * @param request  the echo request containing the message to echo
     * @param observer the response observer
     */
    public void echo(Echo.EchoRequest request, StreamObserver<Echo.EchoResponse> observer) {  
        String message = request.getMessage();  
        Echo.EchoResponse response = Echo.EchoResponse.newBuilder().setMessage(message).build();  
        complete(observer, response);  
    }
}
Copied
  • Specify the proto descriptor in order to provide necessary type information and enable Protobuf marshalling.
  • Define unary method Echo and map it to the this::echo handler.
  • Create a handler for the Echo method, using Protobuf message types for request and response.
  • Extract message string from the request.
  • Create the response containing extracted message.
  • Send the response back to the client by completing response observer.

The complete method shown in the example above is just one of many helper methods available in the ResponseHelper class. See the full list here.

Configuration

Configure the gRPC server using the Helidon configuration framework, either programmatically or via a configuration file.

Configuring the gRPC Server in the Code

Currently, we do not have any custom configuration options for gRPC protocol.

To register a routing with Helidon WebServer, simply add the routing to the listener (WebServer configuration is itself the default listener configuration)

WebServer.builder()
        .port(8080)
        .routing(httpRouting -> httpRouting.get("/greet", (req, res) -> res.send("Hi!"))) 
        .addRouting(GrpcRouting.builder()  
                            .unary(Strings.getDescriptor(),
                                   "StringService",
                                   "Upper",
                                   Main::grpcUpper))
        .build()
        .start();
Copied
  • Configure HTTP routing of the server
  • Configure gRPC routing of the server

Examples

The following gRPC examples for Helidon SE are available: