Redis Integration with Quarkus made simple

This tutorial will guide you through accessing Redis in-memory store from a Quarkus application. We will show which are the key interfaces for storing data structures in Redis and how Quarkus Dev Services greatly simplifies setting up a Dev environment for our Redis application.

Redis Overview

Redis is an open-source in-memory data structure store which you can use as database, cache, and message broker. It supports various data structures such as strings, lists, sorted sets, bitmaps, hyperloglogs and even more.

Redis is commonly used as a caching layer: by storing frequently accessed data in memory, Redis significantly reduces access times compared to fetching data from disk-based databases. This enhances the overall performance of applications.

There are several options to access Redis from Java. In this article we will learn how to use Quarkus Client extension for Redis which provides several key interfaces such as:

RedisDataSource: serves as a bridge between your Quarkus application and the Redis server, providing an interface to perform various operations and commands on the Redis data store. It offers functionalities to execute commands, manage data, and interact with the Redis server efficiently.

ReactiveKeyCommands: enables the execution of various key-related operations supported by Redis. This includes commands for key management such as DEL, EXISTS, EXPIRE, TTL, and more.

StringCommands: offers methods that directly map to string-related Redis commands, simplifying the execution of common string-based operations and abstracting the underlying Redis commands for handling string data.

Setting up the Quarkus application

In order to connect to Redis, we will provide the following extension to our Quarkus project:

<dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-redis-client</artifactId>
</dependency>

Then, in order to start a Redis Server, we can rely on Quarkus Dev Services which will start it for you provided that:

  • You have an active Docker daemon running
  • You have not configured quarkus.redis.hosts

Therefore, to satisfy this minimum requirement, just make sure Docker is up and running:

service docker start

Coding the Redis Client

Our basic Redis application will store a simple key value structure. For this purpose, start by adding a Java Record to your project:

public record Data(String key, int value) {
    // You can also define additional methods here if needed
}

Then, let’s write the core RedisService:

@Singleton
class RedisService {
    
    private ReactiveKeyCommands<String> keys;
    private StringCommands<String, Integer> cmd;
    private RedisDataSource redisDS;

    public RedisService(RedisDataSource redisDS,  ReactiveRedisDataSource reactiveRedisDS) {
        this.redisDS = redisDS;
        keys = reactiveRedisDS.key();
        cmd = redisDS.string(Integer.class);
    }


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

    int get(String key) {
        return cmd.get(key);
    }

    void set(Data data) {

        cmd.set(data.key(), data.value());
    }

    void increment(String key, int incrementBy) {
        cmd.incrby(key, incrementBy);
    }

    String execute(String command, String param ) {
        return redisDS.execute(command,param).toString();
    }

    Uni<List<String>> keys() {
        return keys
                .keys("*");
    }
}

Here is a quick description of the RedisService methods:

  1. Uni<Void> del(String key)
    • Deletes a key from the Redis database using the ReactiveKeyCommands instance.
  2. int get(String key)
    • Retrieves the value associated with a specific key from the Redis database using the StringCommands.
  3. void set(Data data)
    • Sets a key-value pair in the Redis database using the StringCommands.
  4. void increment(String key, int incrementBy)
    • Call the built-in incrBy function of the StringCommands to increment the value of a key. An equivalent decrby function exists to decrement the value of a key.
  5. String execute(String command, String param)
    • Shows how to use the RedisDataSource to invoke a Raw command by providing a given parameter.
  6. Uni<List<String>> keys()
    • Retrieves a list of keys matching a specified pattern from the Redis database using the ReactiveKeyCommands.

Adding a REST Resource to access the Service

To access our REST Service we will provide a simple REST Endpoint which maps all the above methods with an equivalent REST API:

@Path("/redisclient")
public class RedisResource {
    @Inject
    RedisService service;

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

    @Path("/{command}/{parameter}")
    @POST
    public String execute(String command, String parameter) {
       return service.execute(command, parameter);
    }

    @POST
    public Data create(Data data) {
        service.set(data);
        return data;
    }

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

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

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

Testing the Redis Client

Testing in dev mode is fairly simple when using Dev Service. Just build and start Quarkus in dev mode:

mvn install quarkus:dev

To begin with, we can start storing one key in Redis Storage:

curl -X POST -H "Content-Type: application/json" -d '{"key": "sampleKey", "value": 42}' http://localhost:8080/redisclient

Then, check the list of keys with the GET command:

curl -X GET http://localhost:8080/redisclient
["sampleKey"]

Next, in our application we have not implemented a method to decrement a key. For this purpose, let’s execute the Raw Redis DECR command:

curl -X POST http://localhost:8080/redisclient/DECR/sampleKey

Verify the value of the key after decrementing it:

curl -GET http://localhost:8080/redisclient/sampleKeyey
{"key":"sampleKey","value":41}

Accessing Redis Docker Image

Finally, we will show how you can access the Docker Image that Quarkus boots when you start Dev Service. For this purpose, let’s check the list of active Docker processes:

$ docker ps
e3315d9adb0b   redis:7-alpine              "docker-entrypoint.s…"   16 minutes ago   Up 16 minutes   0.0.0.0:32773->6379/tcp, :::32773->6379/tcp   musing_wing

The Redis Image includes the docker-cli executable. To run it, just execute it on the Docker Process:

docker exec -it e3315d9adb0b redis-cli

Then, you can directly access your Redis Server and execute commands from its Command Line:

java redis tutorial

Conclusion

You’ve now learned how to integrate Redis with a Quarkus application. This tutorial demonstrated basic Redis operations using Quarkus. You can expand upon this foundation to build more complex and powerful applications leveraging Redis’s capabilities.

Source code: https://github.com/fmarchioni/mastertheboss/tree/master/quarkus/redis-client

Found the article helpful? if so please follow us on Socials