The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.
このページを編集

Redis クライアントの使用

stable

このガイドでは、Quarkus アプリケーションが Redis クライアントエクステンションを使用して Redis サーバーに接続する方法を説明します。

この技術は、stableと考えられています。

安定性 、後方互換性、エコシステムにおける存在感は非常に重要視されています。

とりうるステータスの完全なリストについては、 FAQの項目 を参照してください。

前提条件

このガイドを完成させるには、以下が必要です:

  • 約15分

  • IDE

  • JDK 17+がインストールされ、 JAVA_HOME が適切に設定されていること

  • Apache Maven 3.9.15

  • 使用したい場合は、 Quarkus CLI

  • ネイティブ実行可能ファイルをビルドしたい場合、MandrelまたはGraalVM(あるいはネイティブなコンテナビルドを使用する場合はDocker)をインストールし、 適切に設定していること

  • Docker が稼働している環境

アーキテクチャー

このガイドでは、INCRBY コマンドを使用して数値をインクリメントするシンプルな Rest API を公開します。この過程で、GETSET (文字列グループより)、DELKEYS (キーグループより) といった他の Redis コマンドの使い方を見ていきます。

Redis との対話には Quarkus Redis エクステンションを使用します。

ソリューション

次のセクションの指示に従って、アプリケーションをステップバイステップで作成することをお勧めします。ただし、完成した例に直接進むことも可能です。

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

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

Maven プロジェクトの作成

まず、新しいプロジェクトが必要です。以下のコマンドで新しいプロジェクトを作成します。

コマンドラインインタフェース
quarkus create app org.acme:redis-quickstart \
    --extension='redis-client,rest-jackson' \
    --no-code
cd redis-quickstart

Gradleプロジェクトを作成するには、 --gradle または --gradle-kotlin-dsl オプションを追加します。

Quarkus CLIのインストールと使用方法の詳細については、 Quarkus CLI ガイドを参照してください。

Maven
mvn io.quarkus.platform:quarkus-maven-plugin:3.35.1:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=redis-quickstart \
    -Dextensions='redis-client,rest-jackson' \
    -DnoCode
cd redis-quickstart

Gradleプロジェクトを作成するには、 -DbuildTool=gradle または -DbuildTool=gradle-kotlin-dsl オプションを追加します。

Windowsユーザーの場合:

  • cmdを使用する場合、(バックスラッシュ \ を使用せず、すべてを同じ行に書かないでください)。

  • Powershellを使用する場合は、 -D パラメータを二重引用符で囲んでください。例: "-DprojectArtifactId=redis-quickstart"

このコマンドは、Redis エクステンションをインポートした新しいプロジェクトを生成します。

Quarkus プロジェクトがすでに設定されている場合は、プロジェクトのベースディレクトリーで以下のコマンドを実行することで、プロジェクトに redis-client エクステンションを追加することができます。

コマンドラインインタフェース
quarkus extension add redis-client
Maven
./mvnw quarkus:add-extension -Dextensions='redis-client'
Gradle
./gradlew addExtension --extensions='redis-client'

これにより、ビルドファイルに以下が追加されます。

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

Increment POJO の作成

Increment POJO を使用してインクリメントをモデル化します。src/main/java/org/acme/redis/Increment.java ファイルを以下の内容で作成します。

package org.acme.redis;

public class Increment {
    public String key; (1)
    public long value; (2)

    public Increment(String key, long value) {
        this.key = key;
        this.value = value;
    }

    public Increment() {
    }
}
1 Redis キーとして使用されるキー
2 Redis キーが保持する値

Increment Service の作成

Redis クライアントの役割を果たす IncrementService クラスを作成します。このクラスで、SETGETDELKEYSINCRBY の Redis コマンドを実行できるようになります。

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

package org.acme.redis;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;

import io.quarkus.redis.datasource.ReactiveRedisDataSource;
import io.quarkus.redis.datasource.RedisDataSource;
import io.quarkus.redis.datasource.keys.KeyCommands;
import io.quarkus.redis.datasource.keys.ReactiveKeyCommands;
import io.quarkus.redis.datasource.string.StringCommands;
import io.smallrye.mutiny.Uni;

@ApplicationScoped
public class IncrementService {

    // This quickstart demonstrates both the imperative
    // and reactive Redis data sources
    // Regular applications will pick one of them.

    private ReactiveKeyCommands<String> keyCommands; (1)
    private ValueCommands<String, Long> countCommands; (2)

    public IncrementService(RedisDataSource ds, ReactiveRedisDataSource reactive) { (3)
        countCommands = ds.value(Long.class); (4)
        keyCommands = reactive.key();  (5)

    }


    long get(String key) {
        Long value = countCommands.get(key); (6)
        if (value == null) {
            return 0L;
        }
        return value;
    }

    void set(String key, Long value) {
        countCommands.set(key, value); (7)
    }

    void increment(String key, Long incrementBy) {
        countCommands.incrby(key, incrementBy); (8)
    }

    Uni<Void> del(String key) {
        return keyCommands.del(key) (9)
            .replaceWithVoid();
    }

    Uni<List<String>> keys() {
        return keyCommands.keys("*"); (10)
    }
}
1 キーを操作するために使用するフィールド
2 カウンターを操作するために使用するフィールド
3 命令型と反応型の両方のデータソースをインジェクトします
4 カウンターを操作するコマンドを取得します
5 キーを操作するコマンドを取得します
6 指定されたキーに関連付けられた値を取得します。null の場合は 0 を返します。
7 指定されたキーに関連付けられた値を設定します
8 指定されたキーに関連付けられた値をインクリメントします
9 キー (とそれに関連付けられた値) を削除します
10 すべてのキーをリストアップします

Increment Resource の作成

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

package org.acme.redis;

import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.DELETE;
import java.util.List;

import io.smallrye.mutiny.Uni;

@Path("/increments")
public class IncrementResource {

    @Inject
    IncrementService service;

    @GET
    public Uni<List<String>> keys() {
        return service.keys();
    }

    @POST
    public Increment create(Increment increment) {
        service.set(increment.key, increment.value);
        return increment;
    }

    @GET
    @Path("/{key}")
    public Increment get(String key) {
        return new Increment(key, service.get(key));
    }

    @PUT
    @Path("/{key}")
    public void increment(String key, long value) {
        service.increment(key, value);
    }

    @DELETE
    @Path("/{key}")
    public Uni<Void> delete(String key) {
        return service.del(key);
    }
}

テストクラスの作成

pom.xml ファイルを編集して、以下の依存関係を追加します。

<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <scope>test</scope>
</dependency>

src/test/java/org/acme/redis/IncrementResourceTest.java ファイルを以下の内容で作成してください。

package org.acme.redis;

import static org.hamcrest.Matchers.is;

import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;

import static io.restassured.RestAssured.given;

import io.restassured.http.ContentType;

@QuarkusTest
public class IncrementResourceTest {

    @Test
    public void testRedisOperations() {
        // verify that we have nothing
        given()
                .accept(ContentType.JSON)
                .when()
                .get("/increments")
                .then()
                .statusCode(200)
                .body("size()", is(0));

        // create a first increment key with an initial value of 0
        given()
                .contentType(ContentType.JSON)
                .accept(ContentType.JSON)
                .body("{\"key\":\"first-key\",\"value\":0}")
                .when()
                .post("/increments")
                .then()
                .statusCode(200)
                .body("key", is("first-key"))
                .body("value", is(0));

        // create a second increment key with an initial value of 10
        given()
                .contentType(ContentType.JSON)
                .accept(ContentType.JSON)
                .body("{\"key\":\"second-key\",\"value\":10}")
                .when()
                .post("/increments")
                .then()
                .statusCode(200)
                .body("key", is("second-key"))
                .body("value", is(10));

        // increment first key by 1
        given()
                .contentType(ContentType.JSON)
                .body("1")
                .when()
                .put("/increments/first-key")
                .then()
                .statusCode(204);

        // verify that key has been incremented
        given()
                .accept(ContentType.JSON)
                .when()
                .get("/increments/first-key")
                .then()
                .statusCode(200)
                .body("key", is("first-key"))
                .body("value", is(1));

        // increment second key by 1000
        given()
                .contentType(ContentType.JSON)
                .body("1000")
                .when()
                .put("/increments/second-key")
                .then()
                .statusCode(204);

        // verify that key has been incremented
        given()
                .accept(ContentType.JSON)
                .when()
                .get("/increments/second-key")
                .then()
                .statusCode(200)
                .body("key", is("second-key"))
                .body("value", is(1010));

        // verify that we have two keys in registered
        given()
                .accept(ContentType.JSON)
                .when()
                .get("/increments")
                .then()
                .statusCode(200)
                .body("size()", is(2));

        // delete first key
        given()
                .accept(ContentType.JSON)
                .when()
                .delete("/increments/first-key")
                .then()
                .statusCode(204);

        // verify that we have one key left after deletion
        given()
                .accept(ContentType.JSON)
                .when()
                .get("/increments")
                .then()
                .statusCode(200)
                .body("size()", is(1));

        // delete second key
        given()
                .accept(ContentType.JSON)
                .when()
                .delete("/increments/second-key")
                .then()
                .statusCode(204);

        // verify that there is no key left
        given()
                .accept(ContentType.JSON)
                .when()
                .get("/increments")
                .then()
                .statusCode(200)
                .body("size()", is(0));
    }
}

起動

指示に従っていれば、Redis サーバーが実行されているはずです。あとは、以下を使用してアプリケーションを実行するだけです。

コマンドラインインタフェース
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./gradlew --console=plain quarkusDev

別のターミナルを開き、curl http://localhost:8080/increments コマンドを実行します。

アプリケーションとの対話

上記で見たように、API は 5 つの Rest エンドポイントを公開しています。このセクションでは、インクリメントを初期化する方法、現在のインクリメントのリストを見る方法、キーを指定して値をインクリメントする方法、インクリメントの現在の値を取得する方法、そして最後にキーを削除する方法を見ていきます。

新しいインクリメントの作成

curl -X POST -H "Content-Type: application/json" -d '{"key":"first","value":10}' http://localhost:8080/increments (1)
1 最初のインクリメントを作成します。キーは first、初期値は 10 とします。

上記のコマンドを実行すると、以下の結果が返されるはずです。

{
  "key": "first",
  "value": 10
}

現在のインクリメントキーの確認

現在のインクリメントキーのリストを表示するには、以下のコマンドを実行します:

curl http://localhost:8080/increments

上記のコマンドは ["first"] を返し、これまでのところインクリメントが 1 つしかないことを示しているはずです。

新しいインクリメントの取得

キーを使ってインクリメントを取得するには、以下のコマンドを実行する必要があります:

curl http://localhost:8080/increments/first (1)
1 このコマンドを実行すると、以下のような結果が返ってくるはずです:
{
  "key": "first",
  "value": 10
}

キーが与えられた値をインクリメントします

値をインクリメントするには、以下のコマンドを実行します:

curl -X PUT -H "Content-Type: application/json" -d '27' http://localhost:8080/increments/first (1)
1 first の値を 27 増やします。

さて、コマンド curl http://localhost:8080/increments/first を実行すると、次のような結果が返されるはずです。

{
  "key": "first",
  "value": 37 (1)
}
1 first キーの値が 37 になっていることがわかりますが、これはまさに簡単な計算である 10 + 27 の結果と同じです。

キーの削除

インクリメントのキーを指定して削除するには、以下のコマンドを使用します。

curl -X DELETE  http://localhost:8080/increments/first (1)
1 first のインクリメントを削除します。

さて、コマンド curl http://localhost:8080/increments を実行すると、空のリスト [] が返されるはずです。

本番環境での設定

この時点で、QuarkusはRedis Dev Serviceを使用して、Redisサーバーを実行し、アプリケーションを構成しています。しかし、本番環境では、独自のRedisを実行することになります(または、クラウドサービスを使用します)。

以下の形で6379番ポートでRedisサーバーを起動してみましょう:

docker run --ulimit memlock=-1:-1 -it --rm=true --memory-swappiness=0 --name redis_quarkus_test -p 6379:6379 docker.io/library/redis:7

次に、 src/main/resources/application.properties ファイルを開き、以下を追加します。

%prod.quarkus.redis.hosts=redis://localhost:6379

JVMモードでのパッケージ化と実行

従来の jar ファイルとしてアプリケーションを実行することができます。

まず、パッケージ化する必要があります。

コマンドラインインタフェース
quarkus build
Maven
./mvnw install
Gradle
./gradlew build
このコマンドはテストを実行するためのRedisインスタンスを起動します。

次に、それを実行します。

java -jar target/quarkus-app/quarkus-run.jar

ネイティブ実行

ソースコードを変更することなく、このアプリケーションからネイティブ実行可能ファイルを作成することもできます。ネイティブ実行可能ファイルは、JVMへの依存を取り除きます。ターゲットプラットフォーム上でアプリケーションを実行するために必要なすべてのものが実行ファイルに含まれているため、アプリケーションを最小限のリソースオーバーヘッドで実行することができます。

GraalVMは、不要なコードパスを削除するために追加のステップを実行するため、ネイティブ実行可能ファイルのコンパイルには少し時間がかかります。 native プロファイルを使用して、ネイティブ実行可能ファイルをコンパイルしてください。

コマンドラインインタフェース
quarkus build --native
Maven
./mvnw install -Dnative
Gradle
./gradlew build -Dquarkus.native.enabled=true

ビルドが完了したら、実行可能ファイルを次のように実行することが出来ます。

./target/redis-quickstart-1.0.0-SNAPSHOT-runner

さらに詳しく

Quarkus Redis エクステンションの詳細については、 Redis エクステンションリファレンスガイド を参照してください。

関連コンテンツ