Application Development

Kotlin, meet gRPC: a new open-source project for modern apps

GCP AppDev.jpg

As developers work to modernize applications, they need foundational tools that are simple and scalable. gRPC is a high-performance, open-source, universal RPC framework originally developed here at Google that developers are adopting in tremendous numbers, helping them connect services more easily and reliably. Paired with Kotlin, the second most popular JVM-based programming language in the world, developers can build everything from mobile apps to cloud microservices. To help, we've open-sourced gRPC Kotlin for the JVM, allowing you to use gRPC with your Kotlin projects.

Building on top of the Java API for gRPC, this new project provides Kotlin-friendly gRPC classes, including support for Kotlin coroutines. 

Let’s take a look at an example. First we need a proto definition, which is a language agnostic definition of a service interface, like:

  message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

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

(Full hello_world.proto source)

After running the gRPC Kotlin generator, you can implement the service as a coroutine (suspend fun):

  private class HelloWorldService: GreeterCoroutineImplBase() {
 override suspend fun sayHello(request: HelloRequest) = HelloReply
     .newBuilder()
     .setMessage("Hello ${request.name}")
     .build()
}

(Full HelloWorldServer.kt source)

And call it asynchronously from a client:

  val request = HelloRequest.newBuilder().setName(name).build()
val response = async { stub.sayHello(request) }
println("Received: ${response.await().message}")

(Full HelloWorldClient.kt source)

Coroutines are a natural fit for asynchronous programming, and gRPC for Kotlin makes it easy!

gRPC Kotlin, meet Cloud Run

You can use the gRPC Kotlin project in all kinds of ways, but one that we are particularly excited about is the ability to create services that run on Cloud Run, a fully managed serverless compute platform that automatically scales containers. We recently announced that Cloud Run supports unary gRPC; with today’s announcement, you can now deploy unary gRPC Kotlin services on Cloud Run as well. If you want to give this a try, check out the gRPC Cloud Run example for Kotlin.

Streaming with gRPC Kotlin Flows

In execution environments where streaming gRPC is supported, you can use streaming RPCs via Kotlin’s new asynchronous Flow API. This adapts the concept of Reactive Streams to Kotlin coroutines with an intuitive and clean API. If you’re not familiar with Kotlin Flows, we recommend watching Roman Elizarov’s talk on them from KotlinConf 2019. Here’s an example using the Flow API with gRPC Kotlin to consume a server stream, starting with the proto:

  service Greeter {
  rpc SayHelloStream (HelloRequest) returns (stream HelloReply) {}
}

(Full hello_world.proto source)

The server handles the request and returns a Flow that emits a HelloReply once per second:

  private class HelloWorldService:
  GreeterGrpcKt.GreeterCoroutineImplBase() {
  override fun sayHelloStream(req: HelloRequest): Flow<HelloReply> = flow {
    while (true) {
      delay(1000)
      emit(HelloReply.newBuilder().setMessage("Hello, ${req.name}").build())
    }
  }
}

(Full HelloWorldServer.kt source)

The client makes a request and then prints each HelloReply as it arrives:

  val req = HelloRequest.newBuilder().setName(name).build()
stub.sayHelloStream(req).collect { response ->
  println(response.message)
}

(Full HelloWorldClient.kt source)

Adding gRPC Kotlin to your project

The gRPC Kotlin generator configurations need to be added along with the grpc-java configurations. Using the Kotlin protoc generator is as easy as modifying your build to use the grpc-kotlin libraries. For example, in a Gradle build's protobuf.plugins settings, you would add the line:

  grpckt {
    artifact = "io.grpc:protoc-gen-grpc-kotlin:0.1.1"
}

And add a dependency on the grpc-kotlin-stub library:

  implementation "io.grpc:grpc-kotlin-stub:0.1.1"

(Full build.gradle file)

For Maven builds, you will need both the grpc-java protoc plugin and gRPC Kotlin:

  <!-- In the protobuf-maven-plugin -->
<execution>
    <id>grpc-kotlin</id>
    <goals>
        <goal>compile</goal>
        <goal>compile-custom</goal>
    </goals>
    <configuration>
        <pluginId>grpc-kotlin</pluginId>
         <pluginArtifact>io.grpc:protoc-gen-grpc-kotlin:${grpc.kotlin.version}:exe:${os.detected.classifier}</pluginArtifact>
    </configuration>
</execution>

And the grpc-kotlin-stub Maven dependency:

  <dependency>
    <groupId>io.grpc</groupId>
    <artifactId>grpc-kotlin-stub</artifactId>
    <version>0.1.1</version>
</dependency>

(Full pom.xml file)

Try the gRPC Kotlin 0.1.1 release

Together, gRPC and Kotlin have the potential to improve how you develop mobile and cloud-native applications, and we’re excited for you to give the project a spin and let us know how things go. Please note that version 0.1.1 is the initial release of this project, so be sure to check for new releases. And if you run across any issues, file them on the gRPC Kotlin open source project.


With contributions from: Ray Tsang, David Winer, Patrice Chalin, Tyson Henning, Kevin Bierhoff, and James Ward.