Using a Redis Singleton for NextJS API Routes
Asked Answered
H

1

7

In my NextJS app, I have multiple API routes:

  • /api/user/[id]
  • /api/questions
  • /api/posts

Each of these endpoints uses a Redis connection to get or put data within a Redis server.

I've noticed that I get errors in my console, because I am making too many connections to the Redis server. So I had an idea of creating a Singleton class and connecting to the Redis server once within the singleton. getInstance() returns the connection.

But I've noticed that my singleton is created once per API route. Does NextJS do something to cause this to happen?

How can I create 1 instance of a Redis connection in a NextJS app, just for the API routes held inside of pages/api? I'm using ioredis library.

Hobnob answered 15/3, 2022 at 22:17 Comment(1)
Any solutions to this?Widgeon
S
0

You can use global variables. Below setup for redis should work for nextJS using redis cloud free instance which has max 30 connections available in free plan.

Code:

import * as redis from 'redis';

const REDIS_USERNAME = process.env.REDIS_USERNAME;
const REDIS_PASSWORD = process.env.REDIS_PASSWORD;
const REDIS_HOST = process.env.REDIS_HOST;
const REDIS_PORT = process.env.REDIS_PORT;

let redisClient;
let redisClientPromise;

if (process.env.NEXT_PUBLIC_NODE_ENV === 'development') {
    if (!global._redisClientPromise) {
        redisClient = redis.createClient({
            url: `redis://${REDIS_USERNAME}:${REDIS_PASSWORD}@${REDIS_HOST}:${REDIS_PORT}`
        });
        redisClient.connect().then(() => {
            console.info(
                `NextJS Redis client connected..`
            );
        }).catch((error) => {
            console.error(`[ERROR] Couldn't connect to Redis client: ${error}`);
        });
        global._redisClientPromise = redisClient;
    }
    redisClientPromise = global._redisClientPromise
} else {
    redisClient = redis.createClient({
        url: `redis://${REDIS_USERNAME}:${REDIS_PASSWORD}@${REDIS_HOST}:${REDIS_PORT}`
    });
    redisClient.connect().then(() => {
        console.info(
            `NextJS Redis client connected..`
        );
    }).catch((error) => {
        console.error(`[ERROR] Couldn't connect to Redis client: ${error}`);
    });
    redisClientPromise = redisClient;
}

export default redisClientPromise;
Suazo answered 23/1, 2023 at 17:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.