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 stable.

Being stable, backward compatibility and presence in the ecosystem are taken very seriously.

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+ instalado com JAVA_HOME configurado corretamente

  • Apache Maven 3.9.9

  • 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.24.2: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.native.enabled=true

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