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_HOMEconfigured 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:
For Windows users:
-
If using cmd, (don’t use backward slash
\and put everything on the same line) -
If using Powershell, wrap
-Dparameters 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:
quarkus extension add redis-client
./mvnw quarkus:add-extension -Dextensions='redis-client'
./gradlew addExtension --extensions='redis-client'
Esto añadirá lo siguiente a su archivo de construcción:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-redis-client</artifactId>
</dependency>
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:
quarkus dev
./mvnw quarkus:dev
./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:
quarkus build
./mvnw install
./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:
quarkus build --native
./mvnw install -Dnative
./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.