アプリケーション開発

Kotlin と gRPC の組み合わせ: 最新のアプリ向けの新しいオープンソース プロジェクト

GCP AppDev.jpg

※この投稿は米国時間 2020 年 4 月 17 日に、Google Cloud blog に投稿されたものの抄訳です。

アプリケーションをモダナイズする場合、シンプルかつスケーラブルな基本ツールが必要です。gRPC は元々 Google が開発した、高パフォーマンスのオープンソース ユニバーサル RPC フレームワークで、サービスを簡単かつ確実に接続できるため、数多くの開発者から絶大な支持を得ています。世界で 2 番目に人気の高い JVM ベースのプログラミング言語、Kotlin と組み合わせることで、モバイルアプリからクラウドのマイクロサービスまで、あらゆるものをビルドできます。Google では、gRPC を Kotlin プロジェクトで使用できるよう、JVM 向けにオープンソースの gRPC Kotlin を立ち上げました。

この新しいプロジェクトは、gRPC の Java API 上に構築されているので、Kotlin コルーチンをサポートするなど、Kotlin 向けの gRPC クラスを提供できます。

例を見てみましょう。protoを次のように定義します。

  message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

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

(Full hello_world.proto source)

これをコルーチン(suspend fun)として実装できます。

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

(Full HelloWorldServer.kt source)

次にクライアントから非同期で呼び出します。

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

(Full HelloWorldClient.kt source)

コルーチンは非同期プログラミングに適しているので、Kotlin の gRPC を使うことでかんたんにできます。

gRPC Kotlin と Cloud Run の組み合わせ

gRPC Kotlin プロジェクトは多種多様な使い方ができますが、中でもすばらしいのは、コンテナを自動スケーリングするフルマネージドのサーバーレス コンピューティング プラットフォームである、Cloud Run 上で実行するサービスをビルドできる機能です。Google では最近、Cloud Run が単項の gRPC をサポートできるようになったと発表しましたが、本日、単項の gRPC Kotlin サービスも Cloud Run でデプロイできるようになりました。お試しになりたい場合は、gRPC Cloud Run の Kotlin 使用例をご覧ください。(TODO: non-fork & maven central dep への更新)

gRPC Kotlin フローを使用したストリーミング

gRPC のストリームがサポートされている実行環境では、Kotlin の新しい非同期フロー API による RPC のストリームが使用できます。これは、Reactive Streams のコンセプトを採用して、直感的ですっきりした API を Kotlin のコルーチンに取り入れたものです。Kotlin フローに詳しくない場合は、KotlinConf 2019 の Roman Elizarov 氏による説明をご覧ください。フロー API と gRPC Kotlin を使って、次のような proto から始まるストリームを使用します。

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

(Full hello_world.proto source)

サーバーはリクエストを処理して、1 秒ごとに HelloReply を 1 回出力するフローを返します。

  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)

クライアントはリクエストを送信し、HelloReply が届くたびに表示します。

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

(Full HelloWorldClient.kt source)

gRPC Kotlin をプロジェクトに追加する

Kotlin protoc 生成ツールは、ビルドを変更して grpc-kotlin ライブラリを使うのと同じくらい簡単に使用できます。たとえば Gradle ビルドの protobuf.plugins 設定では、次の行を追加します。

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

次に、grpc-kotlin-stub ライブラリに依存関係を追加します。

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

(Full build.gradle file)

Maven ビルドの場合は、protoc-gen-grpc-kotlin protocPlugin も pom.xml ファイルに追加します。

  <!-- 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>

grpc-kotlin-stub の Maven 依存関係は次のとおりです。

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

(Full pom.xml file)

gRPC Kotlin 0.1 リリース版を試す

gRPC と Kotlin を組み合わせて使用すると、モバイルアプリやクラウド ネイティブ アプリの開発を改善できる可能性があります。このプロジェクトをぜひご活用になり、感想をお聞かせください。バージョン 0.1 はこのプロジェクトの初回リリースです。今後の最新リリースもご確認ください。また、何か問題がありましたら、gRPC Kotlin オープンソース プロジェクトにお問い合わせください。

- By ソフトウェア エンジニア Louis Wasserman、デベロッパー プログラム エンジニア Brent Shaffer