The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

gRPC入門

このページでは、QuarkusアプリケーションでgRPCを使い始める方法を説明します。このページではMavenでの設定方法を説明していますが、Gradleを使用することも可能です。

ここでは、 Quarkusプロジェクトジェネレータ から生成された通常のQuarkusプロジェクトを想像してみましょう。デフォルトの設定で十分ですが、必要に応じていくつかのエクステンションを選択することもできます。

ソリューション

次の章で紹介する手順に沿って、ステップを踏んでアプリを作成することをお勧めします。ただし、完成した例にそのまま進んでも構いません。

Gitレポジトリをクローンするか git clone https://github.com/quarkusio/quarkus-quickstarts.gitアーカイブ をダウンロードします。

ソリューションは grpc-plain-text-quickstart ディレクトリ にあります。

プロジェクトの設定

ビルドファイルにQuarkus gRPCエクステンションを追加します:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-grpc</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-grpc")

デフォルトでは、 quarkus-grpc エクステンションはリアクティブなプログラミングモデルに依存しています。本ガイドではリアクティブなアプローチを採用します。 pom.xml ファイルの dependencies セクションで、 RESTEasy Reactiveの依存関係を確認してください。

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-resteasy-reactive")

Maven を使用している場合は、 pom.xmlquarkus-maven-plugingenerate-code ゴールが有効になっていることを確認してください。 テスト用に異なる proto ファイルからコードを生成したい場合は、 generate-code-tests ゴールも追加してください。 Gradle プラグインには追加のタスク/ゴールは必要ありません。

<build>
    <plugins>
        <plugin>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-maven-plugin</artifactId>
            <version>${quarkus-plugin.version}</version>
            <extensions>true</extensions>
            <executions>
                <execution>
                    <goals>
                        <goal>build</goal>
                        <goal>generate-code</goal>
                        <goal>generate-code-tests</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

この設定では、サービスとメッセージの定義を src/main/proto ディレクトリーに置くことができます。 quarkus-maven-plugin は、 proto ファイルから Java ファイルを生成します。

quarkus-maven-plugin は、Mavenリポジトリから protoc (protobuf コンパイラ)のバージョンを取得します。取得されたバージョンは、使用しているオペレーティングシステムとCPUアーキテクチャに適合します。この検索されたバージョンがあなたのコンテキストで動作しない場合は、 -Dquarkus.grpc.protoc-os-classifier=your-os-classifier で別の OS クラシファイアを強制的に使用することができます (例: osx-x86_64 )。また,適切なバイナリをダウンロードし、 -Dquarkus.grpc.protoc-path=/path/to/protoc でその場所を指定することもできます。

まずは簡単な Hello サービスから始めてみましょう。 src/main/proto/helloworld.proto ファイルを以下の内容で作成します。

syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.quarkus.example";
option java_outer_classname = "HelloWorldProto";

package helloworld;

// The greeting service definition.
service Greeter {
    // Sends a greeting
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
    string name = 1;
}

// The response message containing the greetings
message HelloReply {
    string message = 1;
}

この proto ファイルは、単一のメソッド ( SayHello ) と交換されたメッセージ (名前を含む HelloRequest と挨拶メッセージを含む HelloReply ) を持つシンプルなサービスインターフェースを定義しています。

proto ファイルには、 option java_generic_services = true; を含めてはいけません。 汎用サービスは非推奨 であり、Quarkusのコード生成プラグインと互換性がありません。

コーディングの前に、gRPCサービスを実装して消費するためのクラスを生成する必要があります。ターミナルで以下を実行します。

$ mvn compile

生成されたら、 target/generated-sources/grpc ディレクトリーを見てみましょう。

target/generated-sources/grpc
└── io
    └── quarkus
        └── example
            ├── Greeter.java
            ├── GreeterBean.java
            ├── GreeterClient.java
            ├── GreeterGrpc.java
            ├── HelloReply.java
            ├── HelloReplyOrBuilder.java
            ├── HelloRequest.java
            ├── HelloRequestOrBuilder.java
            ├── HelloWorldProto.java
            └── MutinyGreeterGrpc.java

これらは、これから使うクラスファイルです。

異なるgRPCの実装/タイプ

もうひとつ、QuarkusのgRPCサポートには、現在3種類のgRPCの使用があることにも注意が必要です:

  1. 古いVert.xのgRPC実装で、gRPCサーバーを別に用意(デフォルト)

  2. 新しいVert.x gRPC実装で、既存のHTTPサーバー上に構築

  3. xDS gRPC wrapper over grpc-java with a separate Netty based gRPC server

それぞれの有効化と使用方法については、さらにドキュメントで説明しています。

gRPCサービスの実装

生成されたクラスができたので、 hello サービスを実装してみましょう。

Quarkusは、Quarkusに統合されたReactive Programming APIであるMutinyを使用した追加モデルも提供しています。Mutinyの詳細については、 Mutiny ガイド を参照してください。サービスクラスは @io.quarkus.grpc.GrpcService アノテーションが付与されている必要があります。

サービスの実装

以下の内容の src/main/java/org/acme/HelloService.java ファイルを作成します。

package org.acme;

import io.quarkus.example.Greeter;
import io.quarkus.example.HelloReply;
import io.quarkus.example.HelloRequest;
import io.quarkus.grpc.GrpcService;
import io.smallrye.mutiny.Uni;

@GrpcService (1)
public class HelloService implements Greeter {  (2)

    @Override
    public Uni<HelloReply> sayHello(HelloRequest request) { (3)
        return Uni.createFrom().item(() ->
                HelloReply.newBuilder().setMessage("Hello " + request.getName()).build()
        );
    }
}
1 実装をBeanとして公開します。
2 生成されたサービスインターフェースを実装する。
3 サービス定義で定義されたメソッドを実装します(ここでは1つのメソッドを使用しています)。

また、Mutinyの代わりにデフォルトのgRPC APIを使用することもできます。

package org.acme;

import io.grpc.stub.StreamObserver;
import io.quarkus.example.GreeterGrpc;
import io.quarkus.example.HelloReply;
import io.quarkus.example.HelloRequest;
import io.quarkus.grpc.GrpcService;

@GrpcService (1)
public class HelloService extends GreeterGrpc.GreeterImplBase { (2)

    @Override
    public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) { (3)
        String name = request.getName();
        String message = "Hello " + name;
        responseObserver.onNext(HelloReply.newBuilder().setMessage(message).build()); (4)
        responseObserver.onCompleted(); (5)
    }
}
1 実装をBeanとして公開します。
2 ImplBase クラスを拡張します。生成されたクラスです。
3 サービス定義で定義されたメソッドを実装します(ここでは1つのメソッドを使用しています)。
4 レスポンスを構築して送信します。
5 レスポンスを閉じます。
サービスの実装ロジックがブロッキングである (例えば、ブロッキング I/O を使用する) 場合には、メソッドに @Blocking をアノテーションします。 io.smallrye.common.annotation.Blocking アノテーションは、I/O スレッド (イベントループ) の代わりにワーカースレッドでアノテーションされたメソッドを呼び出すようにフレームワークに指示します。

gRPCサーバー

サービスは サーバー によって 提供されます 。利用可能なサービス( CDIBean )は自動的に登録され、公開されます。

デフォルトでは、通常、サーバーは localhost:9000 で公開されており、 平文 を使用します(そのため TLS は使用しません)。テストでは、 localhost:9001 を使用します。

mvn quarkus:dev を使用してアプリケーションを実行します。

gRPCサービスを消費する

ここでは、公開しているサービスを消費することにします。簡単に言うと、同じアプリケーションからサービスを消費することになりますが、これは現実の世界では意味がありません。

既存の org.acme.ExampleResource クラスを開き、内容を編集してこのようになります。

package org.acme;

import io.quarkus.example.Greeter;
import io.quarkus.example.HelloRequest;
import io.quarkus.grpc.GrpcClient;
import io.smallrye.mutiny.Uni;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class ExampleResource {

    @GrpcClient                               (1)
    Greeter hello;                            (2)

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }

    @GET
    @Path("/{name}")
    public Uni<String> hello(String name) {
        return hello.sayHello(HelloRequest.newBuilder().setName(name).build())
                .onItem().transform(helloReply -> helloReply.getMessage());  (3)
    }
}
1 サービスをインジェクトし、その名前を設定します。この名前は、アプリケーションの設定で使用されます。指定しない場合、フィールド名が代わりに使用されます : このケースでは hello です。
2 Mutiny APIに基づいて生成されたサービスインターフェースを使用します。
3 サービスを起動します。

hello サービスがどこにあるかを示すようにアプリケーションを構成する必要があります。 src/main/resources/application.properties ファイルで、以下のプロパティーを追加します。

quarkus.grpc.clients.hello.host=localhost
  • hello@GrpcClient アノテーションで使用される名前です。

  • host はサービスホストを設定します (ここでは localhost)。

そして、ブラウザで http://localhost:8080/hello/quarkus を開くと、 Hello quarkus と表示されるはずです!

アプリケーションのパッケージング

他のQuarkusアプリケーションと同様に、次のコマンドでパッケージ化することができます: mvn package また、アプリケーションをネイティブ実行可能ファイルにパッケージすることもできます: mvn package -Dnative

関連コンテンツ