Data handling is the most crucial aspect while building any high performing apps. When dealing with large data sets or complex queries it can take awhile to pull that data from a database every time the user makes a request. This is where caching comes in and Redis is the popular mechanism in cache solutions.
Here, we are going to take a step by step look at setting up the caching in your NodeJS application. We want to speed up your app with redis through js application more efficiently.
Now before we jump into the setup, I would love to spend a moment about Redis. Redis is a powerful open-source, in-memory key-value store used as a database, cache and message broker. Since it stores data in RAM, it is very fast and suitable to cache the response from API or the result of frequent database queries as they rarely change.
Using Redis as a cache allows you to alleviate the load on your main database and serve requests faster via Node. The way it does this is by keeping data in memory and serving it to the NodeJS application instead of querying the database every time.
Install redis:
sudo apt install redis-server
Start redis service:
sudo systemctl status redis If redis service is not running, then you can start it manually sudo systemctl start redis
Verify redis installation: redis-cli ping
If everything working you will get PONG
Install it using npm:
npm install ioredis
Create a redisClient.js file and write the following code in it.
const Redis = require('ioredis');
// Create a new Redis client
const redis = new Redis({
host: '127.0.0.1', // Redis server address
port: 6379, // Default Redis port
});
redis.on('connect', () => {
console.log('Connected to Redis');
});
redis.on('error', (err) => {
console.error('Redis connection error:', err);
});
In this case, we are connecting to the default Redis (127.0.0.1 and 6379).
With the connection to redis established, let us write some caching logic. Let us say we are retrieving information from a DB, and we want to cache the result in order to speed up next requests.
Below is a simple function to check whether the data exists in the redis cache or not. If so, it responds with the cached information from previous visits; if not, it retrieves a record from the “database” (simulated here) and places it in cache for subsequent requests.
const getCachedData = async (key) => {
// Check if data is in cache
const cachedData = await redis.get(key);
if (cachedData) {
console.log('Returning cached data');
return JSON.parse(cachedData); // Return cached data
}
// Simulate a database query (e.g., getting user data)
console.log('Fetching data from database');
const dataFromDb = { userId: 1, name: 'John Doe', email: 'john@example.com' };
// Store the data in cache for 1 hour (3600 seconds)
await redis.setex(key, 3600, JSON.stringify(dataFromDb));
return dataFromDb;
};
How It Works:
Now, this caching logic needs to be applied in an API endpoint. Now, let us see how we can replace an Express route with the caching logic we just built.
Final app.js
const express = require('express');
const app = express();
const port = 3000;
const Redis = require('ioredis');
// Create a new Redis client
const redis = new Redis({
host: '127.0.0.1', // Redis server address
port: 6379, // Default Redis port
});
const getCachedData = async (key) => {
// Check if data is in cache
const cachedData = await redis.get(key);
if (cachedData) {
console.log('Returning cached data');
return JSON.parse(cachedData); // Return cached data
}
// Simulate a database query (e.g., getting user data)
console.log('Fetching data from database');
const dataFromDb = { userId: 1, name: 'John Doe', email: 'john@example.com' };
// Store the data in cache for 1 hour (3600 seconds)
await redis.setex(key, 3600, JSON.stringify(dataFromDb));
return dataFromDb;
};
// Define a route that fetches data
app.get('/user/:id', async (req, res) => {
const userId = req.params.id;
const cacheKey = `user:${userId}`;
try {
const userData = await getCachedData(cacheKey);
res.json(userData);
} catch (error) {
res.status(500).json({ message: 'Error retrieving data' });
}
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
For example, we are using a function called getCachedData in the route handler. If the user data is present in Redis cache, it returns immediately. Else it mimics a call to our database and caches the resultant for future requests.
To test the cache:
Initially, when you make the request it will actually lookup the simulated "database" for the data and then cache it. For sub-sequent requests it will be fetched from redis.
Result:
user-web@user-web:~/Node/Redis$ node app.js
Server running at http://localhost:3000
Fetching data from database
Returning cached data
Returning cached data
Returning cached data
Ready to transform your business with our technology solutions? Contact Us today to Leverage Our NodeJS Expertise.