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

Usando o Cliente Redis

Este guia demonstra como a sua aplicação Quarkus pode se conectar a um servidor Redis utilizando a extensão Redis Client.

Essa tecnologia é considerada preview.

In preview, backward compatibility and presence in the ecosystem is not guaranteed. Specific improvements might require changing configuration or APIs, and plans to become stable are under way. Feedback is welcome on our mailing list or as issues in our GitHub issue tracker.

Para obter uma lista completa de possíveis status, consulte nosso FAQ.

Pré-requisitos

Para concluir este guia, você precisa:

  • Cerca de 15 minutos

  • Um IDE

  • JDK 17+ installed with JAVA_HOME configured appropriately

  • Apache Maven 3.9.6

  • Opcionalmente, o Quarkus CLI se você quiser usá-lo

  • Opcionalmente, Mandrel ou GraalVM instalado e configurado apropriadamente se você quiser criar um executável nativo (ou Docker se você usar uma compilação de contêiner nativo)

  • Um ambiente Docker funcional

Arquitetura

Neste guia, vamos expor uma API Rest simples para incrementar números usando o comando INCRBY . Ao longo do caminho, veremos como usar outros comandos do Redis, como GET , SET (do grupo de strings), DEL e KEYS (do grupo de chaves).

Vamos utilizar a extensão Quarkus Redis para nos conectar e interagir com o Redis.

Solução

Recomendamos que siga as instruções nas seções seguintes e crie a aplicação passo a passo. No entanto, você pode ir diretamente para o exemplo completo.

Clone o repositório Git: git clone https://github.com/quarkusio/quarkus-quickstarts.git, ou baixe um arquivo.

A solução está localizada no diretório redis-quickstart .

Criando o projeto Maven

Primeiro, precisamos de um novo projeto. Crie um novo projeto com o seguinte comando:

CLI
quarkus create app org.acme:redis-quickstart \
    --extension='redis-client,rest-jackson' \
    --no-code
cd redis-quickstart

Para criar um projeto Gradle, adicione a opção --gradle ou --gradle-kotlin-dsl.

Para obter mais informações sobre como instalar e usar a CLI do Quarkus, consulte o guia Quarkus CLI.

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

Para criar um projeto Gradle, adicione a opção '-DbuildTool=gradle' ou '-DbuildTool=gradle-kotlin-dsl'.

Para usuários do Windows:

  • Se estiver usando cmd, (não use barra invertida '\' e coloque tudo na mesma linha)

  • Se estiver usando o Powershell, envolva os parâmetros '-D' entre aspas duplas, por exemplo, '"-DprojectArtifactId=redis-quickstart"'

Este comando gera um novo projeto, importando a extensão Redis.

Se já tiver o projeto Quarkus configurado, você pode adicionar a extensão redis-client ao projeto executando o seguinte comando no diretório base do projeto:

CLI
quarkus extension add redis-client
Maven
./mvnw quarkus:add-extension -Dextensions='redis-client'
Gradle
./gradlew addExtension --extensions='redis-client'

Isto irá adicionar o seguinte trecho no seu arquivo de build:

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

Criando o POJO Incremento

Vamos modelar nossos incrementos usando o POJO Increment. Crie o arquivo src/main/java/org/acme/redis/Increment.java , com o seguinte conteúdo:

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 A variável chave que será utilizada como chave do Redis
2 A variável valor que será o valor mantido pela chave Redis

Criando o Serviço de Incremento

Vamos criar uma classe IncrementService que desempenhará o papel de um cliente Redis. Com essa classe, poderemos executar os comandos Redis SET , GET , DEL , KEYS e INCRBY .

Criar o arquivo src/main/java/org/acme/redis/IncrementoService.java, com o seguinte conteúdo:

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 O campo utilizado para manipular chaves
2 O campo utilizado para manipular o contador
3 Injeta os datasources imperativo e reativo
4 Recuperar os comandos para manipular os contadores
5 Recuperar os comandos para manipular as chaves
6 Recupera o valor associado à chave indicada. Se null, retorna 0.
7 Define o valor associado a uma determinada chave
8 Incrementa o valor associado à chave indicada
9 Exclui uma chave (e o respetivo valor associado)
10 Lista todas as chaves

Criando o recurso de incremento IncrementoResource

Criar o arquivo src/main/java/org/acme/redis/IncrementoResource.java, com o seguinte conteúdo:

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);
    }
}

Criando a classe de teste

Edite o arquivo pom.xml para adicionar a seguinte dependência:

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

Crie o arquivo src/test/java/org/acme/redis/IncrementoResourceTest.java com o seguinte conteúdo:

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));
    }
}

Executando a aplicação

Se você seguiu as instruções, deverá ter o servidor Redis em execução. Em seguida, você só precisa executar a aplicação usando:

CLI
quarkus dev
Maven
./mvnw quarkus:dev
Gradle
./gradlew --console=plain quarkusDev

Abra outro terminal e execute o comando curl http://localhost:8080/incrementos.

Interagindo com a aplicação

Como vimos acima, a API expõe cinco endpoints Rest. Nesta seção, veremos como inicializar um incremento, ver a lista de incrementos atuais, incrementar um valor com sua chave, recuperar o valor atual de um incremento e, por fim, excluir uma chave.

Criando um novo incremento

curl -X POST -H "Content-Type: application/json" -d '{"key":"first","value":10}' http://localhost:8080/increments (1)
1 Criamos o primeiro incremento, com a chave primeira e um valor inicial de 10.

A execução do comando acima deve retornar o resultado abaixo:

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

Ver as chaves atuais de incrementos

Para ver a lista de chaves de incrementos atuais, execute o seguinte comando:

curl http://localhost:8080/increments

O comando acima deve retornar ["first"] indicando que temos apenas um incremento até o momento.

Recuperar um novo incremento

Para recuperar um incremento utilizando a sua chave, teremos de executar o comando abaixo:

curl http://localhost:8080/increments/first (1)
1 Ao executar este comando, deverá obter o seguinte resultado:
{
  "key": "first",
  "value": 10
}

Incrementa um valor dada a sua chave

Para incrementar um valor, execute o seguinte comando:

curl -X PUT -H "Content-Type: application/json" -d '27' http://localhost:8080/increments/first (1)
1 Incrementa o valor primeira em 27.

Agora, ao executar o comando curl http://localhost:8080/incrementos/primeira deve retornar o seguinte resultado:

{
  "key": "first",
  "value": 37 (1)
}
1 Vemos que o valor da chave primeira é agora 37 que é exatamente o resultado de 10 + 27.

Excluindo uma chave

Utilize o comando abaixo, para excluir um incremento dada a sua chave.

curl -X DELETE  http://localhost:8080/increments/first (1)
1 Excluir o incremento primeira.

Agora, ao executar o comando curl http://localhost:8080/incrementos deve retornar uma lista vazia []

Configuração para produção

Neste ponto, o Quarkus usa o Redis Dev Service para executar um servidor Redis e configurar a aplicação. No entanto, em produção, você executará seu próprio Redis (ou usará uma oferta de nuvem).

Vamos iniciar um servidor Redis na porta 6379 usando:

docker run --ulimit memlock=-1:-1 -it --rm=true --memory-swappiness=0 --name redis_quarkus_test -p 6379:6379 redis:5.0.6

Em seguida, abra o arquivo src/main/resources/application.properties e adicione:

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

Empacotando e execução no modo JVM

Você pode executar a aplicação como um arquivo jar convencional.

Em primeiro lugar, temos que empacotar a aplicação:

CLI
quarkus build
Maven
./mvnw install
Gradle
./gradlew build
Este comando iniciará uma instância Redis para executar os testes.

Em seguida, execute:

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

Executando em modo nativo

Você também pode criar um executável nativo a partir dessa aplicação sem fazer nenhuma alteração no código-fonte. Um executável nativo elimina a dependência do JVM: tudo o que é necessário para executar o aplicativo na plataforma de destino está incluído no executável, permitindo que o aplicativo seja executado com o mínimo de sobrecarga de recursos.

A compilação de um executável nativo demora um pouco mais, pois o GraalVM executa etapas adicionais para remover caminhos de código desnecessários. Use o perfil native para compilar um executável nativo:

CLI
quarkus build --native
Maven
./mvnw install -Dnative
Gradle
./gradlew build -Dquarkus.package.type=native

Quando a compilação estiver concluída, pode rodar o executável com:

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

Indo mais longe

Para saber mais sobre a extensão Quarkus Redis, consulte o guia de referência da extensão Redis.

Conteúdo Relacionado