Caching Next.js API routes with Redis
Here is the time difference we observed after caching the API routes with Redis.
So I recently started to observe the response time of api.crackeddevs.com (opens in a new tab) started to increase due to lot of traffic and huge amount of data being fetched from the database.
So I decided to cache the API routes with Redis.
What is Redis?
Redis is an open source in-memory data structure store which uses Key-Value pair to store data. And its blazingly fast.
So now the question was which Redis provider to use and we came to conclusion with two options:
So with some discussion and a suggestion from my friend Yashwanth (opens in a new tab) we decided to go with Upstash's Redis.
We used Upstash JS SDK to connect to the Redis instance and store the data in the cache.
Installation
npm i @upstash/redis
Importing the Redis SDK
import { Redis } from "@upstash/redis";
Initialization Redis Object
const redis = new Redis({
url: `${process.env.UPSTASH_REDIS_REST_URL}`,
token: `${process.env.UPSTASH_REDIS_REST_TOKEN}`,
});
It needs two environment variables UPSTASH_REDIS_REST_URL
and UPSTASH_REDIS_REST_TOKEN
which can be found in the Upstash dashboard.
Creating Redis Key
const RedisKey = `jobs:.....\n`; // unique key
Adding a response to Redis with expiry time
await redis.set(RedisKey, JSON.stringify(data)); // stores the object as string
await redis.expire(RedisKey, 600); // 10 minutes
Retrieving the data from Redis
const CachedData = await redis.get(jobRedisKey);
Conditional to check if cache exists , if yes then return cache
if (CachedData) {
// If data is found in cache, parse it if it's a string and return
console.log('cache HIT');
const data =
typeof CachedData === 'string' // checks if the data is string if yes then parse it
? JSON.parse(CachedData)
: CachedData;
return NextResponse.json(data); // return the cached data
}
So the final code looks like this
import { NextResponse } from 'next/server';
import { Redis } from '@upstash/redis';
const redis = new Redis({
url: `${process.env.UPSTASH_REDIS_REST_URL}`,
token: `${process.env.UPSTASH_REDIS_REST_TOKEN}`,
});
const RedisKey = `jobs:.....\n`; // unique key
export default async function handler(req, res) {
const CachedData = await redis.get(jobRedisKey);
if (CachedData) {
// If data is found in cache, parse it if it's a string and return
console.log('cache HIT');
const data =
typeof CachedData === 'string' // checks if the data is string if yes then parse it
? JSON.parse(CachedData)
: CachedData;
return NextResponse.json(data); // return the cached data
}
const response = await fetch('https://jobs.github.com/positions.json?description=javascript&location=remote'); // fetching example but can be anything
const data = await response.json();
await redis.set(RedisKey, JSON.stringify(data)); // stores the object as string
await redis.expire(RedisKey, 600); // 10 minutes
return NextResponse.json(data);
}
At last
So that's it , I hope you enjoyed reading this article , if you did please share it on twitter (opens in a new tab)
also visit crackeddevs.com (opens in a new tab)
Have a great day ahead . ☀️
© anurag.RSS