Usando cache en Springboot
Tags: spring, spanish, kotlin
Published: 2022-07-27 12:51:00

## Introducción

Para ponernos en contexto, a veces en un proyecto necesitamos realizar una serie de llamadas hacia nuestro backend de manera muy recurrente. Además de ello, esta llamada apenas tiene cambios a nivel de base de datos. Es decir, realizamos la llamada y consultamos a la base de datos o a un servicio externo prácticamente lo mismo siempre y por consiguiente recibimos la respuesta una y otra vez. 

Con este contexto, entra en juego el uso de la cache en nuestro servicio, lo que facilita y ahorra de llamadas innecesarias, ganando en rendimiento de manera muy significativa. Por ejemplo, necesitamos el listado de provincias del país. Sabemos que este listado no va a cambiar  pero tampoco queremos ir a nuestra base de datos a pedir cada vez por ellos una vez llamemos a nuestro servicio.

Por ello, el uso de la cache es un mecanismo para mejorar el rendimiento de nuestro servicio con el uso de la memoria temporal que tiene interna nuestro servicio desplegado. 


## Cache en Springboot

El uso básico de cache en Springboot se puede implementar de manera muy sencilla. En este artículo voy a describir un uso muy sencillo, viendo ya en algo básico como esto un aumento del rendimiento de nuestra aplicación.


### Uso de la Cache 

Para poder empezar a implementar nuestra cache, la anotación que vamos a emplear es @Cacheable, y es la que utilizamos en Spring para marcar las funciones que queremos cachear en memoria. Esto hará que la primera vez invocadas guarden el resultado en memoria y las siguientes veces hagan uso de esa misma memoria.

Normalmente esto lo desarrollaremos en la capa de Servicio aunque podríamos implementarlo en la capa de repositorio igualmente.

```
    @Cacheable("books")
    override fun getBooks(): List<Book>? {
         println("Service layer. getBooks")
         Thread.sleep(2000L)
         return repo.findAll()
    }
```
El nombre que asignamos es importante, ya que es la clave con la que guardamos el resultado en memoria.

De igual manera podríamos cachear la consulta a un libro específico de la siguiente manera:

```
    @Cacheable("book", key = "#id")
    override fun getBookById(id: Long): Book? {
        println("Service layer. getBookById")
        Thread.sleep(2000L)
        return repo.findById(id).orElseGet(null)
    }
```

En ambos ejemplos he puesto un sleep de 2 segundos para apreciar los resultados que luego muestro, ya que en un servicio tan básico, la diferencia entre cachear y no cachear seria de poquitos ms.

![GIF](https://media.giphy.com/media/d3mlE7uhX8KFgEmY/giphy.gif)

Una vez marcados nuestros métodos con @Cacheable, sólo habría que marcar nuestra aplicación con @EnableCaching para indicar a Spring que vamos a hacer uso del cache en la aplicación:

```
@SpringBootApplication
@EnableCaching
class CacheServiceApplication : CommandLineRunner {
      ......
}
```

Y esto es todo... nada más! Así de sencillo quedaría nuestra cache implementada en nuestro servicio. Vamos con las pruebas.

Realizamos nuestra primera llamada al listado de libros:


![Primera llamada a getBooks](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gxytgsu8bjp2cyrxhgix.png)

Vemos como la respuesta la recibimos 2 segundos despues, pero si volvemos a hacerla...magia!

![Segunda llamada a getBooks](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wtvbpl6gmdjwl1pjwkbj.png)

Vemos que ha hecho uso de la cache y la respuesta nos llega en un volado.

![Gif_minion](https://media.giphy.com/media/fBEMsUeGHdpsClFsxM/giphy.gif)

Lo mismo sucede con la llamada a getBookById:


![Segunda llamada a getBookById](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8eeaw407bd9b6rxk2t2.png)

Y en la segunda llamada:


![Segunda llamada a getBookById](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tmmtl3f2ujdsyqarbw40.png)


## Conclusiones

El potencial de esta herramienta es muy grande y hay muchas opciones de configuración con integraciones más complejas, pero ya veis con que poquitas líneas de código Spring nos permite crear una cache en nuestra aplicación que realmente funciona muy bien y con la que podremos ganar mucho rendimiento, aunque hay que saber explotarla y no abusar tampoco ;). 

El código del proyecto podéis encontrarlo [aquí](https://github.com/JaviCoronas/cache-spring.git)

Hasta la próxima!