Using a gRPC client in Lagom

Akka gRPC has special support to allow for seamless configuration of generated clients in Play. To enable this, you need first to enable the gRPC plugin as described in the client docs and then add a source generator in build.sbt:

Scala
akkaGrpcExtraGenerators += akka.grpc.gen.scaladsl.play.PlayScalaClientCodeGenerator
Java
akkaGrpcExtraGenerators += akka.grpc.gen.javadsl.play.PlayJavaClientCodeGenerator

This will generate a Play module that provides all generated clients for injection. The module must be enabled by adding it to the enabled modules in the application.conf.

You can then put the following helloworld.proto file in app/protobuf:

Scala
syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.lightbend.lagom.scaladsl.grpc.interop";
option java_outer_classname = "HelloWorldProto";

package helloworld;

service GreeterService {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}
Full source at GitHub
Java
syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.lightbend.lagom.javadsl.grpc.interop";
option java_outer_classname = "HelloWorldProto";

package helloworld;

service GreeterService {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
    string name = 1;
}

message HelloReply {
    string message = 1;
}
Full source at GitHub

For Scala, you first need to provide a GrpcClientSettings object in your cake:

Scala
// Implicits required by GrpcClientSettings
private implicit val dispatcher: ExecutionContextExecutor = actorSystem.dispatcher
private implicit val sys: ActorSystem                     = actorSystem

private lazy val settings = GrpcClientSettings
  .usingServiceDiscovery(GreeterService.name)
  .withServicePortName("https")
  // response timeout
  .withDeadline(Duration.ofSeconds(5))
  // use a small reconnectionAttempts value to
  // cause a client reload in case of failure
  .withConnectionAttempts(5)
Full source at GitHub

And then instantiate the client using the settings above:

Scala
lazy val greeterServiceClient: GreeterServiceClient = GreeterServiceClient(settings)
Full source at GitHub

For Java, the module file is generated in com.lightbend.lagom.javadsl.grpc.interop.AkkaGrpcClientModule by default, which corresponds to the default value of flat_package for JavaScala. You can read more about this in Services.

The exact package of the module will be based on the package the proto files are generated in, configured through the java_package option in the proto-file (if there are multiple different gRPC generated clients the module will be generated in the longest package prefix shared between the clients).

To hook it into Play, in application.conf:

Java
// enable the client module
play.modules.enabled += com.lightbend.lagom.javadsl.grpc.interop.AkkaGrpcClientModule
Full source at GitHub

The clients are configured with entries under akka.grpc.client named after the client (gRPC package name dot ServiceName), again, in application.conf:

Java
akka.grpc.client {
  "helloworld.GreeterService" {
    service-discovery {
      mechanism = "com.lightbend.lagom.internal.registry.DevModeSimpleServiceDiscovery"
      service-name = "helloworld.GreeterService"
      port-name = "https"
    }

    deadline = 5s
    connection-attempts = 5
  }
}
Full source at GitHub

See Client Configuration for more information on the available options. If the configuration is not present for that client and it is used by some other component, the application start will fail with an exception when injecting the client (see #271).

At this point the client is then available to be injected as any other regular object.

Found an error in this documentation? The source code for this page can be found here. Please feel free to edit and contribute a pull request.