avatarRuchira Madhushan Rajapaksha

Summarize

Building a Reactive Architecture with Spring WebFlux and Reactive Redis

Reactive Architecture around Redis with Spring Boot

In this article, I will talk about how to design a reactive application with Spring WebFlux and Reactive Redis.

Introduction to Redis

Redis is an open-source, in-memory data structure store used as a database, cache, message broker, and streaming engine. It provides data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes, and streams. Redis also provides high availability via Redis Sentinel and automatic partitioning with the Redis Cluster.

What is Reactive Redis?

Spring Boot provides a reactive programming approach to interact with the Redis database, which is called Reactive Redis. This is achieved by offering a reactive version ofRedisConnectionFactory, known asReactiveRedisConnectionFactory, which returns a ReactiveConnection.

You can refer to my other articles related to reactive architecture using reactive Redis down below.

Spring Boot application setup with Reactive Redis

Project Technical Stack

  1. Spring Boot 3.2.0
  2. Java 21
  3. Redis
  4. Docker

Starting Up Redis Server

We will use Docker to start a Redis instance. Simply execute the following command:

docker run --name my-redis -p 6379:6379 -d redis

We will then set up the application with Spring Initializer with the following dependencies in the pom.xml file.

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <optional>true</optional>
</dependency>

<dependency>
   <groupId>io.projectreactor</groupId>
   <artifactId>reactor-test</artifactId>
   <scope>test</scope>
</dependency>

<dependency>
   <groupId>org.springdoc</groupId>
   <artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
   <version>2.3.0</version>
</dependency>

Setting Up Configurations

Configure the application.yml file for the SpringBoot application as follows. We will define the configurations related to Redis in it.

redis:
  host: localhost
  port: 6379

Reactive Redis Configuration

Create a @Configuration class RedisConfig to enable reactive support for Redis.

@Configuration
public class RedisConfig {

    @Value("${redis.host}")
    private String host;

    @Value("${redis.port}")
    private int port;

    @Bean
    @Primary
    public ReactiveRedisConnectionFactory reactiveRedisConnectionFactory() {
        return new LettuceConnectionFactory(host, port);
    }

    @Bean
    public ReactiveRedisOperations<String, Product> reactiveRedisOperations(ReactiveRedisConnectionFactory reactiveRedisConnectionFactory) {
        Jackson2JsonRedisSerializer<Product> serializer = new Jackson2JsonRedisSerializer<>(Product.class);

        RedisSerializationContext.RedisSerializationContextBuilder<String, Product> builder =
                RedisSerializationContext.newSerializationContext(new StringRedisSerializer());

        RedisSerializationContext<String, Product> context = builder.value(serializer).build();

        return new ReactiveRedisTemplate<>(reactiveRedisConnectionFactory, context);
    }
}

LettuceConnectionFactory implements both the RedisConnectionFactory and ReactiveRedisConnectionFactory interfaces. When we declare a bean of LettuceConnectionFactory, we will be registering both RedisConnectionFactory and ReactiveRedisConnectionFactory as Spring beans.

ReactiveRedisOperations is an interface that specifies a basic set of Redis operations, implemented by the ReactiveRedisTemplate.

Jackson2JsonRedisSerializer is a RedisSerializer which is used to bind typed beans or untyped HashMap instances.

Product Class

@Data
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
@RedisHash("PRODUCT:REDIS")
public class Product {

    private String id;
    private String name;
}

Product Service Class

CreateProductService class and use ReactiveRedisOperations to access the Redis database.

@Service
@RequiredArgsConstructor
public class ProductService {

    private final ReactiveRedisOperations<String, Product> reactiveRedisOperations;
    private static final String REDIS_KEY = "PRODUCT:REDIS";

    public Flux<Product> findAll() {
        return this.reactiveRedisOperations.opsForList().range(REDIS_KEY, 0, -1);
    }

    public Mono<Product> findById(final String id) {
        return this.findAll().filter(p -> p.getId().equals(id)).next();
    }


    public Mono<Long> save(final Product product) {
        final String id = UUID.randomUUID().toString().substring(0, 8);
        product.setId(id);
        return this.reactiveRedisOperations.opsForList().rightPush(REDIS_KEY, product);
    }

    public Mono<Boolean> deleteAll() {
        return this.reactiveRedisOperations.opsForList().delete(REDIS_KEY);
    }

}

Product Controller Class

@RestController
@RequestMapping("/product")
@RequiredArgsConstructor
public class ProductController {

    private final ProductService productService;

    @GetMapping
    public Flux<Product> findAll(){
        return this.productService.findAll();
    }

    @GetMapping(path = "/{id}")
    public Mono<Product> findById(@PathVariable final String id) {
        return this.productService.findById(id);
    }


    @PostMapping
    public Mono<Long> save(final Product product){
        return this.productService.save(product);
    }

    @DeleteMapping
    public Mono<Boolean> deleteAll() {
        return this.productService.deleteAll();
    }

}

Testing the Application

We will use Spring Doc Open API to test the Rest Endpoints.

Get all Products

Get ALL Products

Add a New Product

Add New Product

Get Product by Id

Get Product By ID

Delete all Products

Delete ALL Products

Summary

In this article, we have covered:

  1. Introduction to Redis
  2. What is Reactive Redis?
  3. How to start a Redis Server with Docker
  4. Reactive Redis Spring Boot Integration.
  5. Testing the Rest Endpoints using Spring Doc Open API

Please feel free to share your feedback.

Visit to find more of my articles on Medium.

Thanks for reading.

Stackademic

Thank you for reading until the end. Before you go:

  • Please consider clapping and following the writer! 👏
  • Follow us on Twitter(X), LinkedIn, and YouTube.
  • Visit Stackademic.com to find out more about how we are democratizing free programming education around the world.

If you enjoyed this article, consider trying out the AI service I recommend. It provides the same performance and functions to ChatGPT Plus(GPT-4) but more cost-effective, at just $6/month (Special offer for $1/month). Click here to try ZAI.chat.

Spring Webflux
Spring Boot
Reactive Programming
Redis
Spring Boot 3
Recommended from ReadMedium