avatarRuchira Madhushan Rajapaksha

Summary

The article provides a comprehensive guide on building a reactive architecture using Spring WebFlux, Reactive Redis, and Docker, demonstrating how to integrate these technologies to create a responsive and scalable Spring Boot application.

Abstract

The article delves into the design of a reactive application architecture by leveraging Spring WebFlux for reactive programming and Reactive Redis for data management. It begins with an introduction to Redis, highlighting its versatile data structures and high-availability features. The author then explains Reactive Redis, a Spring Boot feature that allows for asynchronous and non-blocking interactions with Redis databases. The setup process for a Spring Boot application with Reactive Redis is detailed, including Docker configuration for Redis, necessary dependencies, and reactive Redis configuration. The article also covers the creation of a Product class, a ProductService for business logic, and a ProductController for REST API endpoints. Testing the application is demonstrated using Spring Doc Open API. The article concludes with a summary of the key points covered and an invitation for feedback, along with a call to action for readers to engage with the author's content on Medium and follow Stackademic on social media platforms.

Opinions

  • The author advocates for the use of Spring WebFlux and Reactive Redis to handle write-heavy workloads effectively.
  • The article suggests that using Docker to run Redis simplifies the setup process for developers.
  • The author emphasizes the importance of reactive programming in building scalable and responsive applications.
  • The use of Spring Initializer with specific dependencies is recommended for setting up the Spring Boot application.
  • The article implies that the ReactiveRedisTemplate and ReactiveRedisOperations are preferred for interacting with Redis in a reactive context.
  • The author encourages the use of Spring Doc Open API for testing REST endpoints, indicating its utility in the development process.
  • The article concludes with a personal appeal for reader engagement and support for the author's and Stackademic's content.

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.
Spring Webflux
Spring Boot
Reactive Programming
Redis
Spring Boot 3
Recommended from ReadMedium