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

Uso del cliente Redis

Esta guía demuestra cómo su aplicación Quarkus puede conectarse a un servidor Redis utilizando la extensión Redis Client.

This technology is considered stable.

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

For a full list of possible statuses, check our FAQ entry.

Requisitos previos

To complete this guide, you need:

  • Roughly 15 minutes

  • An IDE

  • JDK 17+ installed with JAVA_HOME configured appropriately

  • Apache Maven 3.9.11

  • Optionally the Quarkus CLI if you want to use it

  • Optionally Mandrel or GraalVM installed and configured appropriately if you want to build a native executable (or Docker if you use a native container build)

  • Un entorno Docker operativo

Arquitectura

En esta guía, vamos a exponer una API REST sencilla para incrementar números utilizando el comando INCRBY. Por el camino, veremos cómo utilizar otros comandos Redis como GET, SET (del grupo de cadenas), DEL y KEYS (del grupo de claves).

Utilizaremos la extensión Quarkus Redis para conectarnos e interactuar con Redis.

Solución

Recomendamos que siga las instrucciones de las siguientes secciones y cree la aplicación paso a paso. Sin embargo, también puede ir directamente al ejemplo completo.

Clone el repositorio Git: git clone https://github.com/quarkusio/quarkus-quickstarts.git o descargue un archivo.

La solución se encuentra en el directorio redis-quickstart.

Creación del proyecto Maven

En primer lugar, necesitamos un nuevo proyecto. Cree un nuevo proyecto con el siguiente comando:

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

To create a Gradle project, add the --gradle or --gradle-kotlin-dsl option.

For more information about how to install and use the Quarkus CLI, see the Quarkus CLI guide.

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

To create a Gradle project, add the -DbuildTool=gradle or -DbuildTool=gradle-kotlin-dsl option.

For Windows users:

  • If using cmd, (don’t use backward slash \ and put everything on the same line)

  • If using Powershell, wrap -D parameters in double quotes e.g. "-DprojectArtifactId=redis-quickstart"

Este comando genera un nuevo proyecto, importando la extensión de Redis.

Si ya tiene configurado su proyecto Quarkus, puede añadir la extensión redis-client a su proyecto ejecutando el siguiente comando en el directorio base de su proyecto:

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

Esto añadirá lo siguiente a su archivo de construcción:

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

Creación del POJO de incremento

Vamos a modelar nuestros incrementos utilizando el POJO Increment. Cree el archivo src/main/java/org/acme/redis/Increment.java, con el siguiente contenido:

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 La clave que se utilizará como clave de Redis
2 El valor contenido en la clave de Redis

Creación del servicio de incremento

Vamos a crear una clase IncrementService que desempeñará el papel de cliente Redis. Con esta clase, podremos realizar los comandos de Redis SET, GET, DEL, KEYS y INCRBY.

Cree el archivo src/main/java/org/acme/redis/IncrementService.java, con el siguiente contenido:

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 El campo utilizado para manipular las claves
2 El campo utilizado para manipular el contador
3 Inyectar las fuentes de datos imperativas y reactivas
4 Recuperar los comandos para manipular los contadores
5 Recuperar los comandos para manipular las claves
6 Recupera el valor asociado a la clave dada. Si es null, devuelve 0.
7 Establece el valor asociado a la clave dada
8 Incrementa el valor asociado a la clave dada
9 Elimina una clave (y su valor asociado)
10 Lista todas las claves

Creación del recurso de incremento

Cree el archivo src/main/java/org/acme/redis/IncrementResource.java, con el siguiente contenido:

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

Creación de la clase de prueba

Edite el archivo pom.xml para añadir la siguiente dependencia:

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

Cree el archivo src/test/java/org/acme/redis/IncrementResourceTest.java con el siguiente contenido:

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

Ponerlo en marcha

Si ha seguido las instrucciones, debería tener el servidor Redis en funcionamiento. A continuación, solo tiene que ejecutar la aplicación utilizando:

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

Abra otro terminal y ejecute el comando curl http://localhost:8080/increments.

Interacción con la aplicación

Como hemos visto anteriormente, la API expone cinco endpoints REST. En esta sección vamos a ver cómo inicializar un incremento, ver la lista de incrementos actuales, incrementar un valor dada su clave, recuperar el valor actual de un incremento y, por último, eliminar una clave.

Creación de un nuevo incremento

curl -X POST -H "Content-Type: application/json" -d '{"key":"first","value":10}' http://localhost:8080/increments (1)
1 Creamos el primer incremento, con la clave first y un valor inicial de 10.

La ejecución del comando anterior debería devolver el siguiente resultado:

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

Ver claves de incrementos actuales

Para ver la lista de claves de incrementos actuales, ejecute el siguiente comando:

curl http://localhost:8080/increments

El comando anterior debería devolver ["first"] indicando que solo tenemos un incremento hasta el momento.

Recuperar un incremento

Para recuperar un incremento utilizando su clave, tendremos que ejecutar el siguiente comando:

curl http://localhost:8080/increments/first (1)
1 La ejecución de este comando debería devolver el siguiente resultado:
{
  "key": "first",
  "value": 10
}

Incrementar un valor dada su clave

Para incrementar un valor, ejecute el siguiente comando:

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

Ahora, al ejecutar el comando curl http://localhost:8080/increments/first debería devolver el siguiente resultado:

{
  "key": "first",
  "value": 37 (1)
}
1 Vemos que el valor de la clave first es ahora 37, que es exactamente el resultado de 10 + 27, matemáticas rápidas.

Eliminar una clave

Utilice el siguiente comando para eliminar un incremento dada su clave.

curl -X DELETE  http://localhost:8080/increments/first (1)
1 Elimina el incremento first.

Ahora, al ejecutar el comando curl http://localhost:8080/increments debería devolver una lista vacía []

Configuración para producción

En este punto, Quarkus utiliza el Redis Dev Service para ejecutar un servidor Redis y configurar la aplicación. Sin embargo, en producción, ejecutará su propio Redis (o utilizará una oferta en la nube).

Vamos a iniciar un servidor Redis en el puerto 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

A continuación, abra el archivo src/main/resources/application.properties y añada:

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

Empaquetado y ejecución en modo JVM

Puede ejecutar la aplicación como un archivo jar convencional.

En primer lugar, tendremos que empaquetarlo:

CLI
quarkus build
Maven
./mvnw install
Gradle
./gradlew build
Este comando iniciará una instancia de Redis para ejecutar las pruebas.

A continuación, ejecútelo:

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

Ejecución nativa

También puede crear un ejecutable nativo a partir de esta aplicación sin realizar ningún cambio en el código fuente. Un ejecutable nativo elimina la dependencia de la JVM: todo lo necesario para ejecutar la aplicación en la plataforma de destino está incluido en el ejecutable, lo que permite que la aplicación se ejecute con una sobrecarga mínima de recursos.

Compilar un ejecutable nativo lleva un poco más de tiempo, ya que GraalVM realiza pasos adicionales para eliminar rutas de código innecesarias. Utilice el perfil native para compilar un ejecutable nativo:

CLI
quarkus build --native
Maven
./mvnw install -Dnative
Gradle
./gradlew build -Dquarkus.native.enabled=true

Una vez finalizada la compilación, puede ejecutar el ejecutable con:

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

Ir más allá

Para saber más sobre la extensión Redis de Quarkus, consulte la guía de referencia de la extensión Redis.

Related content