Redis
Performance optimisation
Response caching
Java
SpringBoot
Caching
In-memory store

Optimizing Performance with Redis Response Caching in Spring Boot

by: Jerrish Varghese

December 26, 2023

titleImage

Introduction:

Optimizing API performance is always crucial for delivering exceptional user experiences. One effective strategy to achieve this goal is response caching, where frequently requested responses are stored and served directly from the cache. Redis, a lightning-fast in-memory data store, serves as an excellent caching solution. In this blog post, we'll explore how we leveraged Redis Cache Manager in a Spring Boot application to implement response caching effectively for a huge list of master data specific endpoints that had heavy traffic in production environment. Additionally, we'll introduce a sample Plain Old Java Object (POJO) called Lookup and the Office class to illustrate seamless integration with our caching mechanism.

Why Response Caching?

Response caching significantly reduces server load and improves response times by serving cached responses directly from memory. This approach is particularly beneficial for endpoints handling static or infrequently changing data, leading to enhanced performance and scalability.

Setting Up Redis Cache Manager in Spring Boot:

Let's start by configuring Redis Cache Manager in our Spring Boot application to unlock the full potential of Redis for response caching.

1. Dependency Setup:

Ensure that you have the necessary dependencies in your pom.xml or build.gradle file:

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

2. Configuration:

Create a configuration class to set up Redis Cache Manager:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@Configuration
public class CacheConfig {

    @Bean
    public RedisCacheConfiguration redisCacheConfiguration() {
        return RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10)) // Cache entries expire after 10 minutes
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
    }

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, RedisCacheConfiguration config) {
        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(config)
                .build();
    }
}

In this configuration, we set the default cache entry TTL (time-to-live) to 10 minutes and configure serializers for keys and values.

3. Caching Responses:

Now, let's cache responses of specific endpoints in our Spring Boot application. We'll use the @Cacheable annotation to cache the responses.

import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HRMSController {

    private final OfficeService officeService;

    @GetMapping("/office/{stateDepartmentId}")
    @Cacheable(value = "HRMS_CACHE", key = "#root.methodName+#stateCode+#stateDepartmentId")
    public List<Office> getOfficeByStateDepartmentId(
            @RequestHeader(name = X_STATE_CODE) String stateCode,
            @PathVariable String stateDepartmentId) {
        log.info("Fetching office by state department ID: {}", stateDepartmentId);
        return officeService.getOfficeByStateDepartmentId(stateCode, stateDepartmentId);
    }
}

In this example, we're using the @GetMapping annotation to map the endpoint /office/{stateDepartmentId} to the getOfficeByStateDepartmentId method. This method retrieves a list of offices based on the state department ID.

We've also added the @Cacheable annotation to cache the response of this method using Redis Cache Manager. The value attribute specifies the cache name (HRMS_CACHE), and the key attribute generates a unique cache key based on the method name, state code, and state department ID.

Introducing POJOs: Lookup and Office

Now, let's introduce two sample Plain Old Java Objects (POJOs) - Lookup and Office - to illustrate seamless integration with our caching mechanism:

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

@Getter
@SuperBuilder
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "@class")
@NoArgsConstructor
public class Lookup {
    private long id;
    private String code;
    private String name;
    private String nameInLocal;
    private boolean active;
}
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

@Getter
@SuperBuilder
@NoArgsConstructor
public class Office extends Lookup {
    private String stateDepartmentId;
    private int officeTypeId;
    private int districtId;
    private int lbId;
}

Please pay attention to the JsonTypeInfo.Id.CLASS, this might be required if you face serialization error. Otherwise it can be skipped.

Conclusion:

By incorporating Redis Cache Manager in our Spring Boot application and leveraging response caching, we can significantly enhance performance and scalability. Response caching, powered by Redis, reduces response times and server load by serving cached responses directly from memory. Additionally, introducing POJOs like Lookup and Office enables seamless integration with our caching mechanism, further optimizing our application's performance.

In summary, by adopting response caching and leveraging powerful caching solutions like Redis in conjunction with POJOs, we can create high-performance Spring Boot applications that deliver exceptional user experiences. Embrace the power of response caching and elevate your application's performance today!

contact us

Get started now

Get a quote for your project.
logofooter
title_logo

USA

Edstem Technologies LLC
254 Chapman Rd, Ste 208 #14734
Newark, Delaware 19702 US

INDIA

Edstem Technologies Pvt Ltd
Office No-2B-1, Second Floor
Jyothirmaya, Infopark Phase II
Ernakulam, Kerala
Pin: 682303

Work With Us

Blogs

Contact Us

© 2024 — Edstem All Rights Reserved

Privacy PolicyTerms of Use