Learnitweb

Working with Simple Key-Value Pairs in Redis using Redisson (Reactive Mode)

In the previous tutorials, we successfully configured Redisson and created a reusable base test setup.
Now, let’s move forward and interact with Redis by creating a simple key-value example using Redisson Reactive Client.

This will help us understand how to store and retrieve basic data from Redis in a reactive, non-blocking way.


1. Objective

In this tutorial, we will:

  • Create a new test class named KeyValueTest.
  • Extend our base class BaseRedisTest.
  • Use Redisson’s RBucket object to store and retrieve data.
  • Work in reactive mode (asynchronous, event-driven).
  • Verify that our Redis setup is working properly.

2. Project Structure

By now, your test folder should look something like this:

GoldwasserTest
 └── src
     └── test
         └── java
             └── com
                 └── guru
                     ├── base
                     │    └── BaseRedisTest.java
                     └── tests
                          └── KeyValueTest.java

3. Creating the Test Class

Let’s now create a class called KeyValueTest.java inside the com.guru.tests package.

package com.guru.tests;

import com.guru.base.BaseRedisTest;
import org.junit.jupiter.api.Test;
import org.redisson.api.RBucketReactive;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;

public class KeyValueTest extends BaseRedisTest {

    @Test
    public void testSetAndGetKeyValue() {
        // Define a key for our Redis entry
        String key = "user:1:name";

        // Create a bucket for the key
        RBucketReactive<String> bucket = redissonReactiveClient.getBucket(key);

        // Step 1: Set a value into Redis
        Mono<Void> setOperation = bucket.set("Sam");

        // Step 2: Retrieve the value from Redis
        Mono<String> getOperation = bucket.get();

        // Step 3: Combine both operations - first set, then get
        Mono<String> combinedOperation = setOperation.then(getOperation);

        // Step 4: Verify using StepVerifier (from Reactor Test)
        StepVerifier.create(combinedOperation)
                .expectNext("Sam")
                .verifyComplete();
    }
}

4. Explanation of the Code

Let’s go through each part of the code step by step to understand what’s happening.

a. Extending BaseRedisTest

public class KeyValueTest extends BaseRedisTest

We extend BaseRedisTest so we automatically get access to:

  • redissonClient
  • redissonReactiveClient

These clients are already initialized once (via @BeforeAll) in the base class, so we don’t have to reconfigure them in every test.


b. Creating a Key

String key = "user:1:name";

We define a simple Redis key.
In real applications, you should use namespaced keys like user:1:name instead of plain user1name to make your Redis data easier to organize.


c. Getting a Bucket

RBucketReactive<String> bucket = redissonReactiveClient.getBucket(key);
  • RBucket is a Redisson data structure that represents a simple key-value pair in Redis.
  • The <String> generic type indicates we are storing a string value.
  • The Reactive version (RBucketReactive) works with Mono and Flux (reactive streams).

You can think of a bucket as a simple container for a single value.


d. Setting a Value

Mono<Void> setOperation = bucket.set("Sam");

This writes the value "Sam" to Redis under the key "user:1:name".
Since this is a reactive operation, it returns a Mono<Void> — meaning it will execute only when subscribed to.


e. Getting the Value

Mono<String> getOperation = bucket.get();

This fetches the stored value (asynchronously) from Redis.


f. Combining Operations

Mono<String> combinedOperation = setOperation.then(getOperation);

Here, we chain the two operations:

  1. First, execute the set() operation.
  2. Once that completes, execute get() and return the value.

This ensures proper ordering — because reactive streams are lazy and nothing executes until subscribed.


g. Verifying the Result

StepVerifier.create(combinedOperation)
        .expectNext("Sam")
        .verifyComplete();

We use StepVerifier (from Reactor Test) to:

  • Subscribe to the reactive pipeline.
  • Verify that the value retrieved is "Sam".
  • Confirm that the stream completes successfully.

5. Running the Test

Before you run the test, make sure:

  1. Your Redis server is up and running on localhost:6379.
  2. You have cleared any previous data (FLUSHDB command in Redis CLI).
  3. Your project includes the following dependencies:
    • Redisson
    • Reactor Core
    • Reactor Test
    • JUnit 5

Once everything is ready, run the test class.


6. Expected Output

When the test runs successfully, you should see console output like:

Redis connections initialized successfully for tests.
Redis client created successfully!
Reactive Redisson Client created successfully!
Redis key stored successfully.
Redis value retrieved: Sam
BUILD SUCCESS

And if you open your Redis CLI and type:

KEYS *

You should see:

1) "user:1:name"

If you get the value manually:

GET user:1:name

You’ll see:

"Sam"

However, if you see weird unreadable characters, that’s due to serialization format (Redisson uses its own codec by default).
We’ll fix that by using a StringCodec in the next tutorial.


7. Key Concepts Learned

  1. RBucket represents a simple key-value pair in Redis.
  2. Reactive operations require subscription (StepVerifier or .subscribe()).
  3. Redis values can be stored and retrieved asynchronously.
  4. You can chain reactive calls using .then() for ordered execution.
  5. Default serialization may cause unreadable values — we’ll fix that next.

8. Summary

In this tutorial, we:

  • Created a new test class KeyValueTest.
  • Used RBucketReactive to store and retrieve key-value pairs.
  • Verified reactive Redis operations using StepVerifier.
  • Confirmed that Redis is working properly with our Redisson setup.

This forms the foundation for working with Redis data structures.