With over two years of professional experience in Node.js, I've developed a streamlined template that integrates Node.js, Redis, and Docker. In this article, Iโll walk you through how to use it effectively. Letโs get started! ๐ฆพ
๐Overview
This project demonstrates a basic integration of Node.js, Redis, and Docker. It showcases two routes, one that directly interacts with a Redis cache and another without caching, allowing you to compare the performance and behavior of both.
๐ง Prerequisites
Before you start, ensure that you have Docker Desktop installed on your machine. This is required to run the Redis container. You can download it here for both macOS and Windows.
link here - docker desktop
1. ๐Setup app.js
:
First, require all the necessary dependencies and files:
const express = require('express');
const path = require('path');
const cors = require('cors');
const bodyParser = require('body-parser');
const commentRouter = require('./routers/comment.router');
const indexRouter = require('./routers/index.router')
Next, set up a simple Node.js app with middlewares and an error handler:
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.use(express.static(path.join(__dirname, '..', 'public')));
app.use((req, res, next) => {
console.log(req.method, req.originalUrl);
next();
})
app.use('/', indexRouter);
app.use('/comments', commentRouter);
app.use((err, req, res, next) => {
console.error(`${req.method}:${req.originUrl}, failed with error:${err}`);
res.status(500).json({ error: err.message })
});
const PORT = 3001;
app.listen(PORT, () => {
console.log(`server is up on: http://localhost:${PORT}`);
});
2. Setup commentRouter:
The commentRouter has two versions:
- v1: Interacts without Redis caching
- v2: Interacts with Redis caching
const express = require('express');
const { getCommentsService, getCommentsWithRedisService } = require('../services/commentService');
const router = express();
router.get('/v1', getCommentsService);
router.get('/v2', getCommentsWithRedisService);
module.exports = router;
3. ๐ ๏ธServices:
-
getCommentsService
- is related to v1 without caching. -
getCommentsWithRedisService
- is related to v2 with caching.
const axios = require('axios');
const { getSetRedisCache } = require('../utils/redis.util');
const COMMENTS_API_URL = "https://jsonplaceholder.typicode.com/comments"
const EXPIRATION_TIME = 60 * 60; // 1 hour (3600 seconds)
async function getCommentsService(req, res, next) {
const postId = req.query.postId;
try {
const { data } = await axios.get(COMMENTS_API_URL, { params: { postId } });
return res.status(200).json(data);
} catch (error) {
next(new Error('API request has failed'))
}
}
async function getCommentsWithRedisService(req, res, next) {
const postId = req.query.postId;
const cacheKey = `comments?postId=${postId}`;
try {
const data = await getSetRedisCache({
key: cacheKey,
callbackFn: async () => {
const { data } = await axios.get(COMMENTS_API_URL, { params: { postId } });
return data;
},
expirationTime: EXPIRATION_TIME,
})
res.json({ data })
} catch (error) {
next(new Error(error.message))
}
}
module.exports = {
getCommentsService,
getCommentsWithRedisService
}
4. Implement getSetRedisCache
The function caches all the requests you want to cache. First, we need to connect to Redis.
If you're running Node.js locally, you don't need to specify the url:
const Redis = require('redis');
const redisClient = Redis.createClient({ url: '' })
redisClient.connect().catch(console.error);
If you're running Node.js on a Docker container:
const Redis = require('redis');
const redisClient = Redis.createClient({ url: 'redis://redis:6379' })
redisClient.connect().catch(console.error);
Now, implement the caching function itself. The function should cache your request data. The key should be the request url with the parameters:
exports.getSetRedisCache = ({ key, callbackFn, expirationTime }) => {
return new Promise((resolve, reject) => {
redisClient.GET(key)
.then(async (redisData) => {
if (redisData && redisData !== null) return resolve(JSON.parse(redisData));
const newData = await callbackFn();
redisClient.SETEX(key, expirationTime, JSON.stringify(newData));
resolve(newData);
})
.catch(err => reject(err))
})
}
5. ๐Check Cached Keys in Redis
Send 3+ requests in Postman or any other API client:
http://localhost:3001/comments/v2
http://localhost:3001/comments/v2?postId=1
http://localhost:3001/comments/v2?postId=2
http://localhost:3001/comments/v2?postId=3
Then, check the container for results:
Now your data has been cached for 1 hour, and subsequent requests to the server will be faster.
Example:
First iteration:
Feel free to leave a comment.
don't forget to drop a "๐๐ฆ๐ฅ".
๐ Connect with Me
If you found this template useful, feel free to follow me on LinkedIn for more updates and articles: https://www.linkedin.com/in/shaybushary
๐ GitHub Repository
You can find the complete code for this template on GitHub. Don't forget to star the repo if you find it helpful!
https://github.com/Shaybush/nodejs-redis-docker.git
Top comments (1)
Excellent post, showing a very important use