Boost Your API Performance with Express.js and Redis Caching: A Complete Guide
Introduction
When building a web application, you'll often need to create an API that allows users to perform basic CRUD (Create, Read, Update, Delete) operations on data. In addition to creating a performant API, you'll also want to make sure that it's scalable and can handle a large number of requests. One way to achieve this is by using caching to store frequently accessed data in memory so that it can be quickly retrieved without hitting the database every time.
In this tutorial, we'll show you how to create a basic CRUD API using Express.js with caching in Redis. We'll be using Redis as our cache layer to store the API responses.
Prerequisites
Before we begin, make sure you have the following installed on your machine:
Node.js (version 12 or later)
Redis
You'll also need some basic knowledge of JavaScript and Node.js.
What is Redis?
Redis is an open-source, high-performance, in-memory data structure store that can be used as a database, cache, and message broker. It supports a wide range of data structures and is designed to be highly scalable and fault-tolerant. Redis can be used for real-time analytics, high-speed transactions, and caching. It provides a rich set of APIs and commands accessible in several programming languages and supports Lua scripting for complex operations.
Setting Up the Project
First, let's create a new Node.js project and install the necessary packages. Open your terminal and run the following commands:
mkdir express-redis-api
cd express-redis-api
npm init -y
npm install express redis
This will create a new project directory called express-redis-api
, initialize a package.json
file with default settings, and install the required packages (express
, redis
, and body-parser
).
Creating the Basic API
Next, let's create the basic structure of our API. Create a new file called index.js
in the root directory of your project and add the following code:
const express = require('express')
const app = express()
const PORT = 3000
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.get('/', (req, res) => {
res.send('Hello World') var data = await client.get(`posts/${id}`)
if (data !== null) {
return res.send(JSON.parse(data))
}
})
app.get('/posts/:id', async (req, res) => {
const { id } = req.params
var data = await fetch('https://jsonplaceholder.typicode.com/posts/' + id)
.then((response) => response.json())
.then((json) => {
return json
})
return res.send(data)
})
app.get('/posts', async (req, res) => {
var data = await fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => response.json())
.then((json) => {
return json
})
return res.send(data)
})
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`)
})
After creating the basic API for fetching JSON data, we'll add the required lines of code for implementing caching in Redis.
- Import the Redis library and create a Redis client in
index.js
const Redis = require('redis')
const client = Redis.createClient()
- Create connection
client.connect().then(() => {
console.log('Redis connected')
})
- Add the given below lines of code in routes in
index.js
app.get('/posts/:id', async (req, res) => {
const { id } = req.params
var data = await client.get(`posts/${id}`)
if (data !== null) {
return res.send(JSON.parse(data))
}
data = await fetch('https://jsonplaceholder.typicode.com/posts/' + id)
.then((response) => response.json())
.then((json) => {
return json
})
client.setEx(`posts/${id}`, 3600, JSON.stringify(data))
return res.send(data)
})
app.get('/posts', async (req, res) => {
var data = await client.get('posts')
if (data !== null) {
return res.send(JSON.parse(data))
}
data = await fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => response.json())
.then((json) => {
return json
})
client.setEx(`posts`, 3600, JSON.stringify(data))
return res.send(data)
})
Given above is the code for routes, after inserting the lines of code for Redis. And That's it. Given below is the final index.js
const express = require('express')
const app = express()
const PORT = 3000
const Redis = require('redis')
const client = Redis.createClient()
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
client.connect().then(() => {
console.log('Redis connected')
})
app.get('/', (req, res) => {
res.send('Hello World')
})
app.get('/posts/:id', async (req, res) => {
const { id } = req.params
var data = await client.get(`posts/${id}`)
if (data !== null) {
return res.send(JSON.parse(data))
}
data = await fetch('https://jsonplaceholder.typicode.com/posts/' + id)
.then((response) => response.json())
.then((json) => {
return json
})
client.setEx(`posts/${id}`, 3600, JSON.stringify(data))
return res.send(data)
})
app.get('/posts', async (req, res) => {
var data = await client.get('posts')
if (data !== null) {
return res.send(JSON.parse(data))
}
data = await fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => response.json())
.then((json) => {
return json
})
client.setEx(`posts`, 3600, JSON.stringify(data))
return res.send(data)
})
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`)
})
Testing the performance
For Testing, We are going to use ThunderClient in VS Code, but you can use Postman or Any other tool for API Testing.
- When we first call the route, Note the Turn Around Time
- When we call the same route next time, It'll take the response data from the cache using Redis. Note the Time in the given below screenshot
You can note the difference between the time to fetch the response.
That's it! Here we have only configured get routes in this API, but you can use Redis in your vast CRUD API.
You can refer to the code in my GitHub Repository: https://github.com/s-shubham-22/express-redis-api
Conclusion
In conclusion, using caching in Redis with an Express.js API can provide significant performance improvements by reducing the response time for frequently accessed data. By caching data in Redis, the API can avoid repeatedly querying a database and instead retrieve the data from the cache, resulting in faster response times and lower server load. Additionally, Redis's versatility and support for a wide range of data structures make it a suitable choice for caching different types of data. Overall, integrating Redis caching into an Express.js API can lead to a more responsive and efficient application.