Almacenar datos en caché con Expressjs
Tags: node, express, javascript, backend
Published: 2021-03-04 18:08:58

Vamos a aprender un poco de teoría antes de arrancar, según amazon:

# ¿Qué es el almacenamiento en caché?

En informática, una memoria caché es una capa de almacenamiento de datos de alta velocidad que almacena un subconjunto de datos, normalmente transitorios, de modo que las solicitudes futuras de dichos datos se atienden con mayor rapidez que si se debe acceder a los datos desde la ubicación de almacenamiento principal. El almacenamiento en caché permite reutilizar de forma eficaz los datos recuperados o procesados anteriormente.

# ¿Cómo funciona el almacenamiento en caché?

Los datos en una memoria caché suelen almacenarse en hardware de acceso rápido, como la memoria de acceso aleatorio (RAM) y también puede utilizarse junto con un componente de software. El objetivo principal de la caché es aumentar el rendimiento de recuperación de datos para evitar tener que acceder a la capa subyacente de almacenamiento, que es más lenta.

Al intercambiar capacidad por velocidad, una memoria caché normalmente almacena un subconjunto de datos de forma transitoria, a diferencia de las bases de datos cuyos elementos suelen ser completos y duraderos.

Ahora que sabemos todo esto gracias a Amazon Web Services, vamos a ver las diferentes formas de almacenar en caché:

- Almacenamiento en caché en el lado del cliente a través de Javascript:

Los navegadores por defecto traen una pequeña caché, estas pueden ser utilizadas por las API'S que los navegadores nos proporcionan como sessionStorage y localStorage.

- Almacenamiento en caché en el lado del servidor

Esto va a depender de como se use y en qué lenguaje pero la gran mayoría trae soporte para cachear datos a través de él, en el caso de NodeJs por ejemplo tenemos node-cache.
    
- Almacenamiento en caché distribuido

La ventaja de utilizar este tipo de almacenamiento es que no tendremos problemas con la persistencia o la seguridad de los datos, ya que para esto utilizamos herramientas como redis, que es una base de datos que fue creada con el propósito de poder almacenar datos en memoria, aunque también puede ser utilizada como base de datos persistente.

# Ejemplo real con Expressjs

Mi blog fue construido sobre Expressjs y de base de datos utilizo MongoDB, usa la arquitectura REST y en este caso vamos a usar la memoria caché para almacenar la lista de post existentes y poder devolvérselas al usuario de una forma más rápida.


Lo primero que vamos a hacer es requerir node-cache, y luego instanciarlo en una variable para poder usarlo. Al instanciar la clase NodeCache también le decimos el tiempo de vida en el que queremos que se persistan los datos en la memoria caché, en este caso lo hacemos por 10 segundos.

```javascript
const NodeCache = require('node-cache');
const myCache = new NodeCache({stdTTL: 10});
```

Después de eso lo que hacemos es que antes de poder enviarle los datos de la consulta de la base de datos al usuario, la vamos a guardar en la caché a través de la variable myCache, esto lo hacemos con el método set, donde primero especificamos la key con la que identificaremos a los datos y luego le pasamos los datos.

Después de esto volvemos al principio, en donde se hace la petición, y verificamos si los datos guardados existen en caché, para eso utilizamos el método has y le pasamos la llave que corresponde a los datos guardados,en el caso de que exista lo devolveremos al usuario rápidamente, y sino es así vamos a consultar a la base de datos, pero antes de devolvérselos vamos a guardarlo en caché.

```javascript
router.get('/post/all', function(req, res, next){
    if(myCache.has('result'))
    {
        res.send(myCache.get('result'))
        console.log('Desde caché')
        console.log(myCache.get('result'))
    }

    else
    {
        let posts = postModel.find({}, (err, result) => {
            if(!result){
                res.status(400,).send({message: 'Upss, posts not found'});
            }
    
            else{
                myCache.set('result', result);
                res.send(result);
                console.log('Desde db')
                console.log(result);
            }
        })
    }
})
```

Ahora vamos a ver el resultado de todo esto, primero hacemos la misma consulta pero nos traemos los datos directamente desde la db:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ikc62ajottqe1wy7hw00.png)

Ahora vamos a probarlo desde la memoria caché:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/omc4aaa5wda9aj6kmajd.png)

Como ven, logramos reducir bastante el tiempo de devolución de los datos consultados a la db, y esto es solo en una aplicación pequeña, imagínense haciéndolo con imágenes, con videos y otro tipo de datos. Es muy útil.

PD: Solo utilizar caché en peticiones GET.